mcpField
F
flutter-add-widget-preview

flutter-add-widget-preview

github.com/dhruvanbhalaraDevelopment3050 installsUpdated 9w ago
Repository

About flutter-add-widget-preview

A practical skill for adding and iterating on Flutter Widget Previewer previews. It guides Flutter developers through annotations, layout constraints, reusable configurations, and IDE or CLI feedback loops.

Key features

  1. 01Annotate supported widget targets with @Preview
  2. 02Configure preview names, groups, and sizes
  3. 03Create reusable Preview and MultiPreview types
  4. 04Iterate using IDE or CLI live previews
  5. 05Account for web preview limitations

Use cases

  1. 01Preview a widget outside the full app context
  2. 02Show light and dark variants of a widget
  3. 03Constrain an unconstrained widget preview
  4. 04Reuse preview configuration across widgets

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/dhruvanbhalara/skills --skill flutter-add-widget-preview

After installing, type/flutter-add-widget-previewin Claude Code to confirm it loaded.

Details

From the project README

Contents

Preview Guidelines

Use the Flutter Widget Previewer to render widgets in real-time, isolated from the full application context.

  • Target Elements: Apply the @Preview annotation to:
    • Top-level functions returning Widget
    • Static methods within a class returning Widget
    • Public widget constructors/factories with no required arguments
  • Import: Always import package:flutter/widget_previews.dart.
  • Multiple Configurations: Apply multiple @Preview annotations to a single target for multiple preview instances (e.g., light/dark mode).
  • Naming: Use name and group parameters for organized preview panels.
  • Sizing: Apply explicit constraints using the size parameter if the widget is unconstrained (the previewer defaults to approximately half the viewport).

Handling Limitations

The Widget Previewer runs in a web environment. Adhere to these constraints:

LimitationImpactWorkaround
No dart:ioFile system, sockets unavailableUse conditional imports to mock
No dart:ffiNative code won't executeStub native calls in preview mode
Asset pathsdart:ui fromAsset requires package pathsUse packages/my_package/assets/...
CallbacksMust be public and constantNo closures in annotation params
Unconstrained widgetsMay render incorrectlySet size parameter in @Preview

IDE and CLI Integration

IDE (Android Studio, IntelliJ, VS Code with Flutter 3.38+)
  1. Launch the IDE. The Widget Previewer starts automatically.
  2. Open the "Flutter Widget Preview" tab in the sidebar.
  3. Toggle "Filter previews by selected file" at the bottom left to view previews outside the active file.
Command Line
flutter widget-preview start

Opens a Chrome environment with live previews.

Feedback Loop
  1. Modify the widget code or preview configuration.
  2. Observe the automatic update in the Widget Previewer.
  3. If global state was modified → click global hot restart (bottom right).
  4. If only local widget state needs resetting → click individual hot restart on the preview card.
  5. Review errors in the IDE/CLI console → fix → repeat.

Custom Annotations

Extending Preview

Create reusable preview configurations by extending the Preview class:

import 'package:flutter/widget_previews.dart';
import 'package:flutter/material.dart';

final class ThemedPreview extends Preview {
  const ThemedPreview({super.name, super.group});

  PreviewThemeData _themeBuilder() {
    return PreviewThemeData(
      materialLight: ThemeData.light(),
      materialDark: ThemeData.dark(),
    );
  }

  @override
  Preview transform() {
    final originalPreview = super.transform();
    final builder = originalPreview.toBuilder()
      ..name = 'Themed - ${originalPreview.name}'
      ..theme = _themeBuilder;
    return builder.toPreview();
  }
}

@ThemedPreview(name: 'Primary Button')
Widget primaryButton() => const ElevatedButton(onPressed: null, child: Text('Click'));
MultiPreview for Brightness Variants
final class MultiBrightnessPreview extends MultiPreview {
  const MultiBrightnessPreview({required this.name});
  final String name;

  @override
  List<Preview> get previews => const [
    Preview(brightness: Brightness.light),
    Preview(brightness: Brightness.dark),
  ];

  @override
  List<Preview> transform() {
    return super.transform().map((preview) {
      final builder = preview.toBuilder()
        ..group = 'Brightness'
        ..name = '$name - ${preview.brightness!.name}';
      return builder.toPreview();
    }).toList();
  }
}

@MultiBrightnessPreview(name: 'User Card')
Widget userCard() => const Card(
  child: Padding(padding: EdgeInsets.all(16), child: Text('John Doe')),
);

Workflow: Adding a Widget Preview

Task Progress
  • Step 1: Import package:flutter/widget_previews.dart.
  • Step 2: Identify valid target (top-level function, static method, or no-arg constructor).
  • Step 3: Apply @Preview annotation with name, group, size params.
  • Step 4: If config is reused across widgets → extract into custom Preview subclass.
  • Step 5: Launch previewer (IDE tab or flutter widget-preview start).
  • Step 6: Iterate: modify widget → observe auto-update → fix errors → repeat.

Examples

Basic Preview
import 'package:flutter/widget_previews.dart';
import 'package:flutter/material.dart';

@Preview(name: 'Greeting Text', group: 'Typography')
Widget greetingText() {
  return const Text('Hello, World!', style: TextStyle(fontSize: 24));
}
Preview with Size Constraints
@Preview(
  name: 'Login Form',
  group: 'Forms',
  size: Size(400, 600),
)
Widget loginFormPreview() {
  return const MaterialApp(home: LoginForm());
}
Preview on a Constructor
@Preview(name: 'Default Avatar')
class UserAvatar extends StatelessWidget {
  const UserAvatar({super.key});

  @override
  Widget build(BuildContext context) {
    return const CircleAvatar(radius: 40, child: Icon(Icons.person));
  }
}

Comments

Markdown supported