• Stars
    star
    173
  • Rank 212,491 (Top 5 %)
  • Language
    Dart
  • License
    Apache License 2.0
  • Created 6 months ago
  • Updated 5 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Complete port of @preact/signals-core to Dart and extensions for common operations

Tests Website melos

Signals.dart

Complete dart port of Preact signals and takes full advantage of signal boosting.

Documentation Site: https://rodydavis.github.io/signals.dart/

Package Pub
signals signals
signals_core signals_core
signals_flutter signals_flutter
signals_lint signals_lint
signals_devtools_extension

Guide / API

The signals library exposes four functions which are the building blocks to model any business logic you can think of.

  graph LR;
      Signal-->Computed;
      Computed-->Computed;
      Computed-->Effect;
      Signal-->Effect;

signal(initialValue)

The signal function creates a new signal. A signal is a container for a value that can change over time. You can read a signal's value or subscribe to value updates by accessing its .value property.

import 'package:signals/signals.dart';

final counter = signal(0);

// Read value from signal, logs: 0
print(counter.value);

// Write to a signal
counter.value = 1;

Writing to a signal is done by setting its .value property. Changing a signal's value synchronously updates every computed and effect that depends on that signal, ensuring your app state is always consistent.

signal.peek()

In the rare instance that you have an effect that should write to another signal based on the previous value, but you don't want the effect to be subscribed to that signal, you can read a signals's previous value via signal.peek().

final counter = signal(0);
final effectCount = signal(0);

effect(() {
	print(counter.value);

	// Whenever this effect is triggered, increase `effectCount`.
	// But we don't want this signal to react to `effectCount`
	effectCount.value = effectCount.peek() + 1;
});

Note that you should only use signal.peek() if you really need it. Reading a signal's value via signal.value is the preferred way in most scenarios.

untracked(fn)

In case when you're receiving a callback that can read some signals, but you don't want to subscribe to them, you can use untracked to prevent any subscriptions from happening.

final counter = signal(0);
final effectCount = signal(0);
final fn = () => effectCount.value + 1;

effect(() {
	print(counter.value);

	// Whenever this effect is triggered, run `fn` that gives new value
	effectCount.value = untracked(fn);
});

computed(fn)

Data is often derived from other pieces of existing data. The computed function lets you combine the values of multiple signals into a new signal that can be reacted to, or even used by additional computeds. When the signals accessed from within a computed callback change, the computed callback is re-executed and its new return value becomes the computed signal's value.

import 'package:signals/signals.dart';

final name = signal("Jane");
final surname = signal("Doe");

final fullName = computed(() => name.value + " " + surname.value);

// Logs: "Jane Doe"
print(fullName.value);

// Updates flow through computed, but only if someone
// subscribes to it. More on that later.
name.value = "John";
// Logs: "John Doe"
print(fullName.value);

Any signal that is accessed inside the computed's callback function will be automatically subscribed to and tracked as a dependency of the computed signal.

effect(fn)

The effect function is the last piece that makes everything reactive. When you access a signal inside an effect's callback function, that signal and every dependency of said signal will be activated and subscribed to. In that regard it is very similar to computed(fn). By default all updates are lazy, so nothing will update until you access a signal inside effect.

import 'package:signals/signals.dart';

final name = signal("Jane");
final surname = signal("Doe");
final fullName = computed(() => name.value + " " + surname.value);

// Logs: "Jane Doe"
effect(() => print(fullName.value));

// Updating one of its dependencies will automatically trigger
// the effect above, and will print "John Doe" to the console.
name.value = "John";

You can destroy an effect and unsubscribe from all signals it was subscribed to, by calling the returned function.

import 'package:signals/signals.dart';

final name = signal("Jane");
final surname = signal("Doe");
final fullName = computed(() => name.value + " " + surname.value);

// Logs: "Jane Doe"
final dispose = effect(() => print(fullName.value));

// Destroy effect and subscriptions
dispose();

// Update does nothing, because no one is subscribed anymore.
// Even the computed `fullName` signal won't change, because it knows
// that no one listens to it.
surname.value = "Doe 2";

Warning Cycles

Mutating a signal inside an effect will cause an infinite loop, because the effect will be triggered again. To prevent this, you can use untracked(fn) to read a signal without subscribing to it.

import 'dart:async';

import 'package:signals/signals.dart';

Future<void> main() async {
  final completer = Completer<void>();
  final age = signal(0);

  effect(() {
    print('You are ${age.value} years old');
    age.value++; // <-- This will throw a cycle error
  });

  await completer.future;
}

batch(fn)

The batch function allows you to combine multiple signal writes into one single update that is triggered at the end when the callback completes.

import 'package:signals/signals.dart';

final name = signal("Jane");
final surname = signal("Doe");
final fullName = computed(() => name.value + " " + surname.value);

// Logs: "Jane Doe"
effect(() => print(fullName.value));

// Combines both signal writes into one update. Once the callback
// returns the `effect` will trigger and we'll log "Foo Bar"
batch(() {
	name.value = "Foo";
	surname.value = "Bar";
});

