Skip to content

Commit

Permalink
Minor documentation updates (slackhq#594)
Browse files Browse the repository at this point in the history
  • Loading branch information
kierse authored Apr 28, 2023
1 parent f30a55c commit 91a2f6a
Show file tree
Hide file tree
Showing 6 changed files with 19 additions and 23 deletions.
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
⚡️ Circuit
==========

🚧 **Under construction** 🚧

### [slackhq.github.io/circuit](https://slackhq.github.io/circuit)

License
Expand Down
20 changes: 9 additions & 11 deletions docs/index.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
⚡️ Circuit
==========

🚧 **Under construction** 🚧

This project is very much a work in progress and far from finished!
Circuit is used in production at Slack and ready for general use 🚀. The API is considered unstable as we continue to iterate on it.

## Overview

Expand All @@ -26,24 +24,24 @@ Circuit’s core components are its `Presenter` and `Ui` interfaces.
6. `Presenter` and `Ui` are both generic types, with generics to define the `UiState` types they communicate with.
7. They are keyed by `Screen`s. One runs a new `Presenter`/`Ui` pairing by requesting them with a given `Screen` that they understand.

!!! note "Circuits"
The pairing of a `Presenter` and `Ui` for a given `Screen` key is what we semantically call a “circuit”.
!!! note "Screens"
The pairing of a `Presenter` and `Ui` for a given `Screen` key is what we semantically call a “screen".

* Your application is composed of “circuits”.
* A simple counter `Presenter` + `Ui` pairing would be a “counter circuit”.
* Nested presenter/UIs would be “nested circuits” or “sub circuits”
* Composite presenter/UIs would be “composite circuits”
* Your application is composed of “screens".
* A simple counter `Presenter` + `Ui` pairing would be a “counter screen".
* Nested presenter/UIs would be “nested circuits” or “sub screen".
* Composite presenter/UIs would be “composite screen".
* etc etc.

Circuit’s repo (https://github.com/slackhq/circuit) is being actively developed in the open, which allows us to continue collaborating with external folks too. We have a trivial-but-not-too-trivial sample app that we have been developing in it to serve as a demo for a number of common patterns in Circuit use.

## Counter Example

This is a very simple case of a Counter circuit that displays the count and has buttons to increment and decrement.
This is a very simple case of a Counter screen that displays the count and has buttons to increment and decrement.

![image](https://user-images.githubusercontent.com/1361086/193662421-575dcaa9-4990-42e6-b265-9099a007296e.png)

There’s some glue code missing from this example that's covered in the Code Gen (TODO link) section later.
There’s some glue code missing from this example that's covered in the [Code Gen](https://slackhq.github.io/circuit/code-gen/) section later.

```kotlin
@Parcelize
Expand Down
4 changes: 2 additions & 2 deletions docs/presenter.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ interface Presenter<UiState : CircuitUiState> {
}
```

Presenters are solely intended to be business logic for your UI and a translation layer in front of your data layers. They are generally Dagger-injected types as the data layers they interpret are usually coming from the DI graph. In simple cases, they can be typed as a simple `@Composable` presenter function and Circuit code gen (TODO link) can generate the corresponding interface and (TODO link) factory for you.
Presenters are solely intended to be business logic for your UI and a translation layer in front of your data layers. They are generally Dagger-injected types as the data layers they interpret are usually coming from the DI graph. In simple cases, they can be typed as a simple `@Composable` presenter function allowing Circuit [code gen](https://slackhq.github.io/circuit/code-gen/) to generate the corresponding interface and factory for you.

A very simple presenter can look like this:

Expand Down Expand Up @@ -65,7 +65,7 @@ fun ProfilePresenter(
}
```

Presenters can present other presenters by injecting their assisted factories/providers, but note that this makes them a composite presenter that is now assuming responsibility for managing state of multiple nested presenters. [We have an example of this in the Circuit repo](https://github.com/slackhq/circuit/blob/main/samples/star/src/main/kotlin/com/slack/circuit/star/home/HomePresenter.kt).
Presenters can present other presenters by injecting their assisted factories/providers, but note that this makes them a composite presenter that is now assuming responsibility for managing state of multiple nested presenters.

## Retention

Expand Down
4 changes: 2 additions & 2 deletions docs/states-and-events.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ The core state and event interfaces in Circuit are `CircuitUiState` and `Circuit

Presenters are simple functions that determine and return composable states. UIs are simple functions that render states. Uis can emit events via `eventSink` properties in state classes, which presenters then handle. These are the core building blocks!

States and events should be immutable value types.
States should be `@Stable`; events should be `@Immutable`.

> Wait, event callbacks in state types?
Expand All @@ -22,6 +22,6 @@ Yep! This may feel like a departure from how you’ve written UDF patterns in th
Due to this [issue](https://issuetracker.google.com/issues/256100927), you need to extract the `eventSink` into local variables first.

!!! note
Currently, while functions are treated as implicitly `Stable` by the compose compiler, they not skippable when they're non-composable Unit-returning lambdas with equal-but-unstable captures. This may change though, and would be another free benefit for this case.
Currently, while functions are treated as implicitly `Stable` by the compose compiler, they're not skippable when they're non-composable Unit-returning lambdas with equal-but-unstable captures. This may change though, and would be another free benefit for this case.

A longer-form writeup can be found in [this PR](https://github.com/slackhq/circuit/pull/146).
10 changes: 6 additions & 4 deletions docs/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,24 +110,26 @@ fun `present - emit loading state then list of favorites`() = runTest {
val favorites = listOf(Favorite(1L, ...))

val repo = TestFavoritesRepository(favorites)
val presenter = PetListPresenter(navigator, repo)
val presenter = FavoritesPresenter(navigator, repo)

presenter.test {
assertThat(awaitItem()).isEqualTo(PetListScreen.State.Loading)
assertThat(awaitItem()).isEqualTo(FavoritesScreen.State.Loading)
val resultsItem = awaitItem() as Results
assertThat(resultsItem.favorites).isEqualTo(favorites)
}
}
```

The same helper can be used when testing how the presenter responds to incoming events:

```kotlin
@Test
fun `present - navigate to favorite screen`() = runTest {
val repo = TestFavoritesRepository(Favorite(123L))
val presenter = PetListPresenter(navigator, repo)
val presenter = FavoritesPresenter(navigator, repo)

presenter.test {
assertThat(awaitItem()).isEqualTo(PetListScreen.State.Loading)
assertThat(awaitItem()).isEqualTo(FavoritesScreen.State.Loading)
val resultsItem = awaitItem() as Results
assertThat(resultsItem.favorites).isEqualTo(favorites)
val clickFavorite = FavoriteScreen.Event.ClickFavorite(123L)
Expand Down
2 changes: 0 additions & 2 deletions docs/ui.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,3 @@ private fun PreviewFavorites() = Favorites(FavoritesState(listOf("Reeses", "Lola
@Composable
private fun PreviewEmptyFavorites() = Favorites(FavoritesState(listOf()))
```

TODO image sample of IDE preview

0 comments on commit 91a2f6a

Please sign in to comment.