From edc7143f77c427a71443d83f097d78a49eabda98 Mon Sep 17 00:00:00 2001
From: Philipinho <16838612+Philipinho@users.noreply.github.com>
Date: Tue, 28 Apr 2026 11:34:08 +0100
Subject: [PATCH] fix(base): match inline-embed placeholder skeleton to seeded
3 col / 1 row shape
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The placeholder rendered a default 10×6 BaseTableSkeleton while
waiting on the create-base API, then swapped to the real table once
the response landed. Because the inline-embed flow now seeds
Title + Text 1 + Text 2 with one default row, the real table is 3×1
— the swap visibly collapsed a large fake table down to a small
empty one. The scroll didn't jump (initialOffset takes care of that)
but the flicker was jarring.
Re-introduce rows + columns props on BaseTableSkeleton (default still
10 / 6 so other call sites are unaffected) and pass rows=1 columns=3
from the inline-embed placeholder so the swap is visually stable.
---
.../base/components/base-table-skeleton.tsx | 29 ++++++++++++++-----
.../components/base-embed/base-embed-view.tsx | 9 ++++--
2 files changed, 27 insertions(+), 11 deletions(-)
diff --git a/apps/client/src/features/base/components/base-table-skeleton.tsx b/apps/client/src/features/base/components/base-table-skeleton.tsx
index dfcae12fc..9e499fbc2 100644
--- a/apps/client/src/features/base/components/base-table-skeleton.tsx
+++ b/apps/client/src/features/base/components/base-table-skeleton.tsx
@@ -4,18 +4,31 @@ 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;
+const DEFAULT_COLUMN_COUNT = 6;
+const DEFAULT_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() {
+type BaseTableSkeletonProps = {
+ // Override the rendered shape to match what the eventual content
+ // will be — the inline-embed placeholder passes rows=1, columns=3
+ // (matching the seeded Title + Text 1 + Text 2 with one default
+ // row) so the swap from skeleton to real table doesn't visibly
+ // collapse a large fake table down to a small empty one.
+ rows?: number;
+ columns?: number;
+};
+
+export function BaseTableSkeleton({
+ rows = DEFAULT_ROW_COUNT,
+ columns = DEFAULT_COLUMN_COUNT,
+}: BaseTableSkeletonProps = {}) {
const gridTemplateColumns = [
`${ROW_NUMBER_WIDTH}px`,
- ...Array.from({ length: COLUMN_COUNT }, () => `${COLUMN_WIDTH}px`),
+ ...Array.from({ length: columns }, () => `${COLUMN_WIDTH}px`),
].join(" ");
return (
@@ -41,27 +54,27 @@ export function BaseTableSkeleton() {