When you access a signal that you wrote to earlier inside the callback, or access a computed signal that was invalidated by another signal, we'll only update the necessary dependencies to get the current value for the signal you read from. All other invalidated signals will update at the end of the callback function.

import 'package:signals/signals.dart';

final counter = signal(0);
final _double = computed(() => counter.value * 2);
final _triple = computed(() => counter.value * 3);

effect(() => print(_double.value, _triple.value));

batch(() {
	counter.value = 1;
	// Logs: 2, despite being inside batch, but `triple`
	// will only update once the callback is complete
	print(_double.value);
});
// Now we reached the end of the batch and call the effect

Batches can be nested and updates will be flushed when the outermost batch call completes.

import 'package:signals/signals.dart';

final counter = signal(0);
effect(() => print(counter.value));

batch(() {
	batch(() {
		// Signal is invalidated, but update is not flushed because
		// we're still inside another batch
		counter.value = 1;
	});

	// Still not updated...
});
// Now the callback completed and we'll trigger the effect.

DevTools

More Repositories

1

gmail_clone

A Gmail Clone built with Flutter
Dart
802
star
2

flutter_login

100% Shared Code Android/iOS Login Example - JSON API
Dart
682
star
3

plugins

Flutter plugins created by Rody Davis
Dart
488
star
4

flutter_everywhere

Template Flutter Project for iOS, Android, Fuschica, MacOS, Windows, Linux, Web, Command Line, Chrome Extension
C++
402
star
5

flutter_piano

A Cross Platform Piano made with Flutter
Dart
385
star
6

storyboard

Flutter Storyboard
Dart
199
star
7

data_tables

Data Tables for Flutter
Dart
172
star
8

easy_web_view

Flutter Web Views on Mobile and Web made easy!
Dart
156
star
9

moor_shared

Shared SQLite DB across mobile, web and desktop
Dart
143
star
10

flutter_ast

Flutter and Dart AST Analyzer/Parser
Dart
101
star
11

multi_window

Flutter Multi Window Example on MacOS
C++
91
star
12

vscode_ipad

An Attempt to Port VSCode to the iPad with Flutter.io
Objective-C
88
star
13

FlutterWebXRThreeJS

Flutter Web Example with ThreeJS
Dart
71
star
14

easy_google_maps

Easy Google Maps for Flutter
Dart
67
star
15

flutter_dynamic_widget

Widget Runtime for WidgetStudio
Dart
64
star
16

flutter_json_widgets

Build flutter widgets with pure dart classes
Dart
64
star
17

file_access

File.io for Web, Desktop and Mobile for Flutter
Dart
59
star
18

native_draggable

Native Drag and Drop for Flutter on iOS and MacOS
Dart
59
star
19

undo

Undo/Redo for Flutter and Dart
Dart
57
star
20

flutter_midi

Midi Playback in Flutter
Swift
55
star
21

navigation_rail

Navigation Rail for Flutter
Dart
51
star
22

flutter_web_component

Render Flutter app inside of a Web Component
Dart
51
star
23

golden_layout

Flutter Golden Layout
Dart
51
star
24

fb_auth

Shared Mobile and Web Firebase Login
Dart
45
star
25

flutter_pptx

Create PowerPoint (pptx) presentations in Flutter and Dart
Dart
44
star
26

sheet_music

Sheet Music for Flutter
Dart
41
star
27

flutter_multi_touch_canvas

Flutter Multi Canvas with Pan/Zoom
C++
38
star
28

flutter_implicit_animations

Flutter animations every frame
C++
37
star
29

flutter_ffi_webassembly

Flutter FFI+WebAssembly Example
Makefile
33
star
30

lit-native

Example of how to embed a Lit web component into native platforms.
Swift
32
star
31

flutter_remote_compiler

Remote Flutter/Dart Compiler for CloudRun and Docker
Dart
32
star
32

floating_search_bar

Floating Search Bar like Gmail for Flutter
Dart
30
star
33

media_picker

A Flutter Plugin for Selecting and Taking New Photos and Videos.
Java
28
star
34

flutter_take_5

Flutter Take 5 Video Series
Dart
28
star
35

flutter_wasm_interop

Dart
25
star
36

shared_dart

Web, Android, iOS, and Server in one Project with Flutter and Cloud Run
C++
25
star
37

md_responsive_flutter

Responsive Material Design Template with Flutter
Dart
25
star
38

mobile_sidebar

Responsive Sidebar for Flutter
Objective-C
23
star
39

podcast-player

Podcast Player with Flutter
Dart
23
star
40

flutter_tauri

Flutter + Tauri + Vite.
Dart
22
star
41

html-canvas-utilities

TypeScript
21
star
42

object-dom

HTML Object Declarative Dom
TypeScript
21
star
43

provider_persist

Persist your UI State with Provider.
Objective-C
20
star
44

flutter_multi_window

Multi Window Plugin for Flutter
Dart
19
star
45

flutter_scripts

