From 058a698fea3e43bbbb9e501833536f11128796e9 Mon Sep 17 00:00:00 2001 From: Zeke Zhang <958414905@qq.com> Date: Thu, 31 Oct 2024 22:49:03 +0800 Subject: [PATCH] perf(TableSkeleton): improve skeleton component performance --- .../schema-component/antd/table-v2/Table.tsx | 2 + .../antd/table-v2/TableSkeleton.tsx | 135 ++++++++++++++++++ 2 files changed, 137 insertions(+) create mode 100644 packages/core/client/src/schema-component/antd/table-v2/TableSkeleton.tsx diff --git a/packages/core/client/src/schema-component/antd/table-v2/Table.tsx b/packages/core/client/src/schema-component/antd/table-v2/Table.tsx index 463a40722d..82caba977e 100644 --- a/packages/core/client/src/schema-component/antd/table-v2/Table.tsx +++ b/packages/core/client/src/schema-component/antd/table-v2/Table.tsx @@ -44,6 +44,7 @@ import { useSatisfiedActionValues } from '../../../schema-settings/LinkageRules/ import { useToken } from '../__builtins__'; import { SubFormProvider } from '../association-field/hooks'; import { ColumnFieldProvider } from './components/ColumnFieldProvider'; +import { TableSkeleton } from './TableSkeleton'; import { extractIndex, isCollectionFieldComponent, isColumnComponent } from './utils'; const RecursionFieldMemo = React.memo(RecursionField); @@ -930,6 +931,7 @@ export const Table: any = withDynamicSchemaProps( } return !!service?.loading; }, + SkeletonComponent: TableSkeleton, }, ), { displayName: 'NocoBaseTable' }, diff --git a/packages/core/client/src/schema-component/antd/table-v2/TableSkeleton.tsx b/packages/core/client/src/schema-component/antd/table-v2/TableSkeleton.tsx new file mode 100644 index 0000000000..b62379eb04 --- /dev/null +++ b/packages/core/client/src/schema-component/antd/table-v2/TableSkeleton.tsx @@ -0,0 +1,135 @@ +/** + * This file is part of the NocoBase (R) project. + * Copyright (c) 2020-2024 NocoBase Co., Ltd. + * Authors: NocoBase Team. + * + * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License. + * For more information, please refer to: https://www.nocobase.com/agreement. + */ + +import { css } from '@emotion/css'; +import React, { useMemo } from 'react'; +import { useToken } from '../__builtins__'; + +interface TableSkeletonProps { + rows?: number; + columns?: number; +} + +export const TableSkeleton: React.FC = ({ rows = 5, columns = 6 }) => { + const { token } = useToken(); + + const headerHeight = token.controlHeight * 2.06; // 66px + const bodyRowHeight = token.controlHeight * 1.75; // 56px + + const skeletonClass = useMemo( + () => css` + &.skeleton-wrapper { + width: 100%; + background: ${token.colorBgContainer}; + border-radius: ${token.borderRadiusLG}px; + overflow: hidden; + } + + .skeleton-table { + width: 100%; + border-collapse: separate; + border-spacing: 0; + } + + .skeleton-cell { + padding: ${token.padding}px ${token.padding}px; + border-bottom: 1px solid ${token.colorBorderSecondary}; + vertical-align: middle; + height: ${bodyRowHeight}px; + box-sizing: border-box; + } + + .skeleton-cell:first-child { + padding-left: ${token.padding + 2}px; + width: ${token.controlHeight * 1.2}px; + } + + .header { + background: ${token.colorFillQuaternary}; + } + + .header .skeleton-cell { + padding-top: ${token.padding}px; + padding-bottom: ${token.padding}px; + height: ${headerHeight}px; + } + + .skeleton-loading { + height: ${token.controlHeight / 2}px; + background: ${token.colorFillQuaternary}; + border-radius: ${token.borderRadiusSM}px; + } + + .skeleton-checkbox { + width: ${token.controlHeight / 2}px; + height: ${token.controlHeight / 2}px; + background: ${token.colorFillQuaternary}; + border-radius: ${token.borderRadiusSM}px; + } + + thead tr { + height: ${headerHeight}px; + } + + tbody tr { + height: ${bodyRowHeight}px; + } + `, + [ + bodyRowHeight, + headerHeight, + token.borderRadiusLG, + token.borderRadiusSM, + token.colorBgContainer, + token.colorBorderSecondary, + token.colorFillQuaternary, + token.controlHeight, + token.padding, + ], + ); + + return ( +
+ + + + + {Array(columns) + .fill(null) + .map((_, i) => ( + + ))} + + + + {Array(rows) + .fill(null) + .map((_, rowIndex) => ( + + + {Array(columns) + .fill(null) + .map((_, colIndex) => ( + + ))} + + ))} + +
+
+
+
+
+
+
+
+
+
+ ); +};