# Shared DevTools Components

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

## Usage

The following will add the package as a dependency to your `pubspec.yaml` (and run an
implicit `flutter pub get`):

```console
$ flutter pub add devtools_app_shared
```

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.
