Git Product home page Git Product logo

widgetbook's Introduction

Discord style: very good analysis GitHub Workflow Status

Open Source Package & Widgetbook Cloud

Widgetbook is the custom widget library specifically created for Flutter applications. Developers can manage all of their widgets in one place and see how they will appear on different devices as well as in different languages and themes.

Widgetbook Cloud is the collaboration platform for Flutter frontend teams. Developers can easily share their Widgetbook with designers, project managers, clients, and more to simplify review processes.

Get access to Widgetbook Cloud!

Packages

The widgetbook repository contains of the Widgetbook packages which are located at /widgetbook/packages/.

The following packages exist:

Package Pub
widgetbook Pub Version
widgetbook_annotation Pub Version
widgetbook_generator Pub Version

Examples

All example apps are located at /widgetbook/examples/.

Running the examples in VS Code

You can run the example apps in VS Code by using the predefined launch configurations. The following configurations exist:

Configuration Description
Debug widgetbook_generator Launches the generated code from package:widgetbook_generator. Run flutter pub run build_runner build before! This is great to develop package:widgetbook_generator.

Contributions

We love the open source flutter community!💙 If you'd like to contribute to one or all Widgetbook packages, feel free to open a pull-request at any time. To give new contributors exciting first challenges, we're labelling some easy-to-fix issues "good first issue".

Questions or Issues?

If something does not feel right or if you have questions, feel free to contact us. You can do so by creating an issue or contacting us on discord.

widgetbook's People

Contributors

boredcity avatar castrors avatar dependabot[bot] avatar dominic-cot avatar geisterfurz007 avatar ggirotto avatar gowl avatar heavybeard avatar hiroya-w avatar jamesgorman2 avatar jenshor avatar joshpetit avatar khurramrizvi avatar logickoder avatar lucasjosefiak avatar martnst avatar mastersam07 avatar maudfrz avatar mhadaily avatar mulieriq avatar mvolpato avatar nuesslerm avatar outring avatar roaa94 avatar scotts2017 avatar smartmind12 avatar takassh avatar westito avatar youssefhegab14 avatar youssefraafatnasry avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

widgetbook's Issues

Widgets Inspector

A user wished for an inspector to get information about a widget. For instance, to check for margins. This feature could be similar to the flutter inspector.

Navigation tree state resets on hot reload

How to reproduce

  1. Create a Folder with a WidgetElement
  2. Start the Widgetbook
  3. Open the Folder so its expanded
  4. Hot reload the app
  5. Observe that the Folder is collapsed after hot reload completed.

Knobs to interact with stories

have just come across this project and was wondering if you plan on adding any interactive "story" functionality ?

e.g change widget inputs within the widgetbook interface on the fly

Download request fails (widgetbook.io)

I just want to inform you it's not possible to request a download from the following homepage: https://widgetbook.io.

The following error occurred after press on Get Access:
Oops! Something went wrong while submitting the form.

The following error is visible in the console:

GET https://firecrown.us1.list-manage.com/subscribe/post-json?u=34ac9ff90651cadf6f31835ab&id=363df7e9b9&c=jQuery351047704463576119527_1634213232985&FNAME=Markus&SNAME=Krebs&EMAIL=markuskrebs93%40gmail.com&b_34ac9ff90651cadf6f31835ab_363df7e9b9=&_=1634213232986 net::ERR_ABORTED 503

Grid Addon

A user wished for a pixel grid to be able to approximate distances easier. An option to customise the distance between each grid line is required.

builder of the active story is invoked with old state

How to reproduce

  1. create a story with a builder that prints, e.g. a number (1)
  2. select the story (on selection the number is printed)
  3. change the print of the story to another number (2)
  4. hot reload the Widgetbook
  5. observe that the old number (1) is printed instead of (2)

Workaround

To render the hot reloaded story, deselect the story (e.g., by selecting another story) and select the hot reloaded story again.

Problem

The CanvasCubit which provides the currently selected story does not get updated when the currently selected story is changed (and then hot reloaded). Therefore, a render (and a print) with an the old builder function is invoked.

Test coverage is too low

Currently a bunch of scenarios are not tested. Tests need to be meaningful and cover at least 95% of the code. Currently the coverage for codecov is set to 55% so the test action will pass.

This issue is primarily a reminder that the coverage for codecov is set to 55% and must be increased once additional tests are added.

Current test coverage: codecov

Theme properties need to be required or have defaults

When theme properties are set, I just see a "No theme defined" in the main preview window, yet the lightTheme and darkTheme properties on Widgetbook are not marked as required.
I worked around this by setting:

lightTheme: ThemeData.light(),
darkTheme: ThemeData.dark(),

But really I think they should either be set to required in the constructor or otherwise sensible default like the above should be used.

Missing Showcase

