From ecc042299f652e68c4b4ac74fbf6fd5eb70c2643 Mon Sep 17 00:00:00 2001 From: Lukas Harbarth Date: Wed, 18 Jun 2025 17:04:33 +0200 Subject: [PATCH] fix(SplitterLayout - TypeScript): extend `children` type to allow conditional rendering --- .../src/components/SplitterLayout/index.tsx | 38 ++----------------- .../src/components/SplitterLayout/types.ts | 37 ++++++++++++++++++ .../useConcatSplitterElements.tsx | 3 +- 3 files changed, 42 insertions(+), 36 deletions(-) create mode 100644 packages/main/src/components/SplitterLayout/types.ts diff --git a/packages/main/src/components/SplitterLayout/index.tsx b/packages/main/src/components/SplitterLayout/index.tsx index c3941588fa4..34d9c7dc533 100644 --- a/packages/main/src/components/SplitterLayout/index.tsx +++ b/packages/main/src/components/SplitterLayout/index.tsx @@ -2,46 +2,13 @@ import { debounce, useStylesheet, useSyncRef } from '@ui5/webcomponents-react-base'; import { clsx } from 'clsx'; -import type { CSSProperties, DependencyList, ReactElement } from 'react'; +import type { CSSProperties } from 'react'; import { forwardRef, useEffect, useRef, useState } from 'react'; import { SplitterLayoutContext } from '../../internal/SplitterLayoutContext.js'; -import type { CommonProps } from '../../types/index.js'; -import type { SplitterElementPropTypes } from '../SplitterElement/index.js'; import { classNames, styleData } from './SplitterLayout.module.css.js'; +import type { SplitterLayoutPropTypes } from './types.js'; import { useConcatSplitterElements } from './useConcatSplitterElements.js'; -interface SplitterLayoutOptions { - /** - * Defines whether the `SplitterLayout` should be reset when its size changes depending on the orientation. - */ - resetOnSizeChange?: boolean; - /** - * Defines whether the `SplitterLayout` should be reset when its `children` change. - */ - resetOnChildrenChange?: boolean; - /** - * Defines a list of dependencies that trigger a reset of the `SplitterLayout` when they are changed. - * - * __Note:__ The order and size of arrays of dependencies must remain constant in React, it's therefore not possible to change size or order between renders. - */ - resetOnCustomDepsChange?: DependencyList; -} - -export interface SplitterLayoutPropTypes extends CommonProps { - /** - * Controls if a vertical or horizontal `SplitterLayout` is rendered. - */ - vertical?: boolean; - /** - * The content areas (optional) to be split. The control will show n-1 splitter bars between n controls in this aggregation. - */ - children?: ReactElement | ReactElement[]; - /** - * Defines options to customize the behavior of the SplitterLayout. - */ - options?: SplitterLayoutOptions; -} - /** * A layout that contains several content areas. The content that is added to the `SplitterLayout` should be wrapped * into 0-n `SplitterElement`s which define the size and size constraints of the content area. @@ -137,4 +104,5 @@ const SplitterLayout = forwardRef((prop SplitterLayout.displayName = 'SplitterLayout'; +export type { SplitterLayoutPropTypes }; export { SplitterLayout }; diff --git a/packages/main/src/components/SplitterLayout/types.ts b/packages/main/src/components/SplitterLayout/types.ts new file mode 100644 index 00000000000..2ca922802da --- /dev/null +++ b/packages/main/src/components/SplitterLayout/types.ts @@ -0,0 +1,37 @@ +import type { CommonProps } from '@ui5/webcomponents-react-base'; +import type { DependencyList, ReactElement } from 'react'; +import type { SplitterElementPropTypes } from '../SplitterElement/index.js'; + +interface SplitterLayoutOptions { + /** + * Defines whether the `SplitterLayout` should be reset when its size changes depending on the orientation. + */ + resetOnSizeChange?: boolean; + /** + * Defines whether the `SplitterLayout` should be reset when its `children` change. + */ + resetOnChildrenChange?: boolean; + /** + * Defines a list of dependencies that trigger a reset of the `SplitterLayout` when they are changed. + * + * __Note:__ The order and size of arrays of dependencies must remain constant in React, it's therefore not possible to change size or order between renders. + */ + resetOnCustomDepsChange?: DependencyList; +} + +type SplitterLayoutChild = ReactElement | undefined | false | null; + +export interface SplitterLayoutPropTypes extends CommonProps { + /** + * Controls if a vertical or horizontal `SplitterLayout` is rendered. + */ + vertical?: boolean; + /** + * The content areas (optional) to be split. The control will show n-1 splitter bars between n controls in this aggregation. + */ + children?: SplitterLayoutChild | SplitterLayoutChild[]; + /** + * Defines options to customize the behavior of the SplitterLayout. + */ + options?: SplitterLayoutOptions; +} diff --git a/packages/main/src/components/SplitterLayout/useConcatSplitterElements.tsx b/packages/main/src/components/SplitterLayout/useConcatSplitterElements.tsx index 4e73cf0eafc..9c77e26017c 100644 --- a/packages/main/src/components/SplitterLayout/useConcatSplitterElements.tsx +++ b/packages/main/src/components/SplitterLayout/useConcatSplitterElements.tsx @@ -2,9 +2,10 @@ import type { CSSProperties, ReactElement } from 'react'; import { Children, cloneElement, isValidElement, useMemo } from 'react'; import { Splitter } from '../Splitter/index.js'; import type { SplitterElementPropTypes } from '../SplitterElement/index.js'; +import type { SplitterLayoutPropTypes } from './types.js'; interface ConcatSplitterElements { - children: ReactElement | ReactElement[]; + children: SplitterLayoutPropTypes['children']; width: CSSProperties['width']; height: CSSProperties['height']; vertical: boolean;