Sandboxed
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
sandboxed
— Main viewer and runtimesandboxed_core
— Story primitives and paramssandboxed_generator
— Code generation toolssandboxed_ui_kit
— Internal UI components
Installation
-
Add to
pubspec.yaml
:dependencies: sandboxed_core: sandboxed: dev_dependencies: sandboxed_generator:
-
Fetch dependencies:
flutter pub get
-
Write
Meta
andStory
definitions -
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:
- Open Command Palette →
Preferences: Configure User Snippets
- Create or open a global or workspace snippet file
- 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/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/theme_mode
- provider/title
- router
- router.gr
- sandboxed
- theme
- toolbar/toolbar
- toolbar/toolbar_addon_mixin
- 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/sb_bottom_app_bar
- widgets/sb_notification_listener
- widgets/search_bar