liqkit_ui
Navigation

Tree View

Cross-platform extension. iOS 26 navigates hierarchies with drill-down (and split-view sidebars on iPad), not in-place collapsing tree rows — the system has no native equivalent. The closest references are shadcn/ui and forui.dev. liqkit_ui ships this rendered in iOS 26 visual language (Liquid Glass surfaces, San Francisco type, iOS color palette) so it composes cleanly with the rest of the library, but the interaction model itself is web-native rather than iOS-canonical.

LiqTreeView is the iOS 26 hierarchical list — a column of indented rows with collapsible folders. Distinct from LiqAccordion (flat top-level expand/collapse panels), the tree supports arbitrarily nested children and is the right primitive for a file-explorer pane, a document outline, or an org chart.

The widget owns its expansion state internally — pass initialExpanded to seed which folder ids are open on first paint. Selection is owned by the consumer: pass selectedId to highlight a row and listen to onSelected to update it. Tapping a folder row toggles expansion and does not fire onSelected; that callback fires only for leaves.

Files

// ignore_for_file: file_names // hyphenated name required by snippet manifest conventionimport 'package:docs_snippets/src/demo.dart';import 'package:docs_snippets/src/snippet_frame.dart';import 'package:flutter/material.dart';import 'package:liqkit_ui/liqkit_ui.dart';/// Snippet builder consumed by `apps/docs_snippets/lib/src/routes.g.dart`.Widget treeViewFilesBuilder(BuildContext context) {  return SnippetFrame(    child: LiqDemo<String?>(      initial: null,      builder:          (sel, set) =>          LiqTreeView<String>(            selectedId: sel,            onSelected: (id, _) => set(id),            initialExpanded: const <String>{'src', 'src/components'},            nodes: const <LiqTreeNode<String>>[              LiqTreeNode<String>(                id: 'src',                label: 'src',                icon: Icons.folder_outlined,                children: <LiqTreeNode<dynamic>>[                  LiqTreeNode<String>(                    id: 'src/main.dart',                    label: 'main.dart',                    icon: Icons.description_outlined,                  ),                  LiqTreeNode<String>(                    id: 'src/components',                    label: 'components',                    icon: Icons.folder_outlined,                    children: <LiqTreeNode<dynamic>>[                      LiqTreeNode<String>(                        id: 'src/components/button.dart',                        label: 'button.dart',                        icon: Icons.description_outlined,                      ),                      LiqTreeNode<String>(                        id: 'src/components/toggle.dart',                        label: 'toggle.dart',                        icon: Icons.description_outlined,                      ),                    ],                  ),                ],              ),              LiqTreeNode<String>(                id: 'pubspec.yaml',                label: 'pubspec.yaml',                icon: Icons.description_outlined,              ),            ],          ),    ),  );}

Outline

// ignore_for_file: file_names // hyphenated name required by snippet manifest conventionimport 'package:docs_snippets/src/demo.dart';import 'package:docs_snippets/src/snippet_frame.dart';import 'package:flutter/widgets.dart';import 'package:liqkit_ui/liqkit_ui.dart';/// Snippet builder consumed by `apps/docs_snippets/lib/src/routes.g.dart`.Widget treeViewOutlineBuilder(BuildContext context) {  return SnippetFrame(    child: LiqDemo<String?>(      initial: 'ch1/intro',      builder:          (sel, set) =>          LiqTreeView<String>(            selectedId: sel,            onSelected: (id, _) => set(id),            initialExpanded: const <String>{'ch1', 'ch2', 'ch3'},            nodes: const <LiqTreeNode<String>>[              LiqTreeNode<String>(                id: 'ch1',                label: '1. Introduction',                children: <LiqTreeNode<dynamic>>[                  LiqTreeNode<String>(id: 'ch1/intro', label: '1.1 Overview'),                  LiqTreeNode<String>(id: 'ch1/scope', label: '1.2 Scope'),                ],              ),              LiqTreeNode<String>(                id: 'ch2',                label: '2. Foundations',                children: <LiqTreeNode<dynamic>>[                  LiqTreeNode<String>(id: 'ch2/colors', label: '2.1 Colors'),                  LiqTreeNode<String>(                    id: 'ch2/typography',                    label: '2.2 Typography',                  ),                  LiqTreeNode<String>(id: 'ch2/spacing', label: '2.3 Spacing'),                ],              ),              LiqTreeNode<String>(                id: 'ch3',                label: '3. Components',                children: <LiqTreeNode<dynamic>>[                  LiqTreeNode<String>(id: 'ch3/buttons', label: '3.1 Buttons'),                  LiqTreeNode<String>(id: 'ch3/forms', label: '3.2 Forms'),                ],              ),            ],          ),    ),  );}

On this page