<!--
Copyright 2025 The Flutter Authors
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file or at https://developers.google.com/open-source/licenses/bsd.
-->
# 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.

## Supported Flutter versions

This package follows the `flutter/packages`
[policy](https://github.com/flutter/flutter/blob/master/docs/ecosystem/contributing/README.md#supported-flutter-versions)
for supported Flutter versions, which states that a package will support the latest `stable`
version of Flutter, as well as the current `master`. In practice, this package will often
support older versions as well, as minimum version requirements are generally only updated
when there is a specific need, such as using a new DevTools or Flutter feature.
