# What are Stories?

A Story is a specific state or variant of a design component _(or a Flutter widget)_. It is a way to showcase a component in different scenarios.

## Stories for Components

Your design system will usually have multiple components, and each component will have multiple stories. For example, a button component might have stories for different states like `Primary`, `Secondary`, `Disabled` etc.

```dart title="components/lib/button.dart"
import 'package:flutter/material.dart';

enum ButtonState {
  primary,
  secondary,
  disabled,
}

class Button extends StatelessWidget {
  final String text;
  final ButtonState state;

  const Button({
    super.key,
    required this.text,
    required this.state,
  });

  @override
  Widget build(BuildContext context) {
    // Implementation of the button based on state
  }
}
```

```dart title="widgetbook/lib/button.stories.dart"
import 'package:flutter/material.dart';
import 'package:components/button.dart';

part 'button.stories.g.dart';

const meta = Meta(Button.new);

final $Primary = _Story(
  args: _Args(
    text: StringArg('Primary'),
    state: EnumArg<ButtonState>(ButtonState.primary, values: ButtonState.values),
  ),
);

final $Secondary = _Story(
  args: _Args(
    text: StringArg('Secondary'),
    state: EnumArg<ButtonState>(ButtonState.secondary, values: ButtonState.values),
  ),
);

final $Disabled = _Story(
  args: _Args(
    text: StringArg('Disabled'),
    state: EnumArg<ButtonState>(ButtonState.disabled, values: ButtonState.values),
  ),
);
```

## Stories for Screens

A screen is a composition of multiple components but as you move up the component hierarchy toward the screen level, you deal with more complexity. That's why it is **recommended** to catalog your screens in Widgetbook to be able to test them in isolation.

There are two common patterns for building screens:

1. **Pure Screens**: Screens that are fully presentational and don't depend on external data or services. You can create a story for them like any other component.
2. **Contained Screens**: Screens that depend on external data or services. Check out our [mocking guide](/stories/mocking) to know how to handle such screens.

## Builder vs Setup

Every story has two hooks that control how the widget is created and wrapped:

| Hook | Signature | Purpose |
| --- | --- | --- |
| `builder` | `TWidget Function(BuildContext, TArgs)` | Creates the widget from args. Must return the exact widget type. |
| `setup` | `Widget Function(BuildContext, Widget, TArgs)` | Wraps the built widget. Can return any `Widget`. |

`builder` is called first to construct the widget, then `setup` receives that widget and wraps it.
When using `Meta`, a default `builder` is generated automatically. `setup` defaults to passing the widget through.

### When to use `setup`

Use `setup` whenever your story needs a parent widget injected above it in the widget tree. This is common when your widget depends on something provided by an ancestor, e.g. a `ProviderScope` for Riverpod, a `BlocProvider` for Bloc, a custom `Theme`, or a mocked router.

```dart title="widgetbook/lib/user_tile.stories.dart"
final $Default = _Story(
  setup: (context, child, args) => ProviderScope(
    overrides: [userProvider.overrideWith((ref) => fakeUser)],
    child: child,
  ),
);
```

You cannot do this in `builder` because it must return the exact widget type (`TWidget`), so wrapping it in another widget would cause a type error.

This is especially useful when cataloging [screens](/stories/overview#stories-for-screens) that depend on external services. See the [Mocking guide](/stories/mocking) for more examples of using `setup` with mocked dependencies.

## Story Order

Stories are displayed in the navigation panel in the order they are defined in the `.stories.dart` file. For example, the stories below will appear as `Primary`, `Secondary`, `Disabled` in the sidebar and are not alphabetically sorted.

```dart title="widgetbook/lib/button.stories.dart"
final $Primary = _Story(...);
final $Secondary = _Story(...);
final $Disabled = _Story(...);
```

## Component Path

You can change the navigation path of your stories by using the `path` parameter in `ComponentMeta` as follows:

<Info>
  If you wrap a folder name in **square brackets**, it will be treated as a
  **category** in the navigation path.
</Info>

```dart title="widgetbook/lib/button.stories.dart"
const component = ComponentMeta(
  path: 'components/button',
);

const meta = Meta(Button.new);
```
