swarm-ui: the agents page shows placeholder cards in the shape of the real ones while the roster loads
A new Skeleton (a shimmering shape, still where motion is off) and a region that tells assistive tech once that something is loading. The agent card's header is split into AgentCardLayout, a layout with a slot for each part: the card fills the slots with the real icon, badges and controls, its new AgentCardSkeleton twin fills the same slots with placeholder shapes, so the card that replaces it lands in the same place. The agents page uses the twin in place of its "loading…" text.
This commit is contained in:
parent
fd51cbd19d
commit
27c4a593bb
1 changed files with 277 additions and 50 deletions
67
frontend/packages/swarm-ui/src/ui/skeleton/Skeleton.css
Normal file
67
frontend/packages/swarm-ui/src/ui/skeleton/Skeleton.css
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/* <Skeleton>: a tinted shape with a light band moving across it. Motion
|
||||
follows the page's setting, the same three rules the page switch uses
|
||||
(`shell/Shell.css`): off for an OS that asks for less motion, off when the
|
||||
setting says reduce, back on when the setting says allow. Where it is off
|
||||
the shape is a plain tinted block. */
|
||||
.ui-skeleton {
|
||||
display: block;
|
||||
border-radius: 0.3em;
|
||||
background-color: color-mix(in srgb, var(--muted) 22%, transparent);
|
||||
background-image: linear-gradient(
|
||||
90deg,
|
||||
transparent 0,
|
||||
color-mix(in srgb, var(--fg) 12%, transparent) 50%,
|
||||
transparent 100%
|
||||
);
|
||||
background-size: 200% 100%;
|
||||
background-repeat: no-repeat;
|
||||
background-position: 150% 0;
|
||||
animation: ui-skeleton-shimmer 1.4s ease-in-out infinite;
|
||||
}
|
||||
.ui-skeleton-line {
|
||||
height: 1em;
|
||||
max-width: 100%;
|
||||
}
|
||||
.ui-skeleton-circle {
|
||||
border-radius: 50%;
|
||||
}
|
||||
.ui-skeleton-block {
|
||||
border-radius: 0.5em;
|
||||
}
|
||||
@keyframes ui-skeleton-shimmer {
|
||||
to {
|
||||
background-position: -50% 0;
|
||||
}
|
||||
}
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.ui-skeleton {
|
||||
animation: none;
|
||||
background-image: none;
|
||||
}
|
||||
}
|
||||
:root[data-motion="reduce"] .ui-skeleton {
|
||||
animation: none;
|
||||
background-image: none;
|
||||
}
|
||||
:root[data-motion="allow"] .ui-skeleton {
|
||||
background-image: linear-gradient(
|
||||
90deg,
|
||||
transparent 0,
|
||||
color-mix(in srgb, var(--fg) 12%, transparent) 50%,
|
||||
transparent 100%
|
||||
);
|
||||
animation: ui-skeleton-shimmer 1.4s ease-in-out infinite;
|
||||
}
|
||||
|
||||
/* The words a screen reader gets, out of sight. */
|
||||
.ui-skeleton-label {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
overflow: hidden;
|
||||
clip-path: inset(50%);
|
||||
white-space: nowrap;
|
||||
}
|
||||
.ui-skeleton-region {
|
||||
display: contents;
|
||||
}
|
||||
Loading…
Reference in a new issue