From b01f6e9af91e1d2c355e6ee6f27d176faff76dd2 Mon Sep 17 00:00:00 2001 From: Philipinho <16838612+Philipinho@users.noreply.github.com> Date: Sat, 18 Apr 2026 22:22:11 +0100 Subject: [PATCH] feat(base): add layout-matching skeleton loading component --- .../base/components/base-table-skeleton.tsx | 84 +++++++++++++++++++ .../styles/base-table-skeleton.module.css | 47 +++++++++++ 2 files changed, 131 insertions(+) create mode 100644 apps/client/src/features/base/components/base-table-skeleton.tsx create mode 100644 apps/client/src/features/base/styles/base-table-skeleton.module.css diff --git a/apps/client/src/features/base/components/base-table-skeleton.tsx b/apps/client/src/features/base/components/base-table-skeleton.tsx new file mode 100644 index 00000000..dfcae12f --- /dev/null +++ b/apps/client/src/features/base/components/base-table-skeleton.tsx @@ -0,0 +1,84 @@ +import { Skeleton } from "@mantine/core"; +import gridClasses from "@/features/base/styles/grid.module.css"; +import classes from "@/features/base/styles/base-table-skeleton.module.css"; + +const ROW_NUMBER_WIDTH = 64; +const COLUMN_WIDTH = 180; +const COLUMN_COUNT = 6; +const ROW_COUNT = 10; + +// Deterministic per-cell widths so the skeleton doesn't flicker between +// renders. Values are rough normal distribution around 55-85 % of cell. +const CELL_WIDTH_RATIOS = [0.78, 0.62, 0.84, 0.55, 0.71, 0.66]; +const HEADER_WIDTH_RATIOS = [0.42, 0.58, 0.5, 0.64, 0.46, 0.54]; + +export function BaseTableSkeleton() { + const gridTemplateColumns = [ + `${ROW_NUMBER_WIDTH}px`, + ...Array.from({ length: COLUMN_COUNT }, () => `${COLUMN_WIDTH}px`), + ].join(" "); + + return ( +