feat(ui): orchestrated page reveal + stagger motion primitives

Assisted-by: Claude:claude-opus-4-8 [Claude Code]
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
This commit is contained in:
Ettore Di Giacinto
2026-06-18 10:07:54 +00:00
parent 53af1807b6
commit 7d501f1ba1
4 changed files with 31 additions and 1 deletions

View File

@@ -17,4 +17,12 @@ test.describe('Editorial design system', () => {
const shadow = await active.evaluate(el => getComputedStyle(el).boxShadow)
expect(shadow).not.toBe('none')
})
test('page reveal animation is defined on .page-transition', async ({ page }) => {
await page.goto('/app/settings')
const pt = page.locator('.page-transition').first()
await expect(pt).toBeVisible({ timeout: 15_000 })
const name = await pt.evaluate(el => getComputedStyle(el).animationName)
expect(name).toBe('pageReveal')
})
})

View File

@@ -2900,7 +2900,7 @@ select.input {
/* Page route transitions */
.page-transition {
animation: fadeIn 200ms ease;
animation: pageReveal var(--duration-reveal) var(--ease-reveal) both;
display: flex;
flex-direction: column;
flex: 1;
@@ -2908,6 +2908,18 @@ select.input {
min-width: 0;
}
@keyframes pageReveal {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
/* Orchestrated child stagger - opt-in via .reveal-stagger on a container.
Each direct child reveals with an incremental delay driven by --reveal-index. */
.reveal-stagger > * {
animation: pageReveal var(--duration-reveal) var(--ease-reveal) both;
animation-delay: calc(var(--reveal-index, 0) * 60ms);
}
/* Chat-specific styles */
.chat-layout {
display: flex;

View File

@@ -0,0 +1,8 @@
// Returns an inline style setting --reveal-index for orchestrated reveals.
// Usage: <div className="reveal-stagger"> {items.map((it, i) => (
// <Row key={it.id} style={staggerStyle(i)} />))} </div>
// Provided as a plain helper (not a hook) so it can be called in a map
// without violating rules-of-hooks. File name kept for discoverability.
export function staggerStyle(index) {
return { '--reveal-index': index }
}

View File

@@ -101,6 +101,8 @@
--duration-slow: 260ms;
--ease-default: cubic-bezier(0.22, 1, 0.36, 1);
--ease-spring: cubic-bezier(0.22, 1, 0.36, 1);
--duration-reveal: 420ms;
--ease-reveal: cubic-bezier(0.16, 1, 0.3, 1); /* ease-out-expo-ish */
/* Spacing */
--spacing-xs: 0.25rem;