Solid API docs
Provides providers to descendants.
Has some special convenience methods for Signals
.
Default Constructor
Solid({
Widget? child,
Widget Function(BuildContext)? builder,
List<SolidElement> providers = const [],
});
child
is the child that will get access to the providers in its build
method.
builder
is the builder function used to build the child
and immediately get access to a BuildContext
with the access to the providers.
providers
is a list of providers that will be accessible to all descendants.
class NameProvider {
const NameProvider(this.name);
final String name;
void dispose() {
// put your dispose logic here
// ignore: avoid_print
print('dispose name provider');
}
}
class NumberProvider {
const NumberProvider(this.number);
final int number;
}
class ProvidersPage extends StatelessWidget {
const ProvidersPage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Providers'),
),
body: Solid(
providers: [
Provider<NameProvider>(
create: () => const NameProvider('Ale'),
// the dispose method is fired when the [Solid] widget above is removed from the widget tree.
dispose: (provider) => provider.dispose(),
),
Provider<NumberProvider>(
create: () => const NumberProvider(1),
// Do not create the provider lazily, but immediately
lazy: false,
id: #firstNumber,
),
Provider<NumberProvider>(
create: () => const NumberProvider(100),
// Do not create the provider lazily, but immediately
lazy: false,
id: #secondNumber,
),
],
child: const SomeChild(),
),
);
}
}
class SomeChild extends StatelessWidget {
const SomeChild({super.key});
@override
Widget build(BuildContext context) {
final nameProvider = context.get<NameProvider>();
final numberProvider = context.get<NumberProvider>(#firstNumber);
final numberProvider2 = context.get<NumberProvider>(#secondNumber);
return Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text('name: ${nameProvider.name}'),
const SizedBox(height: 8),
Text('number1: ${numberProvider.number}'),
const SizedBox(height: 8),
Text('number2: ${numberProvider2.number}'),
],
),
);
}
}
Solid.value constructor
Solid.value({
SolidElement? element,
List<SolidElement>? elements,
required Widget child,
})
Provide a single or multiple SolidElement
s to a new route.
This is useful for passing multiple providers to modals, because they are spawned in a new tree.
Future<void> openDialog(BuildContext context) {
return showDialog(
context: context,
builder: (_) => Solid.value(
elements: [
context.getElement<NameProvider>(),
context.getElement<NumberProvider>(#firstNumber),
context.getElement<NumberProvider>(#secondNumber),
],
child: Dialog(
child: Builder(builder: (innerContext) {
final nameProvider = innerContext.get<NameProvider>();
final numberProvider1 =
innerContext.get<NumberProvider>(#firstNumber);
final numberProvider2 =
innerContext.get<NumberProvider>(#secondNumber);
return SizedBox.square(
dimension: 100,
child: Center(
child: Text('''
name: ${nameProvider.name}
number1: ${numberProvider1.number}
number2: ${numberProvider2.number}
'''),
),
);
}),
),
),
);
}
T context.get<T>([Identifier? id])
Gets a provider of type T
from the list of providers.
If the provider is not found in the first Solid
ancestor, it will go up in the tree until it finds it in another Solid
ancestor.
id
is an optional parameter that specifies the id of the provider. This is useful when you have multiple providers of the same type and you want to distinguish between them.
This methods throws if the provided cannot be found.
T? context.maybeGet<T>([Identifier? id])
Like context.get
, but returns null
instead of throwing if the provider cannot be found.
SolidElement<T> getElement<T>([Identifier? id])
Gets a provider of type T
from the list of providers.
It returns the SolidElement
of the provider instead of the provider itself.
Can be used in modals to provide access to the provider.
T context.observe<T>([Identifier? id])
Subscribes to the Signal with the value type of T
and the id
provided (if any).
class ObserveSignalPage extends StatelessWidget {
const ObserveSignalPage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: Solid(
providers: [
// provide the count signal to descendants
Provider<Signal<int>>(create: () => Signal(0)),
],
child: const SomeChild(),
),
);
}
}
class SomeChild extends StatelessWidget {
const SomeChild({super.key});
@override
Widget build(BuildContext context) {
// retrieve the count signal, this works only if you don't have another signal of type int
final count = context.observe<int>();
return Center(
child: Text('count: $count'),
);
}
}