Files
windmill/frontend/src/lib/utils/paint.ts
T
GuilhemandClaude Opus 5 66bffaa60d feat: add empty state cards to list pages (#10726)
* feat: add empty state cards to list pages

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: animate trigger drawers on first open

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: distinguish filtered-empty schedules, reuse the rAF helper

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: hide the header create button while the empty state offers it

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Revert "fix: hide the header create button while the empty state offers it"

This reverts commit 98c57eede3.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: use the default variant for the empty state button

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* refactor: share hasActiveFilters from the filter searchbar module

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-17 21:14:11 +02:00

33 lines
1.1 KiB
TypeScript

import { tick } from 'svelte'
/**
* Resolve on the next animation frame, or immediately where there is no rAF (SSR).
*/
export function nextAnimationFrame(): Promise<void> {
return new Promise((resolve) => {
if (typeof requestAnimationFrame === 'function') {
requestAnimationFrame(() => resolve())
} else {
resolve()
}
})
}
/**
* Flush pending DOM updates, then wait until the browser has painted them.
*
* A lazily-mounted drawer creates its panel and gets its `open` class in the same
* flush. A CSS transition takes its start value from the last painted computed
* style, so without a painted closed state the panel snaps open instead of sliding.
* `tick()` alone only flushes the DOM, it does not wait for a paint.
*
* The second frame is load-bearing: a requestAnimationFrame callback runs *before*
* the paint it is scheduled against, so one frame still leaves the closed state
* unpainted. Measured — with a single frame the panel does not transition at all.
*/
export async function tickPainted(): Promise<void> {
await tick()
await nextAnimationFrame()
await nextAnimationFrame()
}