Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add documentation #8

Merged
merged 82 commits into from
Jan 29, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
82 commits
Select commit Hold shift + click to select a range
eb8ed1f
Add documentation
manuel-plavsic Jan 26, 2025
e565dfa
Rename file
manuel-plavsic Jan 26, 2025
ae0b741
Rename alternatives to miscellaneous
manuel-plavsic Jan 26, 2025
937dbf2
Improve docs
manuel-plavsic Jan 26, 2025
22780df
remove file prefixes
manuel-plavsic Jan 26, 2025
38222a0
Make small adjustments
manuel-plavsic Jan 26, 2025
9825b21
Make small correction
manuel-plavsic Jan 26, 2025
1009940
docs: updates
nank1ro Jan 27, 2025
2d13117
docs: add basic example
nank1ro Jan 27, 2025
ea7554e
docs: update sentence
nank1ro Jan 27, 2025
780c9ed
Add Installing page
manuel-plavsic Jan 27, 2025
af99e54
Reframe sentence
manuel-plavsic Jan 27, 2025
dd57382
Remove service_injection example
manuel-plavsic Jan 27, 2025
bb1a4aa
Prepare all examples
manuel-plavsic Jan 27, 2025
d0683b2
Fix typo
manuel-plavsic Jan 27, 2025
b4cfd62
Merge branch 'main' into feat/documentation
nank1ro Jan 27, 2025
2be31b9
Merge branch 'main' into feat/documentation
nank1ro Jan 27, 2025
917a6c7
docs: auto route
nank1ro Jan 27, 2025
4d19ab9
docs: update
nank1ro Jan 27, 2025
3deeb9e
docs: add file structure to bloc
nank1ro Jan 27, 2025
497a778
docs: use link card for source code
nank1ro Jan 27, 2025
cf00e9a
docs: update installing
nank1ro Jan 27, 2025
f3e2eda
docs: add empty line
nank1ro Jan 27, 2025
dd03b50
docs: solidart
nank1ro Jan 27, 2025
d7afcf3
Mention that global state solutions usually use extra objects to mana…
manuel-plavsic Jan 27, 2025
18fe128
Make small corrections
manuel-plavsic Jan 27, 2025
0aca5b0
Make small improvements
manuel-plavsic Jan 27, 2025
b588122
Refine bloc example
manuel-plavsic Jan 28, 2025
056fd32
docs: add example deps
nank1ro Jan 28, 2025
56d8d9a
docs: add dependency
nank1ro Jan 28, 2025
1afbffe
docs: authors
nank1ro Jan 28, 2025
15486af
docs: update bio
nank1ro Jan 28, 2025
a5205d1
docs: author card add social links
nank1ro Jan 28, 2025
7caac1d
docs: update
nank1ro Jan 28, 2025
790aa24
docs: graphical representation of provider scope
nank1ro Jan 28, 2025
aa0a563
docs: update provider scope graph
nank1ro Jan 28, 2025
195fbe9
docs: add provider scope exception
nank1ro Jan 28, 2025
95286e5
docs: theme image
nank1ro Jan 28, 2025
8057b0d
Improve authors section
manuel-plavsic Jan 28, 2025
50f5df6
Improve my own introduction
manuel-plavsic Jan 28, 2025
df7f25b
Improve authors
manuel-plavsic Jan 28, 2025
ab170c4
Small correction
manuel-plavsic Jan 28, 2025
1fe11be
Improve main page title and description
manuel-plavsic Jan 28, 2025
80492d8
Move author section to the end but also add link in index
manuel-plavsic Jan 28, 2025
78ab6bd
docs: add provider scope portal images
nank1ro Jan 28, 2025
95b43ca
docs: update authors
nank1ro Jan 28, 2025
4afd23e
docs: fix typo
nank1ro Jan 28, 2025
a0f049f
docs: add how providers are found graph
nank1ro Jan 28, 2025
958979e
docs: add note about big o notation
nank1ro Jan 28, 2025
af5c2e3
Make changes
manuel-plavsic Jan 28, 2025
f2c6692
Merge branch 'main' into feat/documentation
nank1ro Jan 28, 2025
7369695
Rename to Provider Retrieval Process
manuel-plavsic Jan 28, 2025
dfd6f7b
Add warnings
manuel-plavsic Jan 28, 2025
4b3daf8
Add comma
manuel-plavsic Jan 28, 2025
7bcf2e6
Fix typo
manuel-plavsic Jan 28, 2025
c246e41
Use notes and tips in testing and make other small improvements
manuel-plavsic Jan 28, 2025
9e64e67
Add example heading inside modals.mdx
manuel-plavsic Jan 28, 2025
5cacd72
Add two example headings to reactivity.md
manuel-plavsic Jan 28, 2025
e86f493
Reframe sentence
manuel-plavsic Jan 28, 2025
cca9c91
Rename heading in index
manuel-plavsic Jan 28, 2025
d859d6f
Clarify comment in reactivity.md
manuel-plavsic Jan 28, 2025
90c3c29
Do not capitalize "providers"
manuel-plavsic Jan 28, 2025
3f7108a
Remove unnecessary parts and make some fixes.
manuel-plavsic Jan 28, 2025
eb703d4
Make improvements to scoped-di.mdx
manuel-plavsic Jan 28, 2025
ec7a97d
Fix typos and reframe some sentences.
manuel-plavsic Jan 29, 2025
e79d1d8
Make small adjustment
manuel-plavsic Jan 29, 2025
0725865
Fix headings
manuel-plavsic Jan 29, 2025
a2f3ef9
Fix other headings
manuel-plavsic Jan 29, 2025
78996c3
Reframe text and change its order
manuel-plavsic Jan 29, 2025
17bc916
Simplify sentence in authors.mdx
manuel-plavsic Jan 29, 2025
986a923
docs: fix import
nank1ro Jan 29, 2025
17c6959
docs: fix typos
nank1ro Jan 29, 2025
aafce59
docs: fix variablee not useed
nank1ro Jan 29, 2025
968173c
Merge branch 'main' into feat/documentation
nank1ro Jan 29, 2025
416beaf
docs: preferences example
nank1ro Jan 29, 2025
ae06873
docs: preferences
nank1ro Jan 29, 2025
ddcff31
docs: immutability
nank1ro Jan 29, 2025
70c25cf
docs: remove prefixes from code title
nank1ro Jan 29, 2025
2d82a9c
docs: update var name in immutability
nank1ro Jan 29, 2025
4cc17de
Make improvements
manuel-plavsic Jan 29, 2025
d604538
fix typo
manuel-plavsic Jan 29, 2025
14894aa
Change from examples to single example in preferences.mdx
manuel-plavsic Jan 29, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,13 @@ You can retrieve a provider from any widget in the subtree of the `ProviderScope

### Examples

There are multiple examples on the repository (the `examples` folder and the
single `example` inside the disco package).
There are multiple examples on the repository:

- [basic](https://disco.mariuti.com/examples/basic/) A basic example showing the basic usage of Disco.
- [solidart](https://disco.mariuti.com/examples/solidart/) An example showcasing the power of the `ProviderScope` widgets combined with solidart reactivity.
- [bloc](https://disco.mariuti.com/examples/bloc/) An example showcasing how to provide a light/dark theme Cubit with Disco.
- [auto_route](https://disco.mariuti.com/examples/auto-route/) An example showing how to share a provider between multiple pages without scoping the entire app.
- [preferences](https://disco.mariuti.com/examples/preferences/) An example showing how to provide async objects with Disco.

## Additional information

Expand Down
41 changes: 39 additions & 2 deletions docs/astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,45 @@ export default defineConfig({
},
sidebar: [
{
label: 'Guides',
autogenerate: { directory: 'guides' },
label: 'Overview',
link: '',
},
{
label: 'Installing',
link: 'installing',
},
{
label: 'Core',
items: [
'core/providers',
'core/scoped-di',
'core/immutability',
'core/modals',
'core/testing',
'core/provider-retrieval-process',
'core/configuration',
],
},
{
label: 'Miscellaneous',
items: [
'miscellaneous/reactivity',
'miscellaneous/comparison-with-alternatives',
],
},
{
label: 'Examples',
items: [
'examples/basic',
'examples/solidart',
'examples/preferences',
'examples/bloc',
'examples/auto-route',
],
},
{
label: 'Authors',
link: 'authors',
},
],
}),
Expand Down
Binary file added docs/public/ale.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/public/disco.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/public/manuel.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions docs/public/provider-scope-behavior.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions docs/public/provider-scope-behavior_dark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions docs/public/provider-scope-exception.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions docs/public/provider-scope-exception_dark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions docs/public/provider-scope-portal-exception.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions docs/public/provider-scope-portal-exception_dark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions docs/public/provider-scope-portal.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions docs/public/provider-scope-portal_dark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions docs/public/provider-scope.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions docs/public/provider-scope_dark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed docs/src/assets/houston.webp
Binary file not shown.
59 changes: 59 additions & 0 deletions docs/src/components/AuthorCard.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
---
const { imageSrc, name, twitterUrl, githubUrl } = Astro.props;
import { Icon } from '@astrojs/starlight/components';
---

<div class="author-card">
<img src={imageSrc} alt={`Image of ${name}`} class="author-image" />
<div class="author-info">
<h3 class="author-name">{name}</h3>
<div class="social-links">
{githubUrl && (
<a href={githubUrl} target="_blank" rel="noopener noreferrer">
<Icon name="github" />
</a>
)}
{twitterUrl && (
<a href={twitterUrl} target="_blank" rel="noopener noreferrer">
<Icon name="x.com" />
</a>
)}
</div>
</div>
</div>

<style>
.author-card {
display: flex;
align-items: center; /* Aligns items vertically */
margin: 1rem 0;
}

.author-image {
border-radius: 50%;
width: 50px;
height: 50px;
margin-right: 1rem;
object-fit: cover; /* Ensures the image covers the area without distortion */
}

.author-info {
margin: 0 !important; /* Removes all default margins */
display: flex;
flex-direction: column; /* Stack name and link vertically */
}

.social-links {
display: flex; /* Align icons in a row */
gap: 8px;
}

.author-name {
font-size: 1.25rem;
color: var(--text-color);
margin: 0 !important; /* Removes all default margins */
padding: 0; /* Removes default padding */
line-height: 50px; /* Match line-height to the image height for vertical centering */
}

</style>
39 changes: 39 additions & 0 deletions docs/src/components/ThemeImage.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
---
const { src, darkSrc, alt } = Astro.props;
let uuid = crypto.randomUUID();
---

<img src={src} alt={alt} id={uuid} class="theme-image" />

<script is:inline define:vars={{src, darkSrc, uuid }}>
function updateImage() {
const themeMode = document.documentElement.getAttribute("data-theme");
const isDarkTheme = themeMode === 'dark'; // Check for dark class
const imgElement = document.getElementById(uuid);
imgElement.src = isDarkTheme ? darkSrc : src; // Set the appropriate image
}

// Initial check
updateImage();
// Observe changes to the `data-theme` attribute
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.attributeName === "data-theme") {
updateImage();
}
});
});

observer.observe(document.documentElement, {
attributes: true,
attributeFilter: ["data-theme"],
});
</script>


<style>
.theme-image {
width: 100%;
height: auto;
}
</style>
59 changes: 59 additions & 0 deletions docs/src/content/docs/authors.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
---
title: Authors
description: The authors of Disco.
---
import { Card, CardGrid } from '@astrojs/starlight/components';
import AuthorCard from '../../components/AuthorCard.astro';

<CardGrid>
<AuthorCard
imageSrc="/ale.png"
name="Alexandru Mariuti"
githubUrl="https://github.com/nank1ro"
twitterUrl="https://x.com/nank1ro"
/>
<AuthorCard
imageSrc="/manuel.jpg"
name="Manuel Plavsic"
githubUrl="https://github.com/manuel-plavsic"
twitterUrl="https://x.com/ManuelPlavsic"
/>
</CardGrid>

## Alexandru Mariuti

I am an open source enthusiast, passionate about Dart and Flutter, and a strong believer in the power of community.

Maintainer of:
- [solidart](https://pub.dev/packages/solidart) and [flutter_solidart](https://pub.dev/packages/flutter_solidart) (Dart/Flutter state management library inspired by [SolidJS](https://www.solidjs.com/))
- [shadcn_ui (flutter port)](https://pub.dev/packages/shadcn_ui) (Design system inspired by [ui.shadcn.com](https://ui.shadcn.com/))
- [awesome_flutter_extensions](https://pub.dev/packages/awesome_flutter_extensions) (Useful Flutter extensions)
- [disable_web_context_menu](https://pub.dev/packages/disable_web_context_menu) (Disable native web context menu)
- [disco](https://pub.dev/packages/disco) (Dependency injection library for Flutter)
- [prompt_parser](https://pypi.org/project/prompt-parser/) (Python library for parsing LLM prompts)

## Manuel Plavsic

I am a software engineer passionate about full-stack development, cloud, and cryptography who enjoys challenging established practices to discover better solutions.
I like friendly environments where people work well together and a bit of humor keeps things fun.

Maintainer of:
- [disco](https://pub.dev/packages/disco) (Dependency injection library for Flutter)
- [nidula](https://pub.dev/packages/nidula) (A Dart library for Rust-like Option/Result types)

Contributor of:
- [solidart](https://pub.dev/packages/solidart) and [flutter_solidart](https://pub.dev/packages/flutter_solidart) (Dart/Flutter state management inspired by [SolidJS](https://www.solidjs.com/))

## Disco's journey

Inspired by SolidJS, I — Alexandru — created a state-management library called solidart, also featuring providers and a `Solid` widget, the equivalent of this library's `ProviderScope`.

Manuel played a key role in improving the `Solid` widget and simplifying the providers through numerous PRs. One day, he proposed a radical idea: introducing a `ProviderContext` class that would act like a `Context` in SolidJS or in React. Essentially, `ProviderContext` would serve as the identifier for a scoped `Provider` object, making it safer than relying solely on the type of the provided value (e.g., `context.get<Model>()`).

Shortly after, I realized we could simplify things further by using the providers themselves as identifiers. This approach aligned better with the Flutter ecosystem, where defining providers directly is more intuitive.

During the refactoring process, we adhered to a simple principle: there should only be one way to do something. At one point, we noticed that the provider implementation no longer depended on the rest of solidart. This led us to extract it into a separate package, which we named Disco (where the "di" stands for dependency injection and the "sco" for scope).

We continued refining the library through successive iterations. For instance, we noticed we could make the API feel more natural to Flutter by renaming `modelProvider.get(context)` to `modelProvider.of(context)`.

It has been a wonderful journey, and we hope many will enjoy using this open-source library.
19 changes: 19 additions & 0 deletions docs/src/content/docs/core/configuration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
title: Configuration
description: How to set up the application-wide configuration for Disco.
---

Disco aims to be minimally opinionated. To customize the default configuration, set the desired preferences using `DiscoConfig` before calling `runApp`. For example:

```dart
DiscoConfig.lazy = false;
runApp(
// ...
);
```

### All options

| Option | Default | Description |
| -------------- | ------- | ----------- |
| `lazy` | true | The values of the providers provided in a `ProviderScope` are created lazily. |
103 changes: 103 additions & 0 deletions docs/src/content/docs/core/immutability.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
---
title: Immutability
description: Learn how immutability impacts Disco providers.
---

import { Aside } from '@astrojs/starlight/components';

In Disco, providers are immutable. This means that once a provider is created, it cannot be changed.

This is a design choice that we made to ensure that the instance of the provider is consistent throughout the application.

Let's look at an example, think a bit about the output after the `FloatingActionButton` is pressed, then continue reading to see if you were correct.

```dart
import 'package:disco/disco.dart';
import 'package:flutter/material.dart';