I think you miss a showcase in your docs.
After 15 minutes reading and digging into the example I still couldn't figure out how the library is working.
You should have a video or GIFs or something to show what the actual goal is (or what the "output" of the example in your repo looks like).

Some mobile and desktop apple devices are missing

Mobile

The Device class misses a bunch of mobile apple devices. The proposed mobile devices are defined here: Device Screen Sizes and Orientations.

Desktop

In addition, the following desktop devices need to be added

  • MacBooks
    • 13.3"
    • 14"
    • 15"
    • 16"
  • iMac
    • Slim Unibody iMac (2012, 2013)
      • 21.5"
      • 27"
    • Retina iMac (2014, 2015)
      • 21.5"
      • 27"
    • Apple M1 (2021)
      • 24"
  • Pro Display XDR

For now it's unclear how the different scaling factors of Desktop devices should be implemented.

Search bar

An user wished for a search bar to be able to quickly find the desired widget in their long list of widgets.

No warning is displayed when two Organizer have the same path

The path of an Organizer should be unique. Otherwise elements with a duplicate name are hidden. This might cause problems when hot reloading stories.

For instance, it might happen that a developer copies one or multiple Storys, but forgets to change the name. Therefore, one folder has multiple Storys with the same name. Therefore, multiple Organizers with the same path exist. This can cause the preview to show a different Widget on hot reloading since CanvasCubit might match a Story with the same path but different rendering.

Suggestion

If multiple Storys exist, a warning should be displayed. This warning should state that one or multiple elements in the navigation tree result in the same path and are therefore hidden.

Widgetbook app does not set brightness correctly for rendered widgets

Some widgets might depend on Theme.of(context).brightness. Unfortunately, the widgetbook package does not set the brightness correctly.

Suggested solution

inherit the brightness of the rendered app from the brightness of widgetbook:

injectedTheme.copyWith(brightness: Theme.of(context).brightness, ... )

name resolve fails when multiple annotated Stories have the same name

Since the functions annotated with @WidgetbookStory are just imported in the final .widgetbook.dart file a naming conflict occurs iff multiple methods annoted with @WidgetbookStory and having the method name are defined.

The error thrown looks like this:

lib/app.widgetbook.dart:49:45: Error: 'mealDetailShort' is imported from both 'package:meal_app/widgets/test_file.dart' and 'package:meal_app/widgets/meal_detail.dart'.
builder: (context) => mealDetailShort(context),
^^^^^^^^^^^^^^^
lib/app.widgetbook.dart:53:45: Error: 'mealDetailShort' is imported from both 'package:meal_app/widgets/test_file.dart' and 'package:meal_app/widgets/meal_detail.dart'.
builder: (context) => mealDetailShort(context),

Workaround

  • Rename the Story-defining methods so each method name imported into .widgetbook.dart is unique.

Proposed changes

  • Use named imports instead of plain imports
    • this allows the developer to reuse the names of the Story-defining methods since they can be differentiated by their namespaces

How to use within a package or plugin?

Please document how to use widgetbook with a Flutter package or plugin; or document that this is not possible.

Use case: I am developing and maintaining a public package which would benefit from having an accompanying widgetbook.

Current problem:

flutter create --platforms=windows .
The "--platforms" argument is not supported in package template.

hot reload doesn't work

On Linux desktop, using current beta channel (2.7.0-3.1.pre) I have:

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

void main() {
  runApp(const HotReload());
}

class HotReload extends StatelessWidget {
  const HotReload({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Widgetbook(
      appInfo: AppInfo(
        name: 'My Widgetboard',
      ),
      lightTheme: ThemeData.light(),
      darkTheme: ThemeData.dark(),
      categories: [
        Category(
          name: 'Onboarding',
          widgets: [
            WidgetElement(
              name: 'Test 1',
              stories: [
                Story(
                  name: 'Default',
                  builder: (context) => const Center(
                    child: Text('Hello'),
                  ),
                ),
              ],
            ),
          ],
        ),
      ],
    );
  }
}

Changing the text from 'Hello' to 'World' and then doing a hot-reload doesn't actually update the preview in the Widgetbook window.

MediaQuery data not specified for device.

Widgets that depend on MediaQuery data such as MediaQuery.of(context).size will receive data from the Widgetbook window size instead of the device size as shown bellow.

Screen.Recording.2021-11-23.at.19.25.56.mov

analysis_options excludes important rules

Currently the following rules are ignored:

