From 3e505569119ace6bc50dd8be3dd3b90311428a30 Mon Sep 17 00:00:00 2001 From: Roman Semenov Date: Sun, 8 Dec 2024 16:53:00 +0400 Subject: [PATCH] extract resizableheaderpanel --- .../card_view/header_panel/header_panel.tsx | 99 ++--------------- .../header_panel/resizable_header_panel.tsx | 103 ++++++++++++++++++ .../grids/new/card_view/header_panel/view.tsx | 4 +- 3 files changed, 117 insertions(+), 89 deletions(-) create mode 100644 packages/devextreme/js/__internal/grids/new/card_view/header_panel/resizable_header_panel.tsx diff --git a/packages/devextreme/js/__internal/grids/new/card_view/header_panel/header_panel.tsx b/packages/devextreme/js/__internal/grids/new/card_view/header_panel/header_panel.tsx index c6ef33ce261..60af17829a1 100644 --- a/packages/devextreme/js/__internal/grids/new/card_view/header_panel/header_panel.tsx +++ b/packages/devextreme/js/__internal/grids/new/card_view/header_panel/header_panel.tsx @@ -1,8 +1,7 @@ /* eslint-disable @typescript-eslint/no-non-null-assertion */ -import { resizeObserverSingleton } from '@ts/core/m_resize_observer'; -import { getBoundingRect } from '@ts/core/utils/m_position'; import type { Column } from '@ts/grids/new/grid_core/columns_controller/types'; -import { Component, createRef } from 'inferno'; +import type { RefObject } from 'inferno'; +import { Component } from 'inferno'; import { Sortable } from '../../grid_core/inferno_wrappers/sortable'; import { DropDownButton } from './drop_down_button'; @@ -15,11 +14,15 @@ export const CLASSES = { export interface HeaderPanelProps { columns: Column[]; - onReorder?: (fromIndex: number, toIndex: number) => void; + onReorder: (fromIndex: number, toIndex: number) => void; - onAdd?: (fromIndex: number, toIndex: number) => void; + onAdd: (fromIndex: number, toIndex: number) => void; - onRemove?: (name: string) => void; + onRemove: (name: string) => void; + + shownColumnCount: number; + + elementRef: RefObject; } interface HeaderPanelState { @@ -27,26 +30,16 @@ interface HeaderPanelState { } export class HeaderPanel extends Component { - private status: 'initial' | 'shrinking' | 'normal' = 'initial'; - - private normalHeight = 0; - - private readonly ref = createRef(); - - state = { - shownColumnCount: 1, - }; - public render(): JSX.Element { const visibleColumns = this.props.columns.filter( - (_, index) => index < this.state.shownColumnCount, + (_, index) => index < this.props.shownColumnCount, ); const nonVisibleColumns = this.props.columns.filter( - (_, index) => index >= this.state.shownColumnCount, + (_, index) => index >= this.props.shownColumnCount, ); return ( -
+
{
); } - - private getHeight(): number { - return getBoundingRect(this.ref.current!).height as number; - } - - private updateShownColumns(): void { - // eslint-disable-next-line no-undef-init - let stateToApply: undefined | HeaderPanelState = undefined; - - switch (this.status) { - case 'initial': { - if (this.state.shownColumnCount !== 1) { - throw new Error(); - } - - if (!this.props.columns.length) { - return; - } - - this.normalHeight = this.getHeight(); - this.status = 'shrinking'; - stateToApply = { - shownColumnCount: this.props.columns.length, - }; - break; - } - - case 'shrinking': { - if (this.getHeight() > this.normalHeight) { - stateToApply = { - shownColumnCount: this.state.shownColumnCount - 1, - }; - } else { - this.status = 'normal'; - } - break; - } - - case 'normal': { - this.status = 'shrinking'; - stateToApply = { - shownColumnCount: this.props.columns.length, - }; - break; - } - - default: { - // eslint-disable-next-line max-len - // eslint-disable-next-line @typescript-eslint/naming-convention, @typescript-eslint/no-unused-vars - const _: never = this.status; - } - } - - if (stateToApply) { - this.setState(stateToApply); - } - } - - componentDidMount(): void { - resizeObserverSingleton.observe( - this.ref.current!, - () => this.updateShownColumns(), - ); - } - - componentDidUpdate(): void { - this.updateShownColumns(); - } } diff --git a/packages/devextreme/js/__internal/grids/new/card_view/header_panel/resizable_header_panel.tsx b/packages/devextreme/js/__internal/grids/new/card_view/header_panel/resizable_header_panel.tsx new file mode 100644 index 00000000000..acff2d65dfb --- /dev/null +++ b/packages/devextreme/js/__internal/grids/new/card_view/header_panel/resizable_header_panel.tsx @@ -0,0 +1,103 @@ +/* eslint-disable @typescript-eslint/no-non-null-assertion */ +import { resizeObserverSingleton } from '@ts/core/m_resize_observer'; +import { getBoundingRect } from '@ts/core/utils/m_position'; +import { Component, createRef } from 'inferno'; + +import type { HeaderPanelProps } from './header_panel'; +import { HeaderPanel } from './header_panel'; + +export type Props = Omit; + +interface State { + shownColumnCount: number; +} + +export class ResizableHeaderPanel extends Component { + private status: 'initial' | 'shrinking' | 'normal' = 'initial'; + + private normalHeight = 0; + + private readonly ref = createRef(); + + state = { + shownColumnCount: 1, + }; + + public render(): JSX.Element { + return ( + + ); + } + + private getHeight(): number { + return getBoundingRect(this.ref.current!).height as number; + } + + private updateShownColumns(): void { + // eslint-disable-next-line no-undef-init + let stateToApply: undefined | State = undefined; + + switch (this.status) { + case 'initial': { + if (this.state.shownColumnCount !== 1) { + throw new Error(); + } + + if (!this.props.columns.length) { + return; + } + + this.normalHeight = this.getHeight(); + this.status = 'shrinking'; + stateToApply = { + shownColumnCount: this.props.columns.length, + }; + break; + } + + case 'shrinking': { + if (this.getHeight() > this.normalHeight) { + stateToApply = { + shownColumnCount: this.state.shownColumnCount - 1, + }; + } else { + this.status = 'normal'; + } + break; + } + + case 'normal': { + this.status = 'shrinking'; + stateToApply = { + shownColumnCount: this.props.columns.length, + }; + break; + } + + default: { + // eslint-disable-next-line max-len + // eslint-disable-next-line @typescript-eslint/naming-convention, @typescript-eslint/no-unused-vars + const _: never = this.status; + } + } + + if (stateToApply) { + this.setState(stateToApply); + } + } + + componentDidMount(): void { + resizeObserverSingleton.observe( + this.ref.current!, + () => this.updateShownColumns(), + ); + } + + componentDidUpdate(): void { + this.updateShownColumns(); + } +} diff --git a/packages/devextreme/js/__internal/grids/new/card_view/header_panel/view.tsx b/packages/devextreme/js/__internal/grids/new/card_view/header_panel/view.tsx index 5721d12d420..30ffd8f7f7d 100644 --- a/packages/devextreme/js/__internal/grids/new/card_view/header_panel/view.tsx +++ b/packages/devextreme/js/__internal/grids/new/card_view/header_panel/view.tsx @@ -3,12 +3,12 @@ import { computed } from '@ts/core/reactive/index'; import { ColumnsController } from '@ts/grids/new/grid_core/columns_controller/columns_controller'; import { View } from '@ts/grids/new/grid_core/core/view_old'; -import { HeaderPanel } from './header_panel'; +import { ResizableHeaderPanel } from './resizable_header_panel'; export class HeaderPanelView extends View { public vdom = computed( (columns) => ( -