From 652015cbdb4b810ffd3ce59749f57f1118105a3c Mon Sep 17 00:00:00 2001 From: Jaco Date: Tue, 17 Jan 2023 21:14:58 +0200 Subject: [PATCH] De-magic useWindowColumns (#8838) --- packages/react-components/src/Table/index.tsx | 36 ++++++++++++------- packages/react-hooks/src/useWindowColumns.ts | 26 +++++++------- packages/react-hooks/src/useWindowSize.ts | 11 ++---- 3 files changed, 39 insertions(+), 34 deletions(-) diff --git a/packages/react-components/src/Table/index.tsx b/packages/react-components/src/Table/index.tsx index bab7a084a3..13607d60ec 100644 --- a/packages/react-components/src/Table/index.tsx +++ b/packages/react-components/src/Table/index.tsx @@ -35,16 +35,15 @@ interface BodyState { isSplittable: boolean; } -function extractBody (children: React.ReactNode, isSplit: boolean): BodyState { - if (!Array.isArray(children)) { +function extractBody (body: React.ReactNode, isSplit: boolean): BodyState { + if (!Array.isArray(body)) { return { - body: children, - isEmpty: !children, + body, + isEmpty: !body, isSplittable: false }; } - const body = children.filter((child) => !!child); const isEmpty = body.length === 0; const isSplittable = !isEmpty && isSplit; @@ -59,26 +58,38 @@ function extractBody (children: React.ReactNode, isSplit: boolean): BodyState { function splitBody (body: React.ReactNode[], numColumns: number): React.ReactNode[][] { const result = new Array(numColumns); + const numRows = Math.ceil(body.length / numColumns); for (let i = 0; i < numColumns; i++) { - result[i] = []; + result[i] = new Array(numRows); } + // start at -1, on the first iteration it would + // increment to 0 and all is ok + let row = -1; + for (let i = 0; i < body.length; i++) { - result[i % numColumns].push(body[i]); + const col = i % numColumns; + + if (col === 0) { + row++; + } + + result[col][row] = body[i]; } return result; } function TableBase ({ children, className = '', empty, emptySpinner, filter, footer, header, headerChildren, isFixed, isInline, isSplit = false, legend, maxColumns, noBodyTag }: Props): React.ReactElement { + const numColumns = useWindowColumns(maxColumns); const { body, isEmpty, isSplittable } = useMemo( () => extractBody(children, isSplit), [children, isSplit] ); - const numColumns = useWindowColumns(maxColumns, isSplittable); + const bodySplit = useMemo( - () => isSplittable && (numColumns > 1) && splitBody(body as React.ReactNode[], numColumns), + () => body && isSplittable && (numColumns > 1) && splitBody(body as React.ReactNode[], numColumns), [body, isSplittable, numColumns] ); @@ -107,7 +118,7 @@ function TableBase ({ children, className = '', empty, emptySpinner, filter, foo {bodySplit.map((body, index) => (
{body} @@ -147,7 +158,7 @@ const StyledDiv = styled.div` .ui--Table-Split { display: flex; - flex-wrap: wrap; + flex-wrap: nowrap; margin-bottom: 1.5rem; > .ui--Table-Split-Column-3 { @@ -382,7 +393,8 @@ const StyledDiv = styled.div` .absolute { position: absolute; right: 0.5rem; - top: 0.75rem; + // this seems aligned with expander (when zoomed in) + top: 0.72rem; white-space: nowrap; } } diff --git a/packages/react-hooks/src/useWindowColumns.ts b/packages/react-hooks/src/useWindowColumns.ts index 3084a174ef..c88a4a08b5 100644 --- a/packages/react-hooks/src/useWindowColumns.ts +++ b/packages/react-hooks/src/useWindowColumns.ts @@ -1,24 +1,22 @@ // Copyright 2017-2023 @polkadot/react-hooks authors & contributors // SPDX-License-Identifier: Apache-2.0 -import { useMemo } from 'react'; - import { createNamedHook } from './createNamedHook'; import { useWindowSize } from './useWindowSize'; -function useWindowColumnsImpl (maxColumns: 0 | 1 | 2 | 3 = 3, isActive = true): number { - const windowSize = useWindowSize(isActive); +// we don't have this anywhere +const SIZE_COL_3 = 1500; +// this aligns with Columar +const SIZE_COL_2 = 1050; - return useMemo( - () => isActive - ? windowSize.width >= 1500 - ? Math.min(3, maxColumns) - : windowSize.width >= 1050 - ? Math.min(maxColumns, 2) - : 1 - : 1, - [isActive, maxColumns, windowSize] - ); +function useWindowColumnsImpl (maxColumns: 1 | 2 | 3 = 3): number { + const windowSize = useWindowSize(); + + return maxColumns >= 3 && windowSize.width >= SIZE_COL_3 + ? 3 + : maxColumns >= 2 && windowSize.width >= SIZE_COL_2 + ? 2 + : 1; } export const useWindowColumns = createNamedHook('useWindowColumns', useWindowColumnsImpl); diff --git a/packages/react-hooks/src/useWindowSize.ts b/packages/react-hooks/src/useWindowSize.ts index e653fa6166..ed56fe3677 100644 --- a/packages/react-hooks/src/useWindowSize.ts +++ b/packages/react-hooks/src/useWindowSize.ts @@ -3,18 +3,13 @@ import type { WindowSize } from './ctx/types'; -import { useContext, useRef } from 'react'; +import { useContext } from 'react'; import { WindowSizeCtx } from './ctx/WindowSize'; import { createNamedHook } from './createNamedHook'; -function useWindowSizeImpl (isActive = true): WindowSize { - const windowSize = useContext(WindowSizeCtx); - const staticRef = useRef(windowSize); - - return isActive - ? windowSize - : staticRef.current; +function useWindowSizeImpl (): WindowSize { + return useContext(WindowSizeCtx); } export const useWindowSize = createNamedHook('useWindowSize', useWindowSizeImpl);