  • public_member_api_docs
  • avoid_equals_and_hash_code_on_mutable_classes
  • avoid_dynamic_calls
  • lines_longer_than_80_chars

Since these are important rules, this will be addressed in the future.

Incompatible with widgetbook - can't add to a project

I tried to add to test widgetbook with my last project and run into issue with adding dependency.

error:


Running "flutter pub get" in magillus_com...                    
Because every version of flutter_test from sdk depends on meta 1.3.0 and widgetbook >=0.0.10 depends on meta ^1.7.0, flutter_test from sdk is incompatible with widgetbook >=0.0.10.

So, because magillus_com depends on both widgetbook ^0.0.16 and flutter_test any from sdk, version solving failed.
pub get failed (1; So, because magillus_com depends on both widgetbook ^0.0.16 and flutter_test any from sdk, version solving failed.)

pubspec.yaml:

name: magillus_com
description: A website

publish_to: 'none' # Remove this line if you wish to publish to pub.dev

version: 1.0.0+1

environment:
  sdk: ">=2.12.0 <3.0.0"

dependencies:
  widgetbook: ^0.0.16
  flutter_fimber: "^0.6.1"
  flutter:
    sdk: flutter

  cupertino_icons: ^1.0.1

dev_dependencies:
  flutter_test:
    sdk: flutter
...

**flutter doctor **:

Running flutter doctor...
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 2.5.3, on Ubuntu 20.04.3 LTS 5.11.0-38-generic, locale en_US.UTF-8)
[✓] Android toolchain - develop for Android devices (Android SDK version 31.0.0-rc5)
[✓] Chrome - develop for the web
[✓] Linux toolchain - develop for Linux desktop
[✓] Android Studio (version 2020.3)
[✓] IntelliJ IDEA Ultimate Edition (version 2021.2)
[✓] VS Code (version 1.61.2)
[✓] Connected device (2 available)

• No issues found!

Same issue on all channels of Flutter.

bloc dependencies restrict package usage

If a project uses a different version than widgetbook, the user will get a dependency missmatch. This will make using the package difficult since the team using widgetbook is forced to update to the version used by the package.

Proposed solution:

Removal of flutter_bloc and bloc as a dependency by replacing the state management solution by e.g. InheritedWidget. InheritedWidget does not required additional dependencies.

Widgetbook app throws exception when theme is toggled

If only one theme is defined, the Widgetbook app throws flutter exceptions when toggling the theme. The app continues running, but the exceptions are distracting - especially if you have debugging of packages enabled.

Packages

  • widgetbook

the error occurred in combination with widgetbook_generator but there is no reason to believe this is actually caused by the widgetbook_generator package.

Suggested solution

  • Disable the toggle Theme button if only one theme is defined
    It doesnt really make sense to default to the default theme of widgetbook.
  • Add a tooltip explaining why the button is enabled
  • Start the Widgetbook app in the theme that was defined (currently always defaults to dark theme)

Device can be moved out of sight

Device can be moved out of sight. Expected behaviour is that the device is always visible. It can happen that the device move out of sight without being easily recoverable.

How to

  1. Activate a Story
  2. Move the Device around so its no longer visible

Workaround

  • Move the Device back into sight or
  • Deselect the active story and reselect it. This (currently) resets the viewport and brings the Device back into sight. See #6

Golden Tests

Some users wished to create their Golden Tests with Widgetbook.

Story names do not update on web

How to reproduce

  1. Create a Story with a name (e.g. 'Test')
  2. Start the Widgetbook
  3. Observe that the Story is shown as 'Test'
  4. Change the name (e.g. to 'Test2')
  5. Hot reload the Widgetbook
  6. Observe that the Story is shown as 'Test'. Expected: 'Test2'

This problem only occurs on web. E.g. on the Chrome browser.

Show multiple devices simultaneously

Some users wished to preview their widgets on multiple devices simultaneously. This could be achieved by showing multiple devices beside each other.

Code Preview

Some users wished to preview the code of the widgets in the UI of Widgetbook.

fix: cannot set URL strategy more than once

Hi.

I'm trying to create a simple example with widgetbook (version 1.0.1) package, but it's impossible.

When I try to launch the app to chrome, throw this error:

EXCEPTION CAUGHT BY WIDGETS LIBRARY
The following assertion was thrown building HotReload:
Assertion failed: org-dartlang-sdk:///flutter_web_sdk/lib/_engine/engine/window.dart:25:10
!_isUrlStrategySet
"Cannot set URL strategy more than once."

The relevant error-causing widget was:
HotReload
HotReload:file:///Users/sissa/StudioProjects/flutter/infinite_hub/lib/stories/main.dart:16:19

I launch the app with flutter run -t lib/stories/main.dart -d chrome

My lib/stories/main.dart file:

void main() {
  runApp(HotReloadClass());
}

class HotReloadClass extends StatelessWidget {
  HotReloadClass({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: getAppTheme(),
      home: const HotReload(),
    );
  }
}

The widgetBook file:

import 'package:flutter/material.dart';
import 'package:infinite_hub/customviews/empty_result_widget.dart';
import 'package:widgetbook/widgetbook.dart';

