├── .firebaserc ├── README.md ├── firebase.json └── public ├── images └── dash.png ├── meta.yaml ├── step_01 ├── instructions.md ├── snippet.dart └── solution.dart └── step_02 ├── instructions.md └── snippet.dart /.firebaserc: -------------------------------------------------------------------------------- 1 | { 2 | "projects": { 3 | "default": "" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DartPad Workshop Starter Pack 2 | A starter project for DartPad workshops. Follow the quickstart below to create 3 | your own step-by-step workshop, similar to these 4 | [workshops](https://github.com/flutter/codelabs/tree/master/dartpad_codelabs) 5 | maintained by the Flutter team: 6 | 7 | - [Getting Started with Slivers](https://dartpad.dev/workshops.html?webserver=https://dartpad-workshops-io2021.web.app/getting_started_with_slivers) 8 | - [Inherited Widget](https://dartpad.dev/workshops.html?webserver=https://dartpad-workshops-io2021.web.app/inherited_widget) 9 | - [Null Safety](https://dartpad.dev/workshops.html?webserver=https://dartpad-workshops-io2021.web.app/null_safety_workshop) 10 | 11 | For more information on authoring a DartPad workshop, see the [Workshop Authoring 12 | Guide](https://github.com/dart-lang/dart-pad/wiki/Workshop-Authoring-Guide) on 13 | the DartPad wiki. 14 | 15 | 16 | # Quickstart (Firebase Hosting) 17 | 18 | 1. Fork this repository 19 | 20 | 2. Install the [Firebase CLI](https://firebase.google.com/docs/cli) 21 | 22 | 3. Set the default project ID in `.firebaserc`: 23 | 24 | ``` 25 | { 26 | "projects": { 27 | "default": "" 28 | } 29 | } 30 | ``` 31 | 32 | 4. Edit the files in `public/` to create your own step-by-step workshop. The 33 | `meta.yaml` to configures the metadata such as the project type (Dart or 34 | Flutter), number of steps, and title. 35 | 36 | 4. Deploy to Firebase: 37 | 38 | ```bash 39 | firebase deploy 40 | ``` 41 | 42 | 5. Load in DartPad using the following URL, replacing `` 43 | with your project ID: 44 | 45 | ``` 46 | https://dartpad.dev/workshops.html?webserver=https://.web.app 47 | ``` 48 | -------------------------------------------------------------------------------- /firebase.json: -------------------------------------------------------------------------------- 1 | { 2 | "hosting": { 3 | "public": "public", 4 | "ignore": [ 5 | "firebase.json", 6 | "**/.*", 7 | "**/node_modules/**" 8 | ], 9 | "headers": [ 10 | { 11 | "source": "**", 12 | "headers": [ 13 | { 14 | "key": "Access-Control-Allow-Origin", 15 | "value": "https://dartpad.dev" 16 | } 17 | ] 18 | } 19 | ] 20 | } 21 | } -------------------------------------------------------------------------------- /public/images/dash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnpryan/dartpad_workshop_starter/1819417ddea75a115426ff44282c37c97829b777/public/images/dash.png -------------------------------------------------------------------------------- /public/meta.yaml: -------------------------------------------------------------------------------- 1 | name: Example workshop 2 | 3 | # Accepts 'flutter' or 'dart' 4 | type: flutter 5 | 6 | # Configuration for each step 7 | steps: 8 | - name: Step 1 9 | directory: step_01 10 | has_solution: true 11 | - name: Step 2 12 | directory: step_02 13 | has_solution: false 14 | -------------------------------------------------------------------------------- /public/step_01/instructions.md: -------------------------------------------------------------------------------- 1 | # Step 1 2 | 3 | 12 | 13 | Flutter Codelab 14 | 15 | ```dart 16 | // Put this code in the build() method 17 | children: [ 18 | // Use this code 19 | Text( 20 | 'You have pushed the button this many times:', 21 | ), 22 | Text( 23 | '$_counter', 24 | style: Theme.of(context).textTheme.headline4, 25 | ), 26 | ], 27 | ``` 28 | -------------------------------------------------------------------------------- /public/step_01/snippet.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | void main() => runApp(MyApp()); 4 | 5 | class MyApp extends StatelessWidget { 6 | @override 7 | Widget build(BuildContext context) { 8 | return MaterialApp( 9 | title: 'Flutter Demo', 10 | debugShowCheckedModeBanner: false, 11 | theme: ThemeData( 12 | primarySwatch: Colors.blue, 13 | ), 14 | home: MyHomePage(title: 'Flutter Demo Home Page'), 15 | ); 16 | } 17 | } 18 | 19 | class MyHomePage extends StatefulWidget { 20 | MyHomePage({Key? key, required this.title}) : super(key: key); 21 | 22 | final String title; 23 | 24 | @override 25 | _MyHomePageState createState() => _MyHomePageState(); 26 | } 27 | 28 | class _MyHomePageState extends State { 29 | int _counter = 0; 30 | 31 | void _incrementCounter() { 32 | setState(() { 33 | _counter++; 34 | }); 35 | } 36 | 37 | @override 38 | Widget build(BuildContext context) { 39 | return Scaffold( 40 | appBar: AppBar( 41 | title: Text(widget.title), 42 | ), 43 | body: Center( 44 | child: Column( 45 | mainAxisAlignment: MainAxisAlignment.center, 46 | children: [ 47 | // Add Code Here 48 | ], 49 | ), 50 | ), 51 | floatingActionButton: FloatingActionButton( 52 | onPressed: _incrementCounter, 53 | tooltip: 'Increment', 54 | child: Icon(Icons.add), 55 | ), 56 | ); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /public/step_01/solution.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | void main() => runApp(MyApp()); 4 | 5 | class MyApp extends StatelessWidget { 6 | @override 7 | Widget build(BuildContext context) { 8 | return MaterialApp( 9 | title: 'Flutter Demo', 10 | debugShowCheckedModeBanner: false, 11 | theme: ThemeData( 12 | primarySwatch: Colors.blue, 13 | ), 14 | home: MyHomePage(title: 'Flutter Demo Home Page'), 15 | ); 16 | } 17 | } 18 | 19 | class MyHomePage extends StatefulWidget { 20 | MyHomePage({Key? key, required this.title}) : super(key: key); 21 | 22 | final String title; 23 | 24 | @override 25 | _MyHomePageState createState() => _MyHomePageState(); 26 | } 27 | 28 | class _MyHomePageState extends State { 29 | int _counter = 0; 30 | 31 | void _incrementCounter() { 32 | setState(() { 33 | _counter++; 34 | }); 35 | } 36 | 37 | @override 38 | Widget build(BuildContext context) { 39 | return Scaffold( 40 | appBar: AppBar( 41 | title: Text(widget.title), 42 | ), 43 | body: Center( 44 | child: Column( 45 | mainAxisAlignment: MainAxisAlignment.center, 46 | children: [ 47 | Text( 48 | 'You have pushed the button this many times:', 49 | ), 50 | Text( 51 | '$_counter', 52 | style: Theme.of(context).textTheme.headline4, 53 | ), 54 | ], 55 | ), 56 | ), 57 | floatingActionButton: FloatingActionButton( 58 | onPressed: _incrementCounter, 59 | tooltip: 'Increment', 60 | child: Icon(Icons.add), 61 | ), 62 | ); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /public/step_02/instructions.md: -------------------------------------------------------------------------------- 1 | # Step 3 2 | 3 | Here's how to use NetworkImage to display an image. 4 | -------------------------------------------------------------------------------- /public/step_02/snippet.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | const hostingUrl = 'https://dartpad-workshops-io2021.web.app'; 4 | 5 | void main() => runApp(MyApp()); 6 | 7 | class MyApp extends StatelessWidget { 8 | @override 9 | Widget build(BuildContext context) { 10 | var title = 'Web Images'; 11 | 12 | return MaterialApp( 13 | title: title, 14 | home: Scaffold( 15 | appBar: AppBar( 16 | title: Text(title), 17 | ), 18 | body: Image.network('$hostingUrl/example_flutter/images/dash.png'), 19 | ), 20 | ); 21 | } 22 | } 23 | --------------------------------------------------------------------------------