Spectre JSON - JSON Editor for Flutter

A beautiful and feature-rich JSON editor widget for Flutter with syntax highlighting, tree view navigation, real-time validation, and customizable themes.

pub package License: MIT Flutter

โœจ Features

  • ๐Ÿ“ Flexible View Modes: Choose between dual view (tabs), tree-only, or raw-only modes
  • ๐ŸŽจ Syntax Highlighting: Beautiful JSON syntax highlighting with customizable themes
  • ๐ŸŒณ Interactive Tree View: Navigate and edit JSON with an intuitive tree interface
  • ๐ŸŽฏ Real-time Validation: Live JSON validation with error highlighting
  • ๐Ÿ“‹ Copy & Paste: Built-in clipboard functionality
  • ๐ŸŽจ Customizable Themes: Multiple built-in themes and custom theme support
  • ๐Ÿ“ฑ Responsive Design: Works seamlessly across different screen sizes
  • โšก Performance Optimized: Efficient rendering and memory management
  • ๐Ÿ”ง Smart Indentation: Context-aware indentation and auto-closing
  • ๐ŸŽ›๏ธ Advanced Controls: Format, clear, and validate JSON with action buttons
  • ๐Ÿ’พ Smart Auto-Save: User changes are automatically saved when JSON is valid, without overwriting work-in-progress

๐Ÿš€ Installation

Add spectre_json to your pubspec.yaml:

dependencies:
  spectre_json: ^1.1.7

Then run:

flutter pub get

๐Ÿ“– Quick Start

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

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  Map<String, dynamic> jsonData = {
    'name': 'John Doe',
    'age': 30,
    'isActive': true,
    'address': {
      'street': '123 Main St',
      'city': 'Anytown',
      'zipCode': '12345'
    },
    'hobbies': ['reading', 'coding', 'gaming'],
  };

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('JSON Editor Example')),
      body: Padding(
        padding: EdgeInsets.all(16.0),
        child: JsonEditor(
          initialData: jsonData,
          onDataChanged: (newData) {
            setState(() {
              jsonData = newData;
            });
          },
          title: 'My JSON Data',
          allowCopy: true,
          theme: RedPandaTheme(),
        ),
      ),
    );
  }
}

๐ŸŽฏ Usage

Basic Usage

JsonEditor(
  initialData: yourJsonData,
  onDataChanged: (newData) {
    // Handle data changes
    print('JSON updated: $newData');
  },
)

Advanced Usage

JsonEditor(
  initialData: jsonData,
  onDataChanged: (newData) {
    setState(() {
      jsonData = newData;
    });
  },
  title: 'Configuration Editor',
  readOnly: false,
  allowCopy: true,
  theme: JsonEditorTheme.light(primaryColor: Colors.blue),
  isExpanded: true,
  onExpansionChanged: (expanded) {
    print('Editor ${expanded ? 'expanded' : 'collapsed'}');
  },
  onCollapse: () {
    print('Editor collapsed');
  },
)

Custom Theme

// Using the factory constructor (recommended)
JsonEditor(
  initialData: data,
  onDataChanged: (newData) {},
  theme: JsonEditorTheme.fromColors(
    editorBackground: Colors.grey[900]!,
    foreground: Colors.white,
    primaryColor: Colors.blue,
    stringColor: Colors.green,
    numberColor: Colors.orange,
  ),
)

// Or extend the base class
class MyCustomTheme extends JsonEditorTheme {
  @override
  Color get editorBackground => Colors.grey[900]!;
  
  @override
  Color get foreground => Colors.white;
  
  @override
  Color get primaryColor => Colors.blue;
  
  // ... implement all other color getters
}

View Types

Choose how the JSON editor is displayed:

// Dual view (default) - shows both tree and raw editor with tabs
JsonEditor(
  initialData: data,
  onDataChanged: (newData) {},
  viewType: ViewType.dual,
)

// Tree view only - shows only the interactive tree interface
JsonEditor(
  initialData: data,
  onDataChanged: (newData) {},
  viewType: ViewType.treeOnly,
)