class HotReload extends StatelessWidget {
  const HotReload({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Widgetbook(
      appInfo: AppInfo(name: 'Infinite HUB Widgets'),
      lightTheme: ThemeData.light(),
      darkTheme: ThemeData.dark(),
      categories: [
        WidgetbookCategory(name: 'widgets', widgets: [
          WidgetbookWidget(
            name: 'EmptyResultWidget',
            useCases: [
              WidgetbookUseCase(
                  name: 'Empty result',
                  builder: (context) => EmptyResultWidget(
                        title: 'Test widget book',
                        icon: Icons.clear,
                        baseColor: Colors.blueGrey,
                        onRefresh: () {},
                      ))
            ],
          )
        ]),
      ],
    );
  }
}

The custom widget:

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

class EmptyResultWidget extends StatelessWidget {
  final IconData icon;
  final String title;
  final Color baseColor;
  final Function onRefresh;

  EmptyResultWidget({this.title, this.icon, this.baseColor, this.onRefresh});

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.center,
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Icon(
            icon,
            color: baseColor,
            size: 100,
          ),
          SizedBox(
            height: 12.0,
          ),
          Text(
            title,
            style: TextStyle(
              fontWeight: FontWeight.bold,
              fontSize: 24.0,
              color: baseColor,
            ),
            textAlign: TextAlign.center,
          ),
          SizedBox(height: 20.0),
          null != onRefresh
              ? IconButton(
                  onPressed: onRefresh,
                  icon: Icon(
                    Icons.add,
                    color: Colors.blueGrey,
                  ),
                  iconSize: 30,
                )
              : SizedBox()
        ],
      ),
    );
  }
}

My Futter doctor report:

[✓] Flutter (Channel stable, 2.5.2, on macOS 11.5.2 20G95 darwin-x64, locale en-GB)
    • Flutter version 2.5.2 at /Users/sissa/fvm/versions/2.5.2
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 3595343e20 (6 weeks ago), 2021-09-30 12:58:18 -0700
    • Engine revision 6ac856380f
    • Dart version 2.14.3

[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.2)
    • Android SDK at /Users/sissa/Library/Android/sdk
    • Platform android-31, build-tools 30.0.2
    • ANDROID_HOME = /Users/sissa/Library/Android/sdk
    • Java binary at: /Applications/Android Studio 2.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 11.0.8+10-b944.6916264)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 13.0, Build version 13A233
    • CocoaPods version 1.10.1

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 3.5)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b49-5587405)

[✓] Android Studio (version 4.2)
    • Android Studio at /Applications/Android Studio 2.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 11.0.8+10-b944.6916264)

[✓] VS Code (version 1.40.0)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension can be installed from:
      🔨 https://marketplace.visualstudio.com/items?itemName=Dart-Code.flutter

[✓] Connected device (2 available)
    • macOS (desktop) • macos  • darwin-x64     • macOS 11.5.2 20G95 darwin-x64
    • Chrome (web)    • chrome • web-javascript • Google Chrome 95.0.4638.69

• No issues found!

Thanks in advance.

ControlBar overflows when app is starting

When the app is starting the ControlBar is too large and widget elements are overflowing.

How to reproduce

Start the app. Do not change window size.

Problem

The ControlBar should be swrapped in a single child scroll view (excluding the button for discord).

Widgetbook ships with example app

Widgetbook currently ships with the meal_app example app. To reduce package size the example app should be either moved to another GitHub repo or should be moved out of the package's folder.

Preview on Landscape Mode

Some users wished to preview their widgets not only on devices with portrait mode but also on landscape mode.

no way to use widgets that require localization

I have widgets that make use of Flutters standard localisation mechanism and so require having localizationsDelegates and supportedLocales set on their containing MaterialApp but there is currently no way to do so for the MaterialApp widget that widgetbook uses internally.

BuildContext related Themes cannot be set or annotated

Some themes depend on BuildContext. The current properties require a ThemeData object but for Themes depending on BuildContext it would be beneficial if lightTheme and darkTheme properties would require a ThemeData Function(BuildContext context) type to build the theme.

Related packages:

  • widgetbook
  • widgetbook_generator

Component Documentation

One team wished to add detailed documentation to their widgets. They want to explain how the specific widgets are intended to be used.

Dynamically resize devices

One user wished for an option to resize the devices dynamically. The user wished for an option to not add different devices to preview the widgets on multiple screen sizes but to resize one device dynamically.

Wrapping all use cases in other widgets

Feedback of one user: "My early feedback is to add some means of wrapping all use cases in other widgets. I have a kind of my own Theme, I'm not using the Material one, and right now I have to wrap every widget inside the usecase with that. Something like a Widget builder (Widget usecase) for a Widgetbook (or maybe even the categories/folders for scoping) would be really handy"

Font size accessibility

User wished for being able to change the font size according to the operating system's accessibility setting.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.