logo Sandboxed

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

  • πŸ› οΈ Design. ⚑ Build. πŸ” Preview.
  • ✨ Speed up development. 🧼 Improve maintainability. πŸ“€ Share confidently.

⚠️ Disclaimer
This package is currently in an unstable state and may introduce breaking changes without notice.
It also includes extra dependencies that may make integration into real projects more difficult. These will be removed or streamlined in future releases to improve usability.


πŸš€ Features

  • πŸ“¦ Isolate widgets for independent development and testing
  • 🎨 Live preview with hot reload support
  • πŸ§ͺ Interactive params: bool, color, sliders, etc.
  • 🧩 Built-in addons: pan, theme, safe area, viewport, reload
  • 🏷️ Tags & searchable component catalog
  • πŸ”— Deep linking between stories and docs
  • πŸ“„ MDX docs with live stories (WIP)
  • 🧹 Linting for invalid/missing params (WIP)
  • πŸ“Έ Golden test integration (WIP)

πŸ“¦ Packages

πŸ“¦ Installation

  1. Add it in your pubspec.yaml:

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

    flutter pub get
    
  3. Write Meta and stories

  4. Run build_runner (required only when adding, renaming, removing Meta or Story):

    flutter pub run build_runner build
    

🧰 Usage

To create and preview a widget in sandboxed, define a Meta and one or more Story objects:

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

Then define stories with configurable 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 make your widget interactive in the UI.
Stories will be listed in the visual explorer and updated live via hot reload.

Warning

Important

Run flutter pub run build_runner build after adding, renaming, removing Meta or Story getters to update the component registry.

♻️ Hot reload friendly: All other changes (e.g. story content, styling, params) are picked up automatically with hot reload.

πŸ’‘ VS Code Snippets

You can add these snippets to your VS Code to speed up writing stories and meta definitions.

Expand

How to add:

  1. Open Command Palette β†’ Preferences: Configure User Snippets
  2. Create or open a global or workspace snippet file
  3. Paste the following:
{
  "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/                  # App for testing sandboxed components in isolation
β”œβ”€β”€ sandboxed_library/        # App for testing Sandboxed UI Kit

packages/
β”œβ”€β”€ sandboxed/                # Main UI and logic for the sandbox viewer
β”œβ”€β”€ sandboxed_core/           # Low-level primitives for stories, components, params
β”œβ”€β”€ sandboxed_generator/      # Code generation tools for component discovery
β”œβ”€β”€ sandboxed_ui_kit/         # UI kit used internally by sandboxed apps

example/
β”œβ”€β”€ material_book/            # Demo showcasing Material widgets
β”œβ”€β”€ monorepo/                 # Example of integrating Sandboxed into a monorepo

docs/                         # Developer documentation and guides
.vscode/                      # VSCode workspace configuration
melos.yaml                    # Melos workspace config for multi-package setup
pubspec.yaml                  # Root pubspec for tool-level dependencies

πŸ“… Roadmap

  • 🌐 URL state & session persistence (Done)
  • πŸ›  Generated docs from source/meta (Partial)
  • 🧠 Param mismatch detection + fixes
  • πŸ§ͺ Golden test runner (local & cloud)
  • 🧰 Extended param types (select, JSON, code)
  • πŸ›Ž Settings panel in UI
  • 🧭 Pre-filled search filters
  • 🧩 Lockable & toggleable addons
  • 🧠 VS Code preview plugin (Maybe)
  • ♻️ Reduce dependency footprint

πŸ§‘β€πŸ’» Contributing

Contributions are welcome!
Feel free to open issues, submit PRs, or suggest features.


πŸ“„ License

MIT License Β© 2025 Sandboxed, 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