parse function

Tree parse(
  1. List<SandboxedElement> components
)

Implementation

Tree parse(List<SandboxedElement> components) {
  var root = Tree(
    children: [],
    parent: null,
    data: NodeData(
      const RootNode(
        id: 'root',
        title: 'Sandboxed',
        level: 0,
        index: 0,
        isExpanded: true,
      ),
    ),
  );

  String format(String identifier) {
    return identifier.replaceAll('.', '').replaceAll(' ', '-');
  }

  var nodes = <String, Tree>{};

  for (final component in components) {
    if (component is! Component) continue;
    switch (component) {
      case Component component:
        final parts = [
          ...?component.module?.split('/').map((e) => '[${e.trim()}]'),
          ...component.meta.name.split('/'),
        ].map((e) => e.trim()).toList();

        Tree parent = root;
        root.data.depth = max(root.data.depth, parts.length);

        for (final (index, part) in parts.indexed) {
          final id = format(parts.take(index + 1).join('/'));

          final wasProcessed = nodes.containsKey(id);
          var node = nodes.putIfAbsent(
            id,
            () {
              final level = index + 1;
              final childIndex = parent.children.length;

              if (part.startsWith('[') && part.endsWith(']')) {
                return Tree(
                  data: NodeData(
                    ModuleNode(
                      id: id,
                      title: part.replaceAll(RegExp(r'(^\[|\]$)'), '').trim(),
                      level: level,
                      index: childIndex,
                      isExpanded: true,
                    ),
                  ),
                  children: [],
                  parent: parent,
                );
              }

              return Tree(
                data: NodeData(
                  part == parts.last
                      ? ComponentNode(
                          id: id,
                          title: part.trim(),
                          level: level,
                          index: childIndex,
                          component: component,
                          isExpanded: true,
                        )
                      : FolderNode(
                          id: id,
                          title: part.trim(),
                          level: level,
                          index: childIndex,
                          isExpanded: true,
                        ),
                ),
                children: [],
                parent: parent,
              );
            },
          );

          if (!wasProcessed) {
            parent.children.add(node);
          }

          parent = node;
        }

        // Skip building stories for single story components.
        if (component.stories.length <= 1 &&
            component.meta.documentation.isEmpty == true) {
          continue;
        }

        for (final document in component.meta.documentation) {
          final name = document.name;
          var node = Tree(
            data: NodeData(
              DocumentationNode(
                id: [...parts, name.trim()].join('/'),
                component: component,
                title: name,
                level: parts.length + 1,
                index: parent.children.length,
                document: document,
              ),
            ),
            children: [],
            parent: parent,
          );

          parent.children.add(node);
        }

        for (final (index, story) in component.stories.indexed) {
          final name = story.name ?? 'Story $index';
          var node = Tree(
            data: NodeData(
              StoryNode(
                id: format([...parts, name.trim()].join('/')),
                component: component,
                story: story,
                title: name,
                level: parts.length + 1,
                index: parent.children.length,
              ),
            ),
            children: [],
            parent: parent,
          );

          parent.children.add(node);
        }
    }
  }

  sort(root);

  return root;
}