Skip to content

Commit

Permalink
Added javadoc links
Browse files Browse the repository at this point in the history
Summary: more tweaks, javadocs and removed the widgets section

Reviewed By: passy

Differential Revision: D4883223

fbshipit-source-id: f19596268d4135fc9509d0061a0d3fed1b29a75f
  • Loading branch information
mihaelao authored and facebook-github-bot committed Apr 13, 2017
1 parent 1b85218 commit fc8b6a9
Show file tree
Hide file tree
Showing 28 changed files with 124 additions and 262 deletions.
10 changes: 0 additions & 10 deletions docs/_data/nav_docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,6 @@
items:
- id: debugging
- id: dev-options
- title: Widgets
items:
- id: widgets-card
- id: widgets-edittext
- id: widgets-horizontalscroll
- id: widgets-image
- id: widgets-progress
- id: widgets-recycler
- id: widgets-solidcolor
- id: widgets-text
- title: Contributing
items:
- id: contributing
Expand Down
4 changes: 2 additions & 2 deletions docs/_docs/accessibility.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ This is only applicable for components which mount drawables, since if the compo

## Extra accessibility nodes

On more complex mount specs that need to expose extra nodes to the accessibility framework, you'll have to implement three extra methods:
On more complex mount specs that need to expose extra nodes to the accessibility framework, you'll have to implement three extra methods with the following annotations:

