v1.0
Guides / Page 02·06

Transitions

Animate widget movement with CSS transitions or springs.

Flexiboards is headless, so widgets jump between cells by default. Set transition on a widget, or on widgetDefaults, to animate the movement instead. cssTransitionConfig() supplies the default durations and easing. These demos use native controls and the example styling. They disable movement when the system requests reduced motion:

Svelte Example.svelte

Reduced motion is on; widgets move without animation.

Press Enter to grab or resize widgets. Once grabbed, use Arrow keys to move/resize the widget, Enter to confirm the action, or Esc to cancel it.
A
B

Enable transitions and drag a widget to an empty cell. The dropped widget animates into place unless reduced motion is enabled. Toggle the system preference while the demo is open to check that it updates.

Choosing a preset

Two presets ship with the library. Each returns a complete transition configuration:

  • cssTransitionConfig() uses sine in-out for 150ms moves, circ-out for 200ms drops, and ease-out for 150ms resizing.
  • springTransitionConfig() uses response times of 0.20s for moves, 0.24s for drops, and 0.18s for resizing, with a small bounce on drop. These control the spring’s response, rather than a fixed end time.

simpleTransitionConfig() is deprecated. It retains the original 150ms preset, with ease-in-out for moves and ease-out for drops and resizing.

The CSS preset accepts global easing overrides through --ease-flexi-move, --ease-flexi-drop, and --ease-flexi-resize. Compare CSS and spring motion in the registry demo.

Customising transitions

A transition configuration has three optional entries, move, drop, and resize, one per kind of widget movement. Each is either a plain { duration, easing } object (a CSS transition, with duration in milliseconds and any CSS easing function including cubic-bezier()), or an animation adapter:

  • cssTransition({ duration, easing }) is what the plain object resolves to.
  • spring({ duration, bounce }) is a dependency-free spring using SwiftUI’s parameterisation: duration in seconds is the response time, and bounce runs from 0 (critically damped) to 1.

Mix them per entry, for example a spring for drop and a CSS transition for resize. Any entry you omit plays no animation. The exact shape is in the FlexiWidgetTransitionConfiguration reference.

The example below drives the move and drop durations from a slider:

Svelte Example.svelte

Reduced motion is on; widgets move without animation.

Press Enter to grab or resize widgets. Once grabbed, use Arrow keys to move/resize the widget, Enter to confirm the action, or Esc to cancel it.
A
B

Gotchas

  • Why plain CSS transitions don’t work. Widgets are placed with grid-row and grid-column, which CSS cannot transition. The library measures the before and after boxes and animates a transform between them, so add your transitions through this configuration rather than a stylesheet.
  • Reduced motion. Transitions are opt-in, so honour prefers-reduced-motion by leaving transition unset when it matches. See Accessibility.
  • Configuration lives in core. The presets, adapters, and types come from @flexiboards/core and are re-exported by each adapter package, so the configuration is identical across frameworks.