// Raw editor only - shows only the text editor
JsonEditor(
  initialData: data,
  onDataChanged: (newData) {},
  viewType: ViewType.rawOnly,
)

Expansion Modes

Control how tree view nodes are expanded by default:

// No expansion (default) - only root node is expanded
JsonEditor(
  initialData: data,
  onDataChanged: (newData) {},
  expansionMode: ExpansionMode.none,
)

// Expand all object nodes (including nested objects)
JsonEditor(
  initialData: data,
  onDataChanged: (newData) {},
  expansionMode: ExpansionMode.objects,
)

// Expand all array nodes (including nested arrays)
JsonEditor(
  initialData: data,
  onDataChanged: (newData) {},
  expansionMode: ExpansionMode.arrays,
)

// Expand both objects and arrays
JsonEditor(
  initialData: data,
  onDataChanged: (newData) {},
  expansionMode: ExpansionMode.objectsAndArrays,
)

// Expand everything
JsonEditor(
  initialData: data,
  onDataChanged: (newData) {},
  expansionMode: ExpansionMode.all,
)

// Expand only the top 3 levels
JsonEditor(
  initialData: data,
  onDataChanged: (newData) {},
  expansionMode: ExpansionMode.levels,
  maxExpansionLevel: 3,
)

Delete Confirmation

The JSON editor includes a delete confirmation dialog to prevent accidental deletions. Users can choose to skip future confirmations:

// Skip delete confirmations programmatically
JsonEditor(
  initialData: yourData,
  onDataChanged: (data) {},
  skipDeleteConfirmation: true, // Skip all delete confirmations
)

// Or let users set the preference via the dialog
// Users can check "Don't ask again" in the delete confirmation dialog
// to skip future confirmations for the current session

Debugging Expansion Issues

If you're experiencing issues with tree view expansion, you can enable debug mode to get detailed logging:

JsonEditor(
  initialData: yourData,
  onDataChanged: (data) => print('Data changed: $data'),
  expansionMode: ExpansionMode.all,
  maxExpansionLevel: 5,
  debugMode: true, // Enable debug logging
)

When debug mode is enabled, you'll see detailed console output showing:

  • Which expansion mode is being applied
  • What paths are being expanded
  • The final list of expanded nodes

This can help identify if the expansion parameters are being received correctly and if the expansion logic is working as expected.

Common Issues and Solutions

Issue: Expansion not working when data is loaded asynchronously Solution: The package now automatically handles data changes. If you're still experiencing issues, ensure you're using a ValueKey with your data to force widget recreation:

JsonEditor(
  key: ValueKey(yourData.hashCode), // Force recreation when data changes
  initialData: yourData,
  onDataChanged: (data) {},
  expansionMode: ExpansionMode.all,
)

Issue: Expansion mode not applying to updated data Solution: The package automatically re-applies expansion logic when initialData changes. If you're manually updating the data, make sure to pass the new data to the initialData parameter rather than trying to update it internally.

๐ŸŽจ Available Themes

Built-in Themes

  • RedPandaTheme: Beautiful dark theme with red accents (default)
  • JsonEditorTheme.light(): Clean light theme
  • JsonEditorTheme.dark(): Modern dark theme
  • JsonEditorTheme.material(context): Theme that adapts to your app's Material theme

Custom Themes

Create custom themes using the JsonEditorTheme.fromColors() factory constructor:

JsonEditorTheme.fromColors(
  editorBackground: Colors.grey[900]!,
  foreground: Colors.white,
  primaryColor: Colors.blue,
  stringColor: Colors.green,
  numberColor: Colors.orange,
  booleanColor: Colors.purple,
  nullColor: Colors.red,
  punctuationColor: Colors.grey,
  keyColor: Colors.cyan,
)

๐Ÿ“š API Reference

JsonEditor

The main widget for editing JSON data.

Properties

