# Shared DevTools Components

This package contains UI, utility, and service components from
[Dart & Flutter DevTools](https://docs.flutter.dev/tools/devtools/overview) that can
be shared between DevTools, DevTools extensions, and other tooling surfaces that need
the same logic or styling.

## Usage

Add a dependency to your `pubspec.yaml` file:
```yaml
devtools_app_shared: ^0.0.7
```

Import the component library that you need:
```dart
import 'package:devtools_app_shared/service.dart';
import 'package:devtools_app_shared/service_extensions.dart' as extensions;
import 'package:devtools_app_shared/ui.dart';
import 'package:devtools_app_shared/utils.dart';
```

### Examples

1. Set and access global variables.

```dart
import 'package:devtools_app_shared/utils.dart';

MyCoolClass get coolClass => globals[MyCoolClass] as MyCoolClass;

void main() {
  // Creates a globally accessible variable (`globals[ServiceManager]`);
  setGlobal(MyCoolClass, MyCoolClass());
  coolClass.foo();
}
```

2. Use utilities like the `AutoDisposeMixin`, which supports adding listeners
that will automatically dispose as part of the `StatefulWidget` lifecycle.

```dart
import 'package:devtools_app_shared/utils.dart';

class MyStatefulWidget extends StatefulWidget {
  const MyStatefulWidget({super.key});

  @override
  State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
}

class _MyStatefulWidgetState extends State<MyStatefulWidget>
    with AutoDisposeMixin {
  var foo = 'hi';

  @override
  void initState() {
    super.initState();
    addAutoDisposeListener(someListenable, () {
      setState(() {
        foo = '$foo hi';
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Text(foo);
  }
}
```

3. Access shared UI components and styling.

```dart
import 'package:devtools_app_shared/ui.dart';
...
@override
Widget build(BuildContext context) {
  return RoundedOutlinedBorder( // Shared component
    child: Column(
      children: [
        AreaPaneHeader( // Shared component
          roundedTopBorder: false,
          includeTopBorder: false,
          title: Text('This is a section header'),
        ),
        Expanded(
          child: FooWidget(
            child: Text(
              'Foo',
              style: Theme.of(context).subtleTextStyle, // Shared style
            ),
          ),
        ),
      ],
    ),
  );
}
```

4. VM service management, including access to isolates and service extensions.

```dart
import 'package:devtools_app_shared/service.dart';
import 'package:devtools_app_shared/service_extensions.dart' as extensions;
import 'package:devtools_shared/service.dart';

void main() {
  final serviceManager = ServiceManager();

  // Use the [connectedState] notifier to listen for connection updates.
  serviceManager.connectedState.addListener(() {
    if (serviceManager.connectedState.value.connected) {
      print('Manager connected to VM service');
    } else {
      print('Manager not connected to VM service');
    }
  });

  // To get a [VmService] object from a vm service URI, consider importing
  // `package:devtools_shared/service.dart` from `package:devtools_shared`.
  final finishedCompleter = Completer<void>();
  final vmService = await connect<VmService>(
    uri: Uri.parse(vmServiceUri),
    finishedCompleter: finishedCompleter,
    serviceFactory: VmService.defaultFactory,
  );

  await serviceManager.vmServiceOpened(
    vmService,
    onClosed: finishedCompleter.future,
  );

  // Get a service extension state.
  final ValueListenable<ServiceExtensionState> performanceOverlayEnabled =
      serviceManager.manager.serviceExtensionManager.getServiceExtensionState(
        extensions.performanceOverlay.extension,
      );

  // Set a service extension state.
  await serviceManager.manager.serviceExtensionManager.setServiceExtensionState(
    extensions.performanceOverlay.extension,
    enabled: true,
    value: true,
  );

  // Access isolates.
  final myIsolate = serviceManager.isolateManager.mainIsolate.value;

  // Etc.
}
```

## Issues & feedback

This package is developed as part of the larger
[flutter/devtools](https://github.com/flutter/devtools) project.
Please report any issues or feedback there.
