flutter-add-widget-preview

作者: flutter

使用previews.dart系統為專案新增互動式Widget預覽。在建立新的UI元件或更新現有畫面時使用,以確保…

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

Previewing Flutter Widgets

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, static methods within a class, or public widget constructors/factories that have no required arguments and return a Widget or WidgetBuilder.
  • Imports: Always import package:flutter/widget_previews.dart to access the preview annotations.
  • Custom Annotations: Extend the Preview class to create custom annotations that inject common properties (e.g., themes, wrappers) across multiple widgets.
  • Multiple Configurations: Apply multiple @Preview annotations to a single target to generate multiple preview instances. Alternatively, extend MultiPreview to encapsulate common multi-preview configurations.
  • Runtime Transformations: Override the transform() method in custom Preview or MultiPreview classes to modify preview configurations dynamically at runtime (e.g., generating names based on dynamic values, which is impossible in a const context).

Handling Limitations

Adhere to the following constraints when authoring previewable widgets, as the Widget Previewer runs in a web environment:

  • No Native APIs: Do not use native plugins or APIs from dart:io or dart:ffi. Widgets with transitive dependencies on dart:io or dart:ffi will throw exceptions upon invocation. Use conditional imports to mock or bypass these in preview mode.
  • Asset Paths: Use package-based paths for assets loaded via dart:ui fromAsset APIs (e.g., packages/my_package_name/assets/my_image.png instead of assets/my_image.png).
  • Public Callbacks: Ensure all callback arguments provided to preview annotations are public and constant to satisfy code generation requirements.
  • Constraints: Apply explicit constraints using the size parameter in the @Preview annotation if your widget is unconstrained, as the previewer defaults to constraining them to approximately half the viewport.

Workflows

Creating a Widget Preview

Copy and track this checklist when implementing a new widget preview:

  • Import package:flutter/widget_previews.dart.
  • Identify a valid target (top-level function, static method, or parameter-less public constructor).
  • Apply the @Preview annotation to the target.
  • Configure preview parameters (name, group, size, theme, brightness, etc.) as needed.
  • If applying the same configuration to multiple widgets, extract the configuration into a custom class extending Preview.

Interacting with Previews

Follow the appropriate conditional workflow to launch and interact with the Widget Previewer:

If using a supported 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 if you want to view previews outside the currently active file.

If using the Command Line:

  1. Navigate to the Flutter project's root directory.
  2. Run flutter widget-preview start.
  3. View the automatically opened Chrome environment.

Feedback Loop: Preview Iteration

  1. Modify the widget code or preview configuration.
  2. Observe the automatic update in the Widget Previewer.
  3. If global state (e.g., static initializers) was modified: Click the global hot restart button at the bottom right.
  4. If only the local widget state needs resetting: Click the individual hot restart button on the specific preview card.
  5. Review errors in the IDE/CLI console -> fix -> repeat.

Examples

Basic Preview

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

@Preview(name: 'My Sample Text', group: 'Typography')
Widget mySampleText() {
  return const Text('Hello, World!');
}

Custom Preview with Runtime Transformation

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

final class TransformativePreview extends Preview {
  const TransformativePreview({
    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();
    
    builder
      ..name = 'Transformed - ${originalPreview.name}'
      ..theme = _themeBuilder;

    return builder.toPreview();
  }
}

@TransformativePreview(name: 'Custom Themed Button')
Widget myButton() => const ElevatedButton(onPressed: null, child: Text('Click'));

MultiPreview Implementation

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

/// Creates light and dark mode previews automatically.
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() {
    final previews = super.transform();
    return previews.map((preview) {
      final builder = preview.toBuilder()
        ..group = 'Brightness'
        ..name = '$name - ${preview.brightness!.name}';
      return builder.toPreview();
    }).toList();
  }
}

@MultiBrightnessPreview(name: 'Primary Card')
Widget cardPreview() => const Card(child: Padding(padding: EdgeInsets.all(8.0), child: Text('Content')));

來自 flutter 的更多技能

dart-modern-features
flutter
為了尋找現代化的候選對象:
flutter-fix-layout-issues
flutter
使用 Dart 和 Flutter MCP 工具修復 Flutter 佈局錯誤(溢出、無限制約束)。適用於處理「RenderFlex overflowed」、「Vertical…」等問題。
adding-release-notes
flutter
在 DevTools 發行說明中新增使用者面向的變更描述。用於在 NEXT_RELEASE_NOTES.md 檔案中記錄改進、修正或新功能。
reviewing-devtools-prs
flutter
DevTools 儲存庫專用的 PR 審查工作流程,強制執行 DevTools 風格指南與常見審查模式。用於審查以下專案中的拉取請求時…
dart-use-primary-constructors
flutter
協助使用者撰寫語法與語意正確的 Dart 主要建構子,並遷移/使用新的建構子語法、空主體分號語法、…
code-documentation
flutter
編寫有效程式碼文件的指南,包括 docstrings、JSDoc、dartdoc 和實作註解。在編寫新程式碼、新增…時使用此技能。
api-review
flutter
根據規範的 API 設計指南審查指定的程式碼。當使用者要求進行 API 審查或檢查程式碼是否符合 API 設計時,請使用此技能。
flutter-accessibility
flutter
在 Flutter 應用程式中實作 WCAG 2 與 EN 301 549 無障礙標準及自適應佈局。強制執行語意標註、觸控目標尺寸(最小 48x48 dp)以及文字對比度(小字 4.5:1,大字 3:1),涵蓋行動裝置、網頁與桌面平台。提供網頁語意初始化、互動元件包裝、基於螢幕尺寸的佈局切換,以及鍵盤/滑鼠輸入處理的決策邏輯。包含透過 FocusTraversalGroup 進行的焦點導覽管理,以及...