Property Type Required Default Description
initialData Map<String, dynamic> โœ… - The initial JSON data to display
onDataChanged Function(Map<String, dynamic>) โœ… - Callback function when data changes
title String โŒ 'JSON Editor' The title displayed in the editor header
readOnly bool โŒ false Whether the editor is read-only
allowCopy bool โŒ false Whether to show copy functionality
theme JsonEditorTheme? โŒ RedPandaTheme() Custom theme for the editor
isExpanded bool? โŒ true Initial expansion state
onExpansionChanged Function(bool)? โŒ - Callback when expansion state changes
onCollapse VoidCallback? โŒ - Callback when editor is collapsed
viewType ViewType โŒ ViewType.dual The view type to display (dual, treeOnly, rawOnly)
expansionMode ExpansionMode โŒ ExpansionMode.none Controls how tree view nodes are expanded by default
maxExpansionLevel int โŒ 2 Maximum levels to expand when using ExpansionMode.levels
debugMode bool โŒ false Enable debug logging for troubleshooting expansion issues
skipDeleteConfirmation bool โŒ false Skip delete confirmation dialogs (can also be set via "Don't ask again" checkbox)

JsonEditorTheme

Base class for custom themes with the following color properties:

  • editorBackground: Background color of the editor
  • foreground: Default text color
  • headerBackground: Header background color
  • surfaceBackground: Surface background color
  • lineNumbersBackground: Line numbers background color
  • borderColor: Border color
  • primaryColor: Primary accent color
  • onPrimary: Text color on primary background
  • errorColor: Error text and border color
  • cursorColor: Text cursor color
  • stringColor: JSON string value color
  • numberColor: JSON number value color
  • booleanColor: JSON boolean value color
  • nullColor: JSON null value color
  • punctuationColor: JSON punctuation color
  • keyColor: JSON key color

๐ŸŒŸ Features in Detail

Flexible View Modes

  • Dual View: Switch between text editor and tree view with tabs
  • Tree Only: Dedicated tree view interface for focused navigation
  • Raw Only: Full-featured text editor with syntax highlighting

Syntax Highlighting

  • Color-coded JSON syntax for better readability
  • Support for strings, numbers, booleans, null values, and punctuation
  • Customizable colors through themes

Tree View Features

  • Expandable/collapsible nodes
  • Inline editing of values and keys
  • Add new properties and array items
  • Delete properties and array items with confirmation
  • Intelligent type inference for arrays
  • Copy individual values

Smart Editing

  • Context-aware indentation
  • Auto-closing brackets, braces, and quotes
  • Real-time JSON validation
  • Error highlighting and messages

Action Buttons

  • Format: Beautify JSON with proper indentation
  • Clear: Reset to empty JSON object
  • Validate: Check JSON validity
  • Copy: Copy JSON to clipboard
  • Paste: Paste JSON from clipboard

Tree View Actions

  • Edit: Click to edit values and keys inline
  • Delete: Remove properties and array items with confirmation dialog and "Don't ask again" option
  • Add: Add new properties to objects or items to arrays
  • Copy: Copy individual values, keys, or entire nodes

๐Ÿ“ฑ Platform Support

  • โœ… Android
  • โœ… iOS
  • โœ… Web
  • โœ… Windows
  • โœ… macOS
  • โœ… Linux

๐Ÿ”ง Development

Running Tests

flutter test

Running the Example

cd example
flutter run

๐Ÿค Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

๐Ÿ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

๐Ÿ“‹ Changelog

1.0.0

  • ๐ŸŽ‰ Initial release
  • โœจ Dual view mode (text editor and tree view)
  • ๐ŸŽจ Syntax highlighting with customizable themes
  • ๐ŸŒณ Interactive tree view with inline editing
  • ๐Ÿ”ง Real-time JSON validation
  • ๐Ÿ“‹ Copy and paste functionality
  • ๐ŸŽ›๏ธ Action buttons (format, clear, validate)
  • ๐ŸŽจ Multiple built-in themes (RedPanda, Light, Dark, Material)
  • ๐Ÿ”ง Smart indentation and auto-closing
  • ๐Ÿ“ฑ Responsive design for all platforms
  • โšก Performance optimizations
  • ๐Ÿงช Comprehensive test coverage (85+ tests)

๐Ÿ™ Acknowledgments

  • Inspired by modern code editors and JSON viewers
  • Built with Flutter's powerful widget system
  • Tested across multiple platforms and devices

Libraries

spectre_json