void main() {
runApp(const MainApp());
}

final counterProvider =
Provider.withArgument((context, Counter counter) => counter);

class Counter {
Counter(this.value);

final int value;
}

class MainApp extends StatefulWidget {
const MainApp({super.key});

@override
State<MainApp> createState() => _MainAppState();
}

class _MainAppState extends State<MainApp> {
var counter = Counter(0);

@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Immutability',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: ProviderScope(
providers: [
counterProvider(counter),
],
child: Scaffold(
body: Builder(
builder: (context) {
return Center(
child: Text('The counter is ${counterProvider.of(context).value}'),
);
},
),
floatingActionButton: FloatingActionButton(
onPressed: () {
setState(() {
counter = Counter(counter.value + 1);
});
},
child: const Icon(Icons.add),
),
),
),
);
}
}
```

The example renders `The counter is 0`. After the user presses the `FloatingActionButton`, the counter is incremented, but the UI does not update.
This is because the provider is immutable, and the instance of the provider is not updated. In other words, the `counterProvider` is created only the first time and it still provides the initial instance.

You may be skeptical about the immutability of providers, but it is actually a good thing.
It helps avoid bugs and makes the application more predictable.

The typical usage for a provider is to provide a value for a specific page or widget.
When the page or widget is disposed, the provider gets also disposed, and the value is no longer available.
When the Page is opened again, a new instance of the provider is created, and the value is provided again.

### Force the recreation of a provider

There is one way to force the recreation of a provider, _which we discourage_, but can be used if you know what you are doing.

```dart {2}
ProviderScope(
key: ValueKey(counter),
providers: [
counterProvider(counter),
],
child: ..
)
```

When changing a key, the widget subtree gets regenerated.
The provider recreation is performed inside the `ProviderScope` widget. What exactly happens is the following:

1. The old `ProviderScope` is disposed, which disposes of all the providers inside it.
2. A new `ProviderScope` is created and all the providers are created again.
Loading