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
-
- Object
- DiagnosticableTree
- Widget
- StatefulWidget
- KoolbaseCollectionList
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