logo Sandboxed

pub package pub points likes

Sandboxed is a Flutter tool for developing, testing, and previewing UI components in isolation.


Features

  • Isolated widget development and testing
  • Live preview with hot reload
  • Configurable interactive parameters (boolean, color, string, etc.)
  • Built-in addons: pan, theme, safe area, viewport, reload
  • Tagging and searchable component catalog
  • Deep linking between stories and documentation
  • MDX documentation with embedded stories (WIP)
  • Param validation and linting (WIP)
  • Golden test integration (WIP)

Packages


Installation

  1. Add to pubspec.yaml:

    dependencies:
      sandboxed_core:
      sandboxed:
    
    dev_dependencies:
      sandboxed_generator:
    
  2. Fetch dependencies:

    flutter pub get
    
  3. Write Meta and Story definitions

  4. Run code generation:

    flutter pub run build_runner build
    

Usage

Define a component and its metadata:

Meta get meta => Meta<SandboxButton>(
  name: 'Button',
  module: 'Features / Core',
  component: SandboxButton,
  decorators: [
    Decorator((context, story) => Padding(
      padding: const EdgeInsets.all(16),
      child: story,
    )),
  ],
);

Add stories with interactive parameters:

Story get $Green => Story(
  name: 'Green',
  builder: (context, params) {
    return SandboxButton(
      onPressed: () {},
      title: params.string('title').required("Lorem"),
      color: params.color('color').required(Colors.green),
      size: params.single('size', SandboxButtonSize.values)
                .required(SandboxButtonSize.small),
    );
  },
);

Use params.boolean, params.color, params.string, params.single, or params.multi to configure interactivity.

Warning

Run flutter pub run build_runner build after adding, renaming, or removing Meta or Story definitions.

Other changes are applied automatically via hot reload.


VS Code Snippets

To streamline writing stories, add the following to your VS Code user snippets.

Show snippet setup

How to add:

  1. Open Command Palette → Preferences: Configure User Snippets
  2. Create or open a global or workspace snippet file
  3. Paste:
{
  "Meta + Story": {
    "prefix": "metastory",
    "description": "Creates a new Sandboxed Story with default Meta",
    "body": [
      "import 'package:flutter/widgets.dart';",
      "import 'package:sandboxed_core/sandboxed_core.dart';",
      "",
      "Meta get meta => Meta<${1:Widget}>();",
      "",
      "Story get $${2:Default} => Story($0);"
    ]
  },
  "Story": {
    "prefix": "story",
    "description": "Creates a new Sandboxed Story",
    "body": [
      "Story get $${2:Default} => Story($0);"
    ]
  },
  "Story Config": {
    "prefix": "storyconfig",
    "description": "Creates a global story config",
    "body": [
      "import 'package:sandboxed_core/sandboxed_core.dart';",
      "",
      "Config get config => Config(",
      "  module: '',",
      ");"
    ]
  }
}

Project Structure

apps/
├── sandbox/                  # Testing app for sandboxed stories
├── sandboxed_library/        # Viewer for UI Kit components

packages/
├── sandboxed/                # Main viewer implementation
├── sandboxed_core/           # Core abstractions
├── sandboxed_generator/      # Code generation
├── sandboxed_ui_kit/         # UI library for viewer interface

example/
├── material_book/            # Sample stories for Material components
├── monorepo/                 # Monorepo integration example

docs/                         # Documentation and guides
.vscode/                      # VS Code workspace settings
melos.yaml                    # Melos workspace config
pubspec.yaml                  # Root dependencies

Roadmap

  • Session persistence and URL state (done)
  • Source-based doc generation (partial)
  • Param validation and mismatch detection
  • Golden test support (local/cloud)
  • Advanced param types (select, JSON, code)
  • Customizable settings panel
  • Search filtering
  • Lockable addons
  • VS Code integration (research)
  • Reduced dependency footprint (research)

Contributing

Contributions are welcome. Please open an issue or submit a pull request to get involved.


License

MIT License © 2025 Sandboxed Developed by Vadim Melnikov

Libraries

addons/addon
addons/alignment/alignment_addon
addons/alignment/alignment_picker
addons/app/app_addon
addons/decorator/decorator_addon
addons/interactive_viewer/interactive_viewer_addon
addons/keyboard/keyboard_addon
addons/mixins/decorator_addon
addons/mixins/editor_addon
addons/mixins/param_builder_addon
addons/param_builders/base_param_builders/color_param_builder
addons/param_builders/base_param_builders/core/boolean_param_builder
addons/param_builders/base_param_builders/core/chips_param_builder
addons/param_builders/base_param_builders/core/integer_param_builder
addons/param_builders/base_param_builders/core/number_param_builder
addons/param_builders/base_param_builders/core/string_param_builder
addons/param_builders/base_param_builders/flutter/alignment_param_builder
addons/param_builders/base_param_builders/flutter/edge_insets_param_builder
addons/param_builders/base_param_builders/flutter/text_style_param_builder
addons/param_builders/base_param_builders_addon
addons/reload/reload_addon
addons/safe_area/safe_area_addon
addons/split_themes/split_themes_addon
addons/tags/tags_renderer_addon
addons/theme/theme_addon
addons/typed_addons/flag_addon
addons/viewport/viewport_addon
feature_flags
inspector/addons_inspector
inspector/component_inspector
inspector/params_editor
layout/sandboxed_viewport
layout/story_viewport
model/tag_filter_state
observers/delegate_route_observer
pages/document/document_page
pages/index_page
pages/nothing/nothing_page
pages/story/story_page
params/default_serializers
params/param_builder
params/param_serializer
params/params_notifier
provider/addons
provider/brand_color
provider/component_tree
provider/params
provider/persistence
provider/selected
provider/tags
provider/theme_mode
provider/title
router
router.gr
sandboxed
theme
toolbar/toolbar
toolbar/toolbar_addon_mixin
toolbar/toolbar_button
toolbar/toolbar_overlay_button
tree/component_tree
tree/component_tree_node
tree/component_tree_parser
tree/component_tree_x
tree_next/element_tree
utility/map_difference
Copied from @devfelipereis/map_diff
widgets/component_documentation
widgets/element_name
widgets/gap
widgets/revive
widgets/sandboxed_drawer
widgets/sandboxed_sidebar
widgets/sb_bottom_app_bar
widgets/sb_notification_listener
widgets/sb_share_button