- **GetExtraAccessibilityNodesCount**: Returns number of extra accessibility nodes exposed by the component.
- **OnPopulateExtraAccessibilityNode**: Populates the extra accessibility node with the given bounds.
Expand Down Expand Up @@ -96,7 +96,7 @@ Text.create(c)
.onInitializeAccessiblityNodeInfoHandler(MyComponent.onInitializeAccessibilityNodeInfoEvent(c))
```

One of the best features of `AccessibilityDelegate`s in general is their reusability even across different types of `View`s. This can also be achieved within the Components framework by creating a wrapper spec that takes in a component and adds the desired event handlers. For example, let's say we want to have a Component that appends "please" to every `AccessibilityEvent` that it announces.
One of the best features of `AccessibilityDelegate`s in general is their reusability even across different types of `View`s. This can also be achieved within Litho by creating a wrapper spec that takes in a component and adds the desired event handlers. For example, let's say we want to have a Component that appends "please" to every `AccessibilityEvent` that it announces.

```java
@LayoutSpec
Expand Down
4 changes: 2 additions & 2 deletions docs/_docs/best-practices.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class MyComponentSpec {

## Props vs State

Litho components have two types of data models: Props and State. It's important to understand the difference between the two to know when you need to use each of them.
Litho components have two types of data models: [Props](/docs/props) and [State](/docs/state). It's important to understand the difference between the two to know when you need to use each of them.

Props are for passing data down the tree from a component to its children. They are useful for defining the static part of a component's model, because props cannot be changed.

Expand All @@ -77,6 +77,6 @@ Let's take the example of a list of radio buttons, where you cannot have multipl

Components are esentially functions that receive data as parameters and are immutable. When the props or state of a component change, the framework will create a new component instance with the updated information, because the previous component cannot be mutated.

While the component itself is immutable, it is easy to make it not thread safe by using mutable objects for props and state. Litho computes layout on a background thread, and if the objects that make up a component's props or state are mutated from another thread, then this may result in rendering different outputs for the same component.
While the component itself is immutable, it is easy to make it not thread safe by using mutable objects for props and state. Litho computes [layout on a background thread](/docs/asynchronous-layout), and if the objects that make up a component's props or state are mutated from another thread, then this may result in rendering different outputs for the same component.

You must keep your props and state either as primitive types which are inherently immutable, or if that's not possible make sure that the objects that you are using are immutable.
6 changes: 3 additions & 3 deletions docs/_docs/codegen.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ layout: docs
permalink: /docs/codegen
---

As explained in [Writing Components](/docs/writing-components), Litho relies on code generation in order to create *Components* from *Component Specs*. This process utilises intermediate *ComponentSpec* representations called *SpecModels*, which are immutable java objects.
As explained in [Writing Components](/docs/writing-components), Litho relies on code generation in order to create *Components* from *Component Specs*. This process utilises intermediate *ComponentSpec* representations called [SpecModels](/javadoc/com/facebook/litho/specmodels/model/SpecModel), which are immutable java objects.

Code generation comprises three main steps:

Expand All @@ -14,12 +14,12 @@ Code generation comprises three main steps:
- Component generation from a given Spec Model.

#### Spec Model Creation
Spec models are created at compile time using an annotation processor, which is a tool in javac for scanning and processing annotations. The Components annotation processor will process the annotations, methods and fields on your Component Specs and create a Spec Model for each one.
Spec models are created at compile time using an annotation processor, which is a tool in javac for scanning and processing annotations. The Litho annotation processor will process the annotations, methods and fields on your Component Specs and create a Spec Model for each one.

In the future, we will add the ability to create Spec Models in other ways. For example, we want to be able to create Spec Models directly in Android Studio/Intellij, which would allow us to generate Components without having to build the source code.

#### Spec Model Validation
Spec Models have a method called `validate()`, which returns a list of `SpecModelValidationError`s. If this list is empty then the Spec is well-formed and may be used to generate a valid Component. If not, then it will contain a list of errors that need fixing up before a valid Component may be generated.
Spec Models have a method called `validate()`, which returns a list of [SpecModelValidationErrors](/javadoc/com/facebook/litho/specmodels/model/SpecModelValidationError). If this list is empty then the Spec is well-formed and may be used to generate a valid Component. If not, then it will contain a list of errors that need fixing up before a valid Component may be generated.

#### Component Generation
If the validation step on a Spec Model is successful, then the `generate` method may be called. This will create a [Javapoet](https://github.com/square/javapoet) `TypeSpec` which can then be easily used to create a Component class file.
Expand Down
4 changes: 2 additions & 2 deletions docs/_docs/custom-layout.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ permalink: /docs/custom-layout.html
---
Litho relies on [Yoga](https://facebook.github.io/yoga/), a powerful layout engine that is able to create very complex UIs, for layout calculations. However, there are few exceptions where Yoga is not enough and you may need to implement your own measuring and layout.

Litho provides a custom layout API for accessing size information while the [ComponentTree](link to javadoc) is being created and measured, as well as the possibility to measure a component in isolation.
Litho provides a custom layout API for accessing size information while the [ComponentTree](/javadoc/com/facebook/litho/ComponentTree) is being created and measured, as well as the possibility to measure a component in isolation.

> **IMPORTANT**: This API comes with a **non-negligible** performance overhead. Therefore, it is advisable to only use it when it is absolutely necessary.
Expand Down Expand Up @@ -51,7 +51,7 @@ In the following example, a `Text` component is measured to check if the given t

```java
@LayoutSpec
public class MyComponentSpec {
class MyComponentSpec {

@OnCreateLayoutWithSizeSpec
static ComponentLayout onCreateLayoutWithSizeSpec(
Expand Down
2 changes: 1 addition & 1 deletion docs/_docs/dev-options.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ permalink: /docs/developer-options
---
In addition to Stetho we also provide two compile time flags for visualizing the component hierarchy of your application. These are similar to Android's show view bounds internal setting but because Litho does not always use Android Views we have implemented our own to make it more helpful.

Within the `ComponentsConfiguration` class there are two fields which control this.
Within the [ComponentsConfiguration](/javadoc/com/facebook/litho/config/ComponentsConfiguration) class there are two fields which control this.

### debugHighlightInteractiveBounds
Highlight the interactive bounds of components as well as their expanded touch bounds, if present.
Expand Down
12 changes: 6 additions & 6 deletions docs/_docs/events-overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ layout: docs
permalink: /docs/events-overview
---

The framework provides a general-purpose API to connect components through events. Events are declared as a POJO with an `@Event` annotation. By convention we name suffix Event class names with *Event*. Event declarations may not be inner classes of your `LayoutSpec` or `MountSpec`. This is by design as specs are supposed to be a private concept and events can be used across multiple components.
The framework provides a general-purpose API to connect components through events. Events are declared as a POJO with an `@Event` annotation. By convention we suffix Event class names with *Event*. Event declarations may not be inner classes of your `LayoutSpec` or `MountSpec`. This is by design as specs are supposed to be a private concept and events can be used across multiple components.

```java
@Event
private class ColorChangedEvent {
public class ColorChangedEvent {
public int color;
}
```
Expand All @@ -18,7 +18,7 @@ In this example we will assume we have a component called `ColorComponent`. To i

```java
@LayoutSpec(events = { ColorChangedEvent.class })
public class ColorComponentSpec {
class ColorComponentSpec {
...
@OnCreateLayout
static ComponentLayout onCreateLayout(
Expand All @@ -36,7 +36,7 @@ public class ColorComponentSpec {

For an event of type `FooEvent`, this will auto-generate a matching `dispatchFooEvent` method and an event identifier that will used by event callbacks.

The `dispatchFooEvent` method takes an `EventHandler` as the first argument followed by the list of attributes defined in your `@Event` class. An `EventHandler` is essentially a generic listener interface to connect components through events. The convention is to have an `EventHandler` prop for each event exposed by your component.
The `dispatchFooEvent` method takes an [EventHandler](/javadoc/com/facebook/litho/EventHandler) as the first argument followed by the list of attributes defined in your `@Event` class. An `EventHandler` is essentially a generic listener interface to connect components through events. The convention is to have an `EventHandler` prop for each event exposed by your component.

In the example above, `ColorComponent` takes a `colorChangedHandler` as prop and dispatches the `ColorChangedEvent` to it with the generated `dispatchColorChangedEvent()` method.

Expand All @@ -52,7 +52,7 @@ For example, here's how a component would define a handler for the `ColorChanged

```java
@LayoutSpec
public class MyComponentSpec {
class MyComponentSpec {

@OnCreateLayout
static ComponentLayout onCreateLayout(
Expand Down Expand Up @@ -86,7 +86,7 @@ As you can see, `@OnEvent` callbacks have access to all component props just lik

```java
@LayoutSpec
public class FacePileComponentSpec {
class FacePileComponentSpec {

@OnCreateLayout
static ComponentLayout onCreateLayout(
Expand Down
33 changes: 23 additions & 10 deletions docs/_docs/events-touch-handling.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,34 @@ This means all layout builders have an `EventHandler` prop named `clickHandler`,
For example, setting a click handler on any component is as simple as:

```java
Text.create(c)
.text(title)
.withLayout()
.clickHandler(MyComponent.onClick(c))
@LayoutSpec
class MyComponentSpec {

@OnCreateLayout
static ComponentLayout onCreateLayout(
ComponentContext c,
@Prop String title) {
return Text.create(c)
.text(title)
.withLayout()
.clickHandler(MyComponent.onClick(c))
}
}
```

And the callback within MyComponentSpec would look like this:

```java
@OnEvent(ClickEvent.class)
static void onClick(
ComponentContext c,
@FromEvent View view,
@Prop String someProp) {
// Handle click here.
@LayoutSpec
class MyComponentSpec {
...
@OnEvent(ClickEvent.class)
static void onClick(
ComponentContext c,
@FromEvent View view,
@Prop String someProp) {
// Handle click here.
}
}
```

Expand Down
2 changes: 1 addition & 1 deletion docs/_docs/inc-mount.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ permalink: /docs/inc-mount

## Manual incremental mount

If you're not using `RecyclerComponent`, you can still integrate incremental mount in your existing UI implementation. You'll have to explicitly notify the framework every time the `ComponentView`'s visible region changes, by calling:
If you're not using the [Recycler](javadoc/com/facebook/litho/widget/Recycler) component, you can still integrate [incremental mount](/docs/intro#incremental-mount) in your existing UI implementation. You'll have to explicitly notify the framework every time the `ComponentView`'s visible region changes, by calling:

```java
myComponentView.performIncrementalMount();
Expand Down
16 changes: 8 additions & 8 deletions docs/_docs/layout-specs.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ permalink: /docs/layout-specs

A *layout spec* is the logical equivalent of a composite view on Android. It simply groups existing components together in an immutable layout tree.

Implementing a layout spec is very simple: you only need to write one method annotated with `@OnCreateLayout` which returns an immutable tree of `ComponentLayout` objects.
Implementing a layout spec is very simple: you only need to write one method annotated with `@OnCreateLayout` which returns an immutable tree of [ComponentLayout](/javadoc/com/facebook/litho/ComponentLayout) objects.

Let's start with a simple example:

Expand All @@ -17,14 +17,14 @@ public class MyComponentSpec {
@OnCreateLayout
static ComponentLayout onCreateLayout(
ComponentContext c,
@Prop Uri imageUri,
@Prop int color,
@Prop String title) {

return Row.create(c)
.alignItems(CENTER)
.child(
FrescoComponent.create(c)
.uri(imageUri)
SolidColor.create(c)
.colorRes(color)
.withLayout()
.widthDip(40)
.heightDip(40))
Expand All @@ -41,21 +41,21 @@ public class MyComponentSpec {

As you can see, layout spec classes use the `@LayoutSpec` annotation.

The method annotated with `@OnCreateLayout` must have `ComponentContext` as its first argument followed by a list of arguments annotated with `@Prop`. The annotation processor will validate this and other invariants in the API at build time.
The method annotated with `@OnCreateLayout` must have [ComponentContext](/javadoc/com/facebook/litho/ComponentContext) as its first argument followed by a list of arguments annotated with `@Prop`. The annotation processor will validate this and other invariants in the API at build time.

In the example above, the layout tree has a root *Container* with two children stacked horizontally (`Row.create`) and vertically centered (`Align.CENTER`).

The first child is a `FrescoImage` component that takes an `uri` prop and has a 40dp width and height.
The first child is a [SolidColor](/javadoc/com/facebook/litho/widget/SolidColor) component that takes a `colorRes` prop and has a 40dp width and height.

```java
DraweeComponent.create(c)
SolidColor.create(c)
.uri(imageUri)
.withLayout()
.width(40)
.height(40)
```

The second child is a `Text` component that takes a prop named `text` and fills the remaining horizontal space available in `MyComponent` by using `grow(1f)` (equivalent to Android's `layoutWeight` from `LinearLayout`). The text size is defined in `my_text_size` dimension resource.
The second child is a [Text](/javadoc/com/facebook/litho/widget/Text) component that takes a prop named `text` and fills the remaining horizontal space available in `MyComponent` by using `grow(1f)` (equivalent to Android's `layoutWeight` from `LinearLayout`). The text size is defined in `my_text_size` dimension resource.

```java
Text.create(c)
Expand Down
17 changes: 9 additions & 8 deletions docs/_docs/mount-specs.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,20 +129,21 @@ Just like `@OnPrepare`, the `@OnMeasure` method can also generate inter-stage ou

## ShouldUpdate

A MountSpec can define a method annotated with `@ShouldUpdate` to avoid remeasuring/remounting upon updates.
Invocations of `@ShouldUpdate` are dependent on whether a Component is a pure render function.
A Component is a pure render function if the result of the rendering only depends on its props and states. This means that the Component shouldn't be accessing any mutable global variable during `@OnMount`.
A MountSpec can define a method annotated with `@ShouldUpdate` to avoid remeasuring and remounting upon updates.
Invocations of `@ShouldUpdate` are dependent on whether a Component is a **pure render function**. A Component is a pure render function if the result of the rendering only depends on its props and states. This means that the Component shouldn't be accessing any mutable global variable during `@OnMount`.
A `@MountSpec` can be defined as pure render by using the pureRender parameter of the `@MountSpec` annotation.
Only pureRender Components can assume that when props do not change remounting won't be needed. A `@ShouldUpdate` function can be defined as follows:
Only pure render Components can assume that when props do not change remounting won't be needed. A `@ShouldUpdate` function can be defined as follows:

``` java
@ShouldUpdate(onMount = true)
public boolean shouldUpdate(Diff<String> someStringProp) {
return !someStringProp.getPrevious().equals(someStringProp.getNext());
}
```
The parameters taken from shouldUpdate are Diff of Props or State. A Diff is an object containing the value of a `@Prop` or a `@State` in the old components hierarchy and the value of the same `@Prop`/`@State` in the new components hierarchy.
In this example this component was defining a `@Prop` String someStringProp. ShouldUpdate will receive a Diff<String> to be able to compare the old and new value of this `@Prop`. `@ShouldUpdate` has to take into consideration any prop and any state that are used at OnMount time. It can safely ignore `@Prop`/`@State` that are only used at OnBind/OnUnbind time as these two methods will be executed regardless.
The parameters taken from `shouldUpdate` are [Diffs](/javadoc/com/facebook/litho/Diff) of Props or State. A Diff is an object containing the value of a `@Prop` or a `@State` in the old components hierarchy and the value of the same `@Prop`or `@State` in the new components hierarchy.
In this example this component was defining **someStringProp** as a String `@Prop`. `shouldUpdate` will receive a `Diff<String>` to be able to compare the old and new value of this `@Prop`.
`shouldUpdate` has to take into consideration any prop and any states that are used at `@OnMount` time. It can safely ignore props and states that are only used at '@OnMount/@OnUnbind` time as these two methods will be executed regardless.

The onMount attribute on the `@ShouldUpdate` annotation controls whether this shouldUpdate check can happen at mount time. By default Components will try to do this reconciliation at layout time but if layout diffing is turned off it might be useful to set onMount to true in order to execute this check at mount time instead. The onMount attribute is set to false by default as the equality check might be heavy itself and make mount performances worse.
The `onMount` attribute on the `@ShouldUpdate` annotation controls whether this `shouldUpdate` check can happen at mount time. By default, Litho will try to do this reconciliation at layout time, but if layout diffing is turned off it might be useful to set onMount to true in order to execute this check at mount time instead. The `onMount` attribute is set to false by default as the equality check might be heavy itself and make mount performances worse.

`@ShouldUpdate` is currently only supported in `@MountSpec`. We have plans to expand the support to complex layouts in the future but at the moment a `@ShouldUpdate` annotated method in a `@LayoutSpec` would have no effect.
`@ShouldUpdate` annotated methods are currently only supported in `@MountSpec`. We have plans to expand the support to complex layouts in the future but at the moment a `@ShouldUpdate` annotated method in a `@LayoutSpec` would have no effect.
Loading

0 comments on commit fc8b6a9

Please sign in to comment.