Match list skeletons to the card surface
ListItemSkeleton reused a sand-2 fill that read as a different card; use the real row shell with pulse bars instead, and shrink the updates skeleton to five rows. Signed-off-by: Émile Ré <emile@probo.com>
This commit is contained in:
@@ -27,7 +27,10 @@ import { HeaderBand } from "#/components/HeaderBand/HeaderBand";
|
||||
import { pageHeader } from "#/components/PageHeader/variants";
|
||||
|
||||
import { updatesList } from "./_components/variants";
|
||||
import { UPDATES_PAGE_SIZE } from "./_lib/constants";
|
||||
|
||||
// Placeholder rows for the loading card — enough to read as a list, far fewer
|
||||
// than UPDATES_PAGE_SIZE so the skeleton does not dominate the viewport.
|
||||
const UPDATES_SKELETON_COUNT = 5;
|
||||
|
||||
export function UpdatesPageSkeleton() {
|
||||
const { card, rows } = updatesList();
|
||||
@@ -47,7 +50,7 @@ export function UpdatesPageSkeleton() {
|
||||
<div className="flex w-full max-w-5xl flex-col gap-8">
|
||||
<div className={card()} aria-hidden>
|
||||
<div className={rows()}>
|
||||
{Array.from({ length: UPDATES_PAGE_SIZE }, (_, index) => (
|
||||
{Array.from({ length: UPDATES_SKELETON_COUNT }, (_, index) => (
|
||||
<ComplianceArticleItemSkeleton key={index} />
|
||||
))}
|
||||
</div>
|
||||
|
||||
@@ -32,7 +32,7 @@ export const dialog = tv({
|
||||
],
|
||||
popup: [
|
||||
"fixed left-1/2 top-1/2 z-5 -translate-x-1/2 -translate-y-1/2",
|
||||
"flex w-[calc(100vw-2rem)] max-w-[600px] flex-col gap-4",
|
||||
"flex w-[calc(100vw-2rem)] max-w-150 flex-col gap-4",
|
||||
"max-h-[calc(100vh-2rem)] overflow-y-auto overflow-x-clip",
|
||||
"rounded-5 border border-sand-6 bg-sand-1 py-6 shadow-6 outline-none",
|
||||
"transition-all duration-150",
|
||||
@@ -51,7 +51,7 @@ export const dialog = tv({
|
||||
// so a placeholder can render before Base UI (and the content) loads.
|
||||
export const dialogSkeleton = tv({
|
||||
base: [
|
||||
"flex w-full max-w-[600px] flex-col gap-4",
|
||||
"flex w-full max-w-150 flex-col gap-4",
|
||||
"rounded-5 border border-sand-6 bg-sand-1 py-6 shadow-6",
|
||||
],
|
||||
});
|
||||
|
||||
@@ -20,15 +20,24 @@
|
||||
|
||||
import type { ComponentProps } from "react";
|
||||
|
||||
import { TextSkeleton } from "../typography/TextSkeleton";
|
||||
|
||||
import { list } from "./variants";
|
||||
|
||||
export type ListItemSkeletonProps = Omit<ComponentProps<"li">, "children">;
|
||||
|
||||
// Loading placeholder paired with ListItem: a pulse bar that keeps the row
|
||||
// dividers of a List.
|
||||
// Loading placeholder paired with ListItem: same row shell (card background +
|
||||
// dividers) with pulse bars for the primary column — not a filled sand-2 slab.
|
||||
export function ListItemSkeleton(props: ListItemSkeletonProps) {
|
||||
const { className, ...rest } = props;
|
||||
const { skeletonItem } = list();
|
||||
const { item, content } = list();
|
||||
|
||||
return <li className={skeletonItem({ className })} aria-hidden {...rest} />;
|
||||
return (
|
||||
<li className={item({ className })} aria-hidden {...rest}>
|
||||
<div className={content()}>
|
||||
<TextSkeleton size={2} className="w-40" />
|
||||
<TextSkeleton size={1} className="w-24" />
|
||||
</div>
|
||||
</li>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -27,6 +27,5 @@ export const list = tv({
|
||||
root: "list-none overflow-hidden rounded-4 border border-sand-a3 bg-sand-1",
|
||||
item: "flex items-center gap-4 border-b border-sand-a3 px-4 py-3 last:border-b-0",
|
||||
content: "flex min-w-0 flex-1 flex-col gap-0.5",
|
||||
skeletonItem: "h-16 animate-pulse border-b border-sand-a3 bg-sand-2 last:border-b-0",
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user