A group section spec is used to structure your data into a hierarchy of Sections, each responsible for rendering its own chunk of data.

Group section specs are classes annotated with @GroupSectionSpec. Implementing a GroupSectionSpec is very simple: you only need to write one method annotated with @OnCreateChildren. This method returns a tree of Sections that will have root in this GroupSectionSpec. The children can be Section instances created from other GroupSectionSpec classes or from DiffSectionSpec classes.

Let’s have a look at how you would declare a simple list that contains a header followed by a list of Strings. We’ll use a SingleComponentSection for the header and a DataDiffSection for the list of Strings and we’ll combine these in a hierarchy.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
@GroupSectionSpec
class FooSectionSpec {

  @OnCreateChildren
  static Children onCreateChildren(
      SectionContext c,
      @Prop String headerTitle,
      @Prop List<String> data) {
    return Children.create()
        .child(
            SingleComponentSection.create(c)
                .component(
                    Text.create(c)
                        .text(headerTitle)
                        .build()))
        .child(
            DataDiffSection.<String>create(c)
                .data(data)
                .renderEventHandler(FooSection.onRender(c)))
        .build();
  }

  @OnEvent(RenderEvent.class)
  static RenderInfo onRender(
      SectionContext c,
      @FromEvent String model) {
    return ComponentRenderInfo.create()
        .component(
            Text.create(c)
                .text(model)
                .build())
        .build();
    }
}

Imagine a surface that has multiple such subsections consisting of a header and list of Strings. An example could be a list of contacts grouped alphabetically, delimited by headers showing the first letter of the name. You can easily achieve that by creating a GroupSectionSpec that has a FooSection child for every letter.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@GroupSectionSpec
class BarSectionSpec {

  @OnCreateChildren
  static Children onCreateChildren(
      SectionContext c,
      @Prop List<String> data) {

      final Children.Builder builder = Children.create();

      for(char firstLetter = 'A'; firstLetter <= 'Z'; firstLetter++) {
          builder.child(FooSection.create(c)
              .key(String.valueOf(firstLetter))
              .headerTitle(String.valueOf(firstLetter))
              .data(getItemsForLetter(firstLetter, data)));
      }

      return build.build();
  }
}

Below is a representation of the tree of Sections that has the root in BarSection. Each node in the tree is a Section, and the leaves are Components that can be rendered on screen. Each one of the sections in the tree acts as a data source. Its responsibilities are to describe what data it needs and how that data should be rendered.

Edit on GitHub