Flutter UI
Render reactive state with .ui(), PopsicleWidget, PopsicleBuilder, and PopsicleConsumer.
Flutter UI
Popsicle keeps Flutter rendering as a projection of state:
UI = f(state)
Store .ui()
Use .ui() as the normal Store rendering API:
counter.ui(
(context, state, store) {
return FilledButton(
onPressed: store.increment,
child: Text('$state'),
);
},
);
Attach one-shot effects when the feature needs navigation, snackbars, dialogs, or similar UI work:
profile.ui(
(context, state, store) => ProfileBody(state: state),
effect: (context, effect) {
// Handle an occurrence once.
},
);
ReactiveValue .ui()
Small state projects directly to a widget:
final selectedTab = Popsicle.value(0);
selectedTab.ui(
(index) => Text('Tab $index'),
);
PopsicleWidget
Use PopsicleWidget when one widget needs several
declarations or direct Store access:
class CounterActions extends PopsicleWidget {
const CounterActions({super.key});
@override
Widget build(BuildContext context, Scope scope) {
final count = scope.use(counter);
final store = scope.store(counter);
return Row(
children: [
Text('$count'),
IconButton(
onPressed: store.increment,
icon: const Icon(Icons.add),
),
],
);
}
}
The access rules stay explicit:
scope.get(source) -> current value, non-reactive
scope.use(source) -> current value + rebuild dependency
scope.store(source) -> Store instance, non-reactive
scope.select(source, selector) -> rebuild only for the selected projection
PopsicleBuilder
Use a builder when introducing a small reactive boundary inside an ordinary widget tree:
PopsicleBuilder(
builder: (context, scope, child) {
final mode = scope.use(themeMode);
return Text('$mode');
},
);
Explicit PopsicleConsumer
.ui() is implemented on top of
PopsicleConsumer. Use the explicit widget when a
named widget boundary is clearer:
PopsicleConsumer<CounterStore, int>(
source: counter,
build: (context, state, store) {
return Text('$state');
},
effect: (context, effect) {
// Handle one-shot effect.
},
);
Prefer .ui() for ordinary feature rendering and keep
PopsicleConsumer for explicit or reusable boundaries.