Stagger

list

Staggers enter/exit animations across a list of children.

Preview

Installation

Terminal
flutter pub add nib_motion

Usage

dart
NibMotionList(
  initial: NibAnim(opacity: 0, y: 32),
  animate: NibAnim(opacity: 1, y: 0),
  staggerDelay: Duration(milliseconds: 60),
  children: items.map((item) => ItemCard(item)).toList(),
)

Examples

Stagger List

Each child animates in with an offset delay — use NibMotionList for automatic staggering.

dart
class StaggerListExample extends StatefulWidget {
  const StaggerListExample({super.key});

  @override
  State<StaggerListExample> createState() => _StaggerListExampleState();
}

class _StaggerListExampleState extends State<StaggerListExample> {
  final _signal = NibMotionReplaySignal();

  static const _items = ['Spring physics', 'Gesture states', 'Exit animations', 'Viewport triggers'];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: const Color(0xFF0D1117),
      body: Column(
        children: [
          Expanded(
            child: Center(
              child: NibMotionReplayScope(
                signal: _signal,
                child: NibMotionList(
                  initial: const NibAnim(opacity: 0, y: 16),
                  animate: const NibAnim(opacity: 1, y: 0),
                  staggerDelay: const Duration(milliseconds: 80),
                  transition: NibTransition.springGentle,
                  children: _items
                      .map(
                        (label) => Padding(
                          key: ValueKey(label),
                          padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 5),
                          child: Container(
                            height: 48,
                            decoration: BoxDecoration(
                              color: const Color(0xFF1C2537),
                              borderRadius: BorderRadius.circular(10),
                              border: Border.all(color: const Color(0xFF54C5F8).withAlpha(30)),
                            ),
                            child: Center(
                              child: Text(label, style: const TextStyle(color: Color(0xFFEDF2F7), fontSize: 14)),
                            ),
                          ),
                        ),
                      )
                      .toList(),
                ),
              ),
            ),
          ),
          Padding(
            padding: const EdgeInsets.only(bottom: 24),
            child: TextButton.icon(
              onPressed: _signal.replay,
              icon: const Icon(Icons.replay, size: 16, color: Color(0xFF718096)),
              label: const Text('Replay', style: TextStyle(color: Color(0xFF718096), fontSize: 13)),
            ),
          ),
        ],
      ),
    );
  }
}

Stagger Reverse

Reverse direction staggers from last child to first — useful for exit sequences.

dart
class StaggerReverseExample extends StatefulWidget {
  const StaggerReverseExample({super.key});

  @override
  State<StaggerReverseExample> createState() => _StaggerReverseExampleState();
}

class _StaggerReverseExampleState extends State<StaggerReverseExample> {
  final _signal = NibMotionReplaySignal();

  static const _items = ['First', 'Second', 'Third', 'Fourth'];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: const Color(0xFF0D1117),
      body: Column(
        children: [
          Expanded(
            child: Center(
              child: NibMotionReplayScope(
                signal: _signal,
                child: NibMotionList(
                  initial: const NibAnim(opacity: 0, y: 16),
                  animate: const NibAnim(opacity: 1, y: 0),
                  staggerDelay: const Duration(milliseconds: 100),
                  staggerDirection: NibStaggerDirection.reverse,
                  transition: NibTransition.springGentle,
                  children: _items
                      .map(
                        (label) => Padding(
                          key: ValueKey(label),
                          padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 5),
                          child: Container(
                            height: 48,
                            decoration: BoxDecoration(
                              color: const Color(0xFF1C2537),
                              borderRadius: BorderRadius.circular(10),
                              border: Border.all(color: const Color(0xFF54C5F8).withAlpha(30)),
                            ),
                            child: Center(
                              child: Text(label, style: const TextStyle(color: Color(0xFFEDF2F7), fontSize: 14)),
                            ),
                          ),
                        ),
                      )
                      .toList(),
                ),
              ),
            ),
          ),
          Padding(
            padding: const EdgeInsets.only(bottom: 24),
            child: TextButton.icon(
              onPressed: _signal.replay,
              icon: const Icon(Icons.replay, size: 16, color: Color(0xFF718096)),
              label: const Text('Replay', style: TextStyle(color: Color(0xFF718096), fontSize: 13)),
            ),
          ),
        ],
      ),
    );
  }
}

Stagger In View

Stagger triggered when items enter the viewport — no manual scroll listener needed.

dart
class StaggerInViewExample extends StatelessWidget {
  const StaggerInViewExample({super.key});

  static const _items = [
    'Scroll to reveal',
    'Each item fades',
    'In staggered order',
    'Using whileInView',
    'With per-item delay',
    'No scroll listener',
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: const Color(0xFF0D1117),
      body: ListView.builder(
        padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 16),
        itemCount: _items.length,
        itemBuilder: (context, index) => Padding(
          padding: const EdgeInsets.only(bottom: 10),
          child: NibMotion(
            initial: const NibAnim(opacity: 0, y: 20),
            whileInView: const NibAnim(opacity: 1, y: 0),
            viewport: const NibInViewConfig(amount: 0.3, once: false),
            transition: NibTransition(
              spring: NibSpringDescription.gentle,
              delay: Duration(milliseconds: index * 60),
            ),
            child: Container(
              height: 48,
              decoration: BoxDecoration(
                color: const Color(0xFF1C2537),
                borderRadius: BorderRadius.circular(10),
                border: Border.all(color: const Color(0xFF54C5F8).withAlpha(30)),
              ),
              child: Center(
                child: Text(_items[index], style: const TextStyle(color: Color(0xFFEDF2F7), fontSize: 14)),
              ),
            ),
          ),
        ),
      ),
    );
  }
}

API Reference

API class

NibMotionList

API Properties

initialanimateexitstaggerDelaystaggerDirection