Dart
18
star
46

adaptive_ui

Adaptive UI (Flutter)
C++
17
star
47

settings_manager

Flutter settings manager built on top of Shared Preferences
Dart
17
star
48

lit-html-editor

Rich text editor built with Lit and Material MWC components.
TypeScript
16
star
49

dart_pad_ext

Dart Pad Chrome Extension
JavaScript
16
star
50

widgets_reflect

Dynamic Flutter Widgets from JSON and Reflected Properties
Dart
15
star
51

file_manager

Dart
15
star
52

flutter_codespaces_template

Flutter Template for Github Codespaces
Shell
15
star
53

native_color_picker

Native Color Picker for Flutter
Dart
15
star
54

lit-3d-piano

3D Piano built with Lit, Three.js and Tone.js
TypeScript
15
star
55

flutter_counter_clean_architecture

Flutter counter app with clean architecture and riverpod
Dart
15
star
56

lit-node-editor

Node editor built with canvas api, simple graph data structure and included transforms for scale, pan and move.
TypeScript
15
star
57

pocketbase_drift

Pocketbase client cached with drift (sqlite)
Dart
14
star
58

infinite_canvas

Flutter infinite canvas that can be zoomed and panned.
Dart
14
star
59

flutter_deep_linking

Deep Linking for Flutter Web
Dart
14
star
60

flutter_analyzer

Flutter Analyzer for Flutter
Dart
14
star
61

image_resizer

Flutter/Dart Image Resize and Generator
Dart
13
star
62

widget_gen

Widget Generator for Flutter
Dart
13
star
63

fb_firestore

Firebase Firestore on Web, Mobile and Desktop
Dart
12
star
64

material-icon-pack-stream-deck

Material Design icons for the Stream Deck
JavaScript
12
star
65

SwiftUI2Flutter

Easy way to port SwiftUI Code to Flutter. Support for Platform Channels and Android.
12
star
66

features

Flutter scoped feature manager
Dart
11
star
67

flutter_todo_app

Todo app built on live stream
Dart
11
star
68

lit-draggable-dom

Example of how to take HTML Elements or SVG Elements as slots and render them on a canvas that can be dragged as a whole or individual items.
TypeScript
11
star
69

flutter_ast_core

Dart
11
star
70

flutter_hybrid_template

Dart
11
star
71

firestore_sqlite

Inspired by PocketBase provide client side SQLite database, schema generator and admin UI
Dart
11
star
72

vite-lit-element-starter

Lit Element + Vue
TypeScript
11
star
73

flutter_file_based_routing

File based routing and nested layouts for Flutter
Dart
10
star
74

scaffold_tab_bar

Nested Scaffold Navigation
Dart
10
star
75

lit-code-editor

Lit Code Editor built with Vite and Monaco Editor (ESM version).
TypeScript
10
star
76

flutter_wasm_example

Flutter + WebAssembly Example
Rust
10
star
77

flutter_ssr

Dart
9
star
78

firebase.dart

A Dart Wrapper around the Firestore Rest API (Supports Flutter Desktop, Web, and Mobile)
Objective-C
9
star
79

flutter_codemirror

Flutter + Codemirror
JavaScript
9
star
80

flutter_routing

Proper Routing for Flutter Web
Dart
9
star
81

rodydavis

Polyglot Developer, Musician and Creator
Astro
9
star
82

lit-file-based-routing

Lit + File Based Routing + Nested Layouts
TypeScript
9
star
83

powerpack

Flutter Dart Extensions
Dart
9
star
84

vite-lit-capacitor

An example of Lit web component built with vite for use in capacitor.
TypeScript
8
star
85

project_gen

Project Generator for Flutter
Dart
8
star
86

page_turn

Page Turn Widget Builder for Flutter
Dart
8
star
87

flutter_compiler

Flutter Compiling Flutter
JavaScript
8
star
88

cupertino_controllers

Cupertino Controllers for Flutter
Dart
8
star
89

vscode-router-generator

VSCode extension to generate a router based on file based routing and nested layouts
TypeScript
8
star
90

flutter_gallery_storyboard

Flutter Gallery Storyboard View
Dart
8
star
91

vscode-dynamic-theme

Generate a dynamic theme based on Material Design color space.
TypeScript
7
star
92

flutter_ssr_example

Flutter Server Side Rendering Example
Dart
7
star
93

lit-sheet-music

Lit Sheet Music rendered using opensheetmusicdisplay
HTML
7
star
94

flutter_x

Crossplatform Codebase with Native Plugins
Dart
6
star
95

flutter_graph_database

Graph Database in Flutter and Dart
C++
6
star
96

lit-force-graph

2D/3D force graph with Lit
TypeScript
6
star
97

creative_engineering

Creative Engineering Podcast
Dart
6
star
98

lit-modules

Lit Modules for templates, styles and logic.
TypeScript
6
star
99

flutter_firebase_template

Firebase Auth and Firestore for Web
Dart
6
star
100

Tesla-API

Postman files for Tesla API Testing
5
star