KoolbaseCollectionList class

An opinionated list over a Koolbase collection.

NOT headless (unlike KoolbaseAuthGate): this component owns a ListView.separated inside a RefreshIndicator, because a scrollable, pull-to-refresh list is what nearly every collection screen is. What it owns about DATA lives in KoolbaseCollectionController, deliberately separable, so grid/sliver/custom-scroll variants can be added later without touching the fetch and stream lifecycle. Per-item appearance is entirely yours via itemBuilder; empty/error/loading are slotted.

KoolbaseCollectionList(
  collection: 'expenses',
  query: (q) => q
      .where('user_id', isEqualTo: KoolbaseAuthScope.of(context).user!.id)
      .orderBy('created_at', descending: true),
  itemBuilder: (context, record) => ExpenseTile(record),
)

The query callback runs for EVERY fetch and refresh with a fresh query instance, and must be deterministic — see KoolbaseQueryBuilder. For a scoped collection, filter on the rule's owner_field exactly as koolbase_describe_project reports it; the server enforces the rule either way, but the filter is what makes the query return the caller's records.

Inheritance

Constructors

KoolbaseCollectionList({Key? key, required String collection, required Widget itemBuilder(BuildContext context, KoolbaseRecord record), KoolbaseQueryBuilder? query, WidgetBuilder? empty, Widget error(BuildContext context, Object error, Future<void> retry())?, WidgetBuilder? loading, IndexedWidgetBuilder? separatorBuilder, EdgeInsetsGeometry? padding, @visibleForTesting KoolbaseCollectionController? controller, List<KoolbaseRecord> visible(List<KoolbaseRecord> loaded)?, bool scrollsWithPage = false, bool live = false, Axis scrollDirection = Axis.vertical, String groupBy(KoolbaseRecord record)?, Widget sectionHeaderBuilder(BuildContext context, String section)?})
const

Properties

collection → String
The collection to list.
final
controller → KoolbaseCollectionController?
Test seam only: inject a controller instead of constructing one.
final
empty → WidgetBuilder?
Shown when the load succeeded and there are no records.
final
error → Widget Function(BuildContext context, Object error, Future<void> retry())?
Shown when the FIRST load failed with nothing to show. Receives the error and a retry callback. Later refresh failures keep the records.
final
groupBy → String Function(KoolbaseRecord record)?
Sections: the key of the section a record belongs to, such as its day or its status. Each run of records with the same key gets one header above it, so sort the query by the same field: an unsorted list repeats a header wherever its key comes back. Records from Load more join the last section when they share its key. While the list scrolls by itself the current header stays pinned at the top until the next one pushes it away; with scrollsWithPage headers sit inline. Separators are drawn between rows of a section, never around a header. Vertical lists only.
final
hashCode → int
The hash code for this object.
no setterinherited
itemBuilder → Widget Function(BuildContext context, KoolbaseRecord record)
Builds one record's row. Appearance is entirely the caller's.
final
key → Key?
Controls how one widget replaces another widget in the tree.
finalinherited
live → bool
Keeps the list current with changes other people make: page one is re-read silently when realtime reports a change in collection. Needs a signed-in user. See KoolbaseCollectionController.live.
final
loading → WidgetBuilder?
Shown during the first load. Defaults to a centered spinner.
final
padding → EdgeInsetsGeometry?
Padding for the list. Defaults to none.
final
query → KoolbaseQueryBuilder?
Shapes each fresh query. Null lists the collection unfiltered.
final
runtimeType → Type
A representation of the runtime type of the object.
no setterinherited
scrollDirection → Axis
Which way the rows run. Axis.horizontal: side by side at their own width, each as tall as the tallest -- the list is as tall as its tallest row, so it needs no height, even in a scrolling page -- scrolling sideways. The next page loads as the end comes near, and Load more stays as the last item. The default separator is a VerticalDivider; scrollsWithPage and pull-to-refresh are vertical ideas and do not apply. Rows must be able to say their height (as a card, a column or a sized image can; a scrollable cannot).
final
scrollsWithPage → bool
For a list inside a scrolling page -- a screen whose body scrolls. The rows lay out at their natural height and the PAGE scrolls; Load more stays a row. Pull-to-refresh belongs to the page, so the list adds none. Without it, a list with records inside a scrolling column has no height to size to and throws ("Vertical viewport was given unbounded height"). Default false: the list fills a bounded space and scrolls by itself.
final
sectionHeaderBuilder → Widget Function(BuildContext context, String section)?
Builds a section's header from its key. Defaults to a KoolbaseSectionHeader showing the key. A pinned header must be opaque, or rows show through it.
final
separatorBuilder → IndexedWidgetBuilder?
Separator between rows. Defaults to a hairline Divider.
final
visible → List<KoolbaseRecord> Function(List<KoolbaseRecord> loaded)?
Transforms the loaded records before BOTH the empty decision and the rows, so a filter that leaves nothing shows the empty slot. Runs on every build over the records already loaded — it does not query. The Designer's search-on-list is built on this: a case-insensitive substring filter over the loaded page.
final

Methods

createElement() → StatefulElement
Creates a StatefulElement to manage this widget's location in the tree.
inherited
createState() → State<KoolbaseCollectionList>
Creates the mutable state for this widget at a given location in the tree.
override
debugDescribeChildren() → List<DiagnosticsNode>
Returns a list of DiagnosticsNode objects describing this node's children.
inherited
debugFillProperties(DiagnosticPropertiesBuilder properties) → void
Add additional properties associated with the node.
inherited
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
toDiagnosticsNode({String? name, DiagnosticsTreeStyle? style}) → DiagnosticsNode
Returns a debug representation of the object that is used by debugging tools and by DiagnosticsNode.toStringDeep.
inherited
toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) → String
A string representation of this object.
inherited
toStringDeep({String prefixLineOne = '', String? prefixOtherLines, DiagnosticLevel minLevel = DiagnosticLevel.debug, int wrapWidth = 65}) → String
Returns a string representation of this node and its descendants.
inherited
toStringShallow({String joiner = ', ', DiagnosticLevel minLevel = DiagnosticLevel.debug}) → String
Returns a one-line detailed description of the object.
inherited
toStringShort() → String
A short, textual description of this widget.
inherited

Operators

operator ==(Object other) → bool
The equality operator.
inherited