diff --git a/dev/snippets/README.md b/dev/snippets/README.md index 9f678789f51..6d4fa62b0dc 100644 --- a/dev/snippets/README.md +++ b/dev/snippets/README.md @@ -1,59 +1,135 @@ -## Snippet Tool +# Dartdoc Generation -This is a dartdoc extension tool that takes code snippets and expands how they -are presented so that Flutter can have more interactive and useful code -snippets. +The Flutter API documentation contains code blocks that help provide +context or a good starting point when learning to use any of Flutter's APIs. -This takes code in dartdocs, like this: +To generate these code blocks, Flutter uses dartdoc tools to turn documentation +in the source code into API documentation, as seen on https://api.flutter.dev/. + +## Table of Contents + +- [Types of code blocks](#types-of-code-blocks) + - [Sample tool](#sample-tool) + - [Snippet tool](#snippet-tool) +- [Skeletons](#skeletons) +- [Test Doc Generation Workflow](#test-doc-generation-workflow) +## Types of code blocks + +### Sample Tool + +![Code sample image](assets/code_sample.png) + +The code `sample` tool generates a block containing a description and example +code. Here is an example of the code `sample` tool in use: ```dart -/// {@tool snippet --template="stateless_widget"} -/// The following is a skeleton of a stateless widget subclass called `GreenFrog`. -/// ```dart -/// class GreenFrog extends StatelessWidget { -/// const GreenFrog({ Key key }) : super(key: key); +/// {@tool sample} /// -/// @override -/// Widget build(BuildContext context) { -/// return Container(color: const Color(0xFF2DBD3A)); -/// } +/// If the avatar is to have an image, the image should be specified in the +/// [backgroundImage] property: +/// +/// ```dart +/// CircleAvatar( +/// backgroundImage: NetworkImage(userAvatarUrl), +/// ) +/// ``` +/// {@end-tool} +``` + +This will generate sample code that can be copied to the clipboard and added +to existing applications. + +This uses the skeleton for [sample](config/skeletons/sample.html) snippets. + +### Snippet Tool + +![Code snippet image](assets/code_snippet.png) + +The code `snippet` tool can expand sample code into full Flutter applications. +These sample applications can be directly copied and used to demonstrate the +API's functionality in a sample application: + +```dart +/// {@tool snippet --template=stateless_widget_material} +/// This example shows how to make a simple [FloatingActionButton] in a +/// [Scaffold], with a pink [backgroundColor] and a thumbs up [Icon]. +/// +/// ```dart +/// Widget build(BuildContext context) { +/// return Scaffold( +/// appBar: AppBar( +/// title: Text('Floating Action Button Sample'), +/// ), +/// body: Center( +/// child: Text('Press the button below!') +/// ), +/// floatingActionButton: FloatingActionButton( +/// onPressed: () { +/// // Add your onPressed code here! +/// }, +/// child: Icon(Icons.thumb_up), +/// backgroundColor: Colors.pink, +/// ), +/// ); /// } /// ``` /// {@end-tool} ``` -And converts it into something which has a nice visual presentation, and -a button to automatically copy the sample to the clipboard. +This uses the skeleton for [application](config/skeletons/application.html) +snippets. -It does this by processing the source input and emitting HTML for output, -which dartdoc places back into the documentation. Any options given to the - `{@tool ...}` directive are passed on verbatim to the tool. +Code `snippets` also allow for quick Flutter app generation using the following command: -To render the above, the snippets tool needs to render the code in a combination -of markdown and HTML, using the `{@inject-html}` dartdoc directive. +```bash +flutter create --sample=[directory.File.sampleNumber] [name_of_project_directory] +``` -## Templates +#### Templates In order to support showing an entire app when you click on the right tab of -the code snippet UI, we have to be able to insert the snippet into the template +the code snippet UI, we have to be able to insert the `snippet` into the template and instantiate the right parts. To do this, there is a [config/templates](config/templates) directory that contains a list of templates. These templates represent an entire app that the -snippet can be placed into, basically a replacement for `lib/main.dart` in a +`snippet` can be placed into, basically a replacement for `lib/main.dart` in a flutter app package. +For more information about how to create, use, or update templates, see +[config/templates/README.md](config/templates/README.md). + ## Skeletons -A skeleton (in relation to this tool, in the [config/skeletons](config/skeletons) -directory) is an HTML template into which the snippet Dart code and description -are interpolated, in order to display it nicely. +A skeleton (in relation to this tool) is an HTML template into which the Dart +code blocks and descriptions are interpolated. There is currently one skeleton for -[application](config/skeletons/application.html) snippets and one for -[sample](config/skeletons/sample.html) -snippets, but there could be more. It uses mustache notation (e.g. `{{code}}`) -to mark where the components to be interpolated into the template should go. +[application](config/skeletons/application.html) `snippets` and one for +[sample](config/skeletons/sample.html) `snippets`, but there could be more. -(It doesn't actually use the mustache package, since the only things that need -substituting are simple strings, but it uses the same syntax). +Skeletons use mustache notation (e.g. `{{code}}`) to mark where components will +be interpolated into the template. It doesn't actually use the mustache +package, since these are simple string substitutions, but it uses the same +syntax. + +The code block generation tools process the source input and emit HTML for output, +which dartdoc places back into the documentation. Any options given to the + `{@tool ...}` directive are passed on verbatim to the tool. + +The `snippets` tool renders these examples through a combination of markdown +and HTML using the `{@inject-html}` dartdoc directive. + +## Test Doc Generation Workflow + +If you are making changes to an existing code block or are creating a new code +block, follow these steps to generate a local copy of the API docs and verify +that your code blocks are showing up correctly: + +1. Make an update to a code block or create a new code block. +2. From the root directory, run `./dev/bots/docs.sh`. This should start +generating a local copy of the API documentation. +3. Once complete, check `./dev/docs/doc` to check your API documentation. The +search bar will not work locally, so open `./dev/docs/doc/index.html` to +navigate through the documentation, or search `./dev/docs/doc/flutter` for your +page of interest. diff --git a/dev/snippets/assets/code_sample.png b/dev/snippets/assets/code_sample.png new file mode 100644 index 00000000000..3a9b91debff Binary files /dev/null and b/dev/snippets/assets/code_sample.png differ diff --git a/dev/snippets/assets/code_snippet.png b/dev/snippets/assets/code_snippet.png new file mode 100644 index 00000000000..8fb51b22497 Binary files /dev/null and b/dev/snippets/assets/code_snippet.png differ diff --git a/dev/snippets/config/templates/README.md b/dev/snippets/config/templates/README.md index 1f832388a65..071da8b4a6e 100644 --- a/dev/snippets/config/templates/README.md +++ b/dev/snippets/config/templates/README.md @@ -10,13 +10,13 @@ syntax inside of the dartdoc comment for a Flutter class/variable/enum/etc.: /// above" or "see the code below", since the location of the description may /// change in the future. You can use dartdoc [Linking] in the description, and /// __Markdown__ too. -/// +/// /// ```dart preamble /// class Foo extends StatelessWidget { /// const Foo({this.value = ''}); -/// -/// String value; -/// +/// +/// String value; +/// /// @override /// Widget build(BuildContext context) { /// return Text(value); @@ -28,7 +28,7 @@ syntax inside of the dartdoc comment for a Flutter class/variable/enum/etc.: /// short version of the snippet code sample. /// ```dart /// String myValue = 'Foo'; -/// +/// /// @override /// Widget build(BuildContext) { /// return const Foo(myValue); @@ -40,6 +40,18 @@ syntax inside of the dartdoc comment for a Flutter class/variable/enum/etc.: This will result in the template having the section that's inside "```dart" interpolated into the template's stateful widget's state object body. +For other sections of the template, the interpolation occurs by appending the string +that comes after `code-` into the code block. For example, the +[`stateful_widget`](stateful_widget.tmpl) template contains +`{{code-imports}}`. To interpolate code into `{{code-imports}}`, you would +have to do add the following: + +```dart +/// ```dart imports +/// import 'package:flutter/rendering.dart'; +/// ``` +``` + All code within a code block in a snippet needs to be able to be run through dartfmt without errors, so it needs to be valid code (This shouldn't be an additional burden, since all code will also be compiled to be sure it compiles).