SSpreadsheet class
A reusable, spreadsheet-like 2D table composed of:
- a fixed top header row
- an optional fixed left row-header column
- vertically virtualized body rows (ListView.builder)
- synchronized horizontal scrolling for all rows and headers
This first engine intentionally mirrors the proven sync-scroll architecture used in heavy custom schedulers, while exposing reusable builders.
- Inheritance
-
- Object
- DiagnosticableTree
- Widget
- StatefulWidget
- SSpreadsheet
- Available extensions
Constructors
-
SSpreadsheet({Key? key, required int rowCount, required int columnCount, required SSpreadsheetCellBuilder cellBuilder, SSpreadsheetRowHeaderBuilder? rowHeaderBuilder, SSpreadsheetColumnHeaderBuilder? columnHeaderBuilder, WidgetBuilder? cornerBuilder, double rowHeaderWidth = 100, double headerHeight = 48, SSpreadsheetRowHeightBuilder? rowHeightBuilder, SSpreadsheetColumnWidthBuilder? columnWidthBuilder, EdgeInsetsGeometry padding = EdgeInsets.zero, EdgeInsetsGeometry rowPadding = EdgeInsets.zero, IndexedScrollController? verticalIndexedController, ScrollPhysics? verticalPhysics, ScrollPhysics? horizontalPhysics, Color? backgroundColor, bool showColumnHeader = true, SSpreadsheetHorizontalMetricsChanged? onHorizontalMetricsChanged, SSpreadsheetHorizontalSyncController? horizontalSyncController, bool repaintBoundaryPerRow = false, Duration rowExtentAnimationDuration = Duration.zero, bool addAutomaticKeepAlives = false, bool enableRowAnimations = true, Key rowKeyBuilder(int rowIndex)?, Duration rowAnimationDuration = const Duration(milliseconds: 400), SSpreadsheetSelectionController? selectionController, Object columnKeyBuilder(int columnIndex)?, double dimUnselectedOpacity = 1.0, Duration dimAnimationDuration = const Duration(milliseconds: 250), bool enableTapToSelectRowHeader = false, bool enableTapToSelectColumnHeader = false, Color? rowHeaderTapSplashColor = Colors.transparent, Color? columnHeaderTapSplashColor = Colors.transparent, void onRowHeaderSelected(int rowIndex, Object? key)?, void onColumnHeaderSelected(int rowIndex, Object? key)?, VoidCallback? onSelectionCleared, void onCellTap(int rowIndex, int columnIndex)?, bool enableKeystrokes = false, bool keystrokeDebugLogs = false, Map<
Type, VoidCallback> ? keystrokeActionHandlers, Map<Type, String> ? keystrokeActionLabels, Map<ShortcutActivator, Intent> ? keystrokeShortcuts, bool includeDefaultKeystrokeShortcuts = true, void onKeystrokeEvent(KeyDownEvent)?, FocusNode? keystrokeFocusNode, bool keystrokeRequestFocusOnInit = true, bool shouldPauseKeystrokes()?, SSpreadsheetKeystrokeHudBuilder? keystrokeHudBuilder, Duration keystrokeHudDuration = const Duration(seconds: 1)}) -
const
Properties
- addAutomaticKeepAlives → bool
-
Whether to keep body rows alive.
final
- backgroundColor → Color?
-
Optional background color behind the sheet.
final
- cellBuilder → SSpreadsheetCellBuilder
-
Builds each body cell.
final
- columnCount → int
-
Number of body columns (horizontally scrollable columns).
final
- columnHeaderBuilder → SSpreadsheetColumnHeaderBuilder?
-
Optional builder for the top fixed column-header cells.
final
- columnHeaderTapSplashColor → Color?
-
Splash/hover color for enableTapToSelectColumnHeader's tap target.
Mirrors rowHeaderTapSplashColor.
final
- columnKeyBuilder → Object Function(int columnIndex)?
-
Optional key builder that gives each column a stable identity for
selectionController. Mirrors rowKeyBuilder. If
null, the raw column index is used as the identity key.final - columnWidthBuilder → SSpreadsheetColumnWidthBuilder?
-
Width resolver for each body column.
final
- cornerBuilder → WidgetBuilder?
-
Optional builder for the top-left corner (intersection of row/column headers).
final
- dimAnimationDuration → Duration
-
Duration of the dim/undim opacity animation. Defaults to 250ms.
final
- dimUnselectedOpacity → double
-
Opacity applied (via AnimatedOpacity) to every header/cell that does
not belong to the selected row/column. Defaults to
1.0, which disables dimming entirely even when selectionController is set.final - enableKeystrokes → bool
-
When true, wraps the spreadsheet content in a KeystrokeListener so
that keyboard shortcuts are detected and dispatched to
keystrokeActionHandlers. Defaults to
false(backward compatible).final - enableRowAnimations → bool
-
Whether to animate rows when they are inserted or removed.
final
- enableTapToSelectColumnHeader → bool
-
When
true, tapping a column-header cell toggles that column's selection on selectionController. Mirrors enableTapToSelectRowHeader. Requires selectionController to be set.final - enableTapToSelectRowHeader → bool
-
When
true, tapping a row-header cell toggles that row's selection on selectionController. The tap target wraps whatever rowHeaderBuilder renders as its ancestor (translucent, so interactive elements inside the header — e.g. an icon button — still take priority for their own bounds). Requires selectionController to be set.final - hashCode → int
-
The hash code for this object.
no setterinherited
- headerHeight → double
-
Height of the top header row.
final
- horizontalPhysics → ScrollPhysics?
-
Horizontal row/header physics.
final
- horizontalSyncController → SSpreadsheetHorizontalSyncController?
-
Optional external horizontal sync controller that tracks shared
horizontal metrics and allows external scroll controls.
final
- includeDefaultKeystrokeShortcuts → bool
-
Whether the built-in navigation/editing shortcuts (ESC, Ctrl+S,
Ctrl+Z, etc.) should be registered. Defaults to
true.final - key → Key?
-
Controls how one widget replaces another widget in the tree.
finalinherited
-
keystrokeActionHandlers
→ Map<
Type, VoidCallback> ? -
Maps an Intent type to a callback that implements the action.
final
-
keystrokeActionLabels
→ Map<
Type, String> ? -
Maps an Intent type to a human-readable action label (e.g.
"New Dept Booking"). Used together with the auto-derived shortcut
label to populate the HUD overlay via keystrokeHudBuilder.
final
- keystrokeDebugLogs → bool
-
When true and enableKeystrokes is true, every detected keystroke is
printed via debugPrint. No action handlers fire in this mode.
final
- keystrokeFocusNode → FocusNode?
-
External FocusNode for the internal KeystrokeListener. When
provided, callers can call FocusNode.requestFocus externally to
re-acquire keystroke focus after overlays dismiss.
final
- keystrokeHudBuilder → SSpreadsheetKeystrokeHudBuilder?
-
Custom HUD widget builder. When provided, the HUD is shown
automatically before each keystrokeActionHandlers callback runs
(provided a label exists in keystrokeActionLabels).
final
- keystrokeHudDuration → Duration
-
How long the HUD overlay remains visible before auto-dismissing.
Defaults to 1 second.
final
- keystrokeRequestFocusOnInit → bool
-
When true, the internal KeystrokeListener requests autofocus on
init, giving the hidden TextField the HTML
autofocusattribute on Flutter Web. Defaults totruewhen enableKeystrokes is true.final -
keystrokeShortcuts
→ Map<
ShortcutActivator, Intent> ? -
Custom shortcut bindings scoped to this spreadsheet. Merged after
the built-in default shortcuts (unless includeDefaultKeystrokeShortcuts
is
false). Use this with custom Intent subclasses to detect key combinations not covered by the defaults.final - onCellTap → void Function(int rowIndex, int columnIndex)?
-
Optional callback fired when a body cell is tapped. Wraps the built
cell in a translucent GestureDetector so it doesn't interfere with
interactive widgets the cell itself renders (bookings, buttons, etc.).
final
- onColumnHeaderSelected → void Function(int rowIndex, Object? key)?
-
Called after a column header tap changes selectionController's
column selection. Mirrors onRowHeaderSelected. Only fires when
enableTapToSelectColumnHeader is true.
final
- onHorizontalMetricsChanged → SSpreadsheetHorizontalMetricsChanged?
-
Optional callback exposing synchronized horizontal scroll metrics.
final
- onKeystrokeEvent → void Function(KeyDownEvent)?
-
Raw KeyDownEvent callback for custom handling beyond the Intent
system. Fires for every key event that reaches the internal
KeystrokeListener.
final
- onRowHeaderSelected → void Function(int rowIndex, Object? key)?
-
Called after a row header tap changes selectionController's row
selection (including when it toggles the selection off, in which case
key is
null). Only fires when enableTapToSelectRowHeader is true.final - onSelectionCleared → VoidCallback?
-
Called whenever a tap outside the selected row/column clears
selectionController's selection (either axis).
final
- padding → EdgeInsetsGeometry
-
Padding applied around the whole spreadsheet.
final
- repaintBoundaryPerRow → bool
-
Whether to wrap each built body row in a RepaintBoundary.
final
- rowAnimationDuration → Duration
-
Duration of the insert/remove row animation.
Defaults to 400ms.
final
- rowCount → int
-
Number of body rows.
final
- rowExtentAnimationDuration → Duration
-
Optional animation duration for row height changes.
final
- rowHeaderBuilder → SSpreadsheetColumnHeaderBuilder?
-
Optional builder for the left fixed row-header cells.
final
- rowHeaderTapSplashColor → Color?
-
Splash/hover color for enableTapToSelectRowHeader's tap target.
Defaults to fully transparent (no visible feedback beyond the
dimming/selection state itself) to preserve prior behavior. Pass
nullto fall back toSInkButton's own default (currentlyColors.purple) for a visible ripple, or any other color to match your header's theme.final - rowHeaderWidth → double
-
Width of the fixed left row-header column.
final
- rowHeightBuilder → SSpreadsheetColumnWidthBuilder?
-
Height resolver for each body row.
final
- rowKeyBuilder → Key Function(int rowIndex)?
-
Optional key builder that gives each row a stable identity across rebuilds.
final
- rowPadding → EdgeInsetsGeometry
-
Padding applied inside each body row container.
final
- runtimeType → Type
-
A representation of the runtime type of the object.
no setterinherited
- selectionController → SSpreadsheetSelectionController?
-
Optional controller enabling row/column selection + dimming.
See SSpreadsheetSelectionController.
final
- shouldPauseKeystrokes → bool Function()?
-
When provided and returns
true, all keystroke intent handlers are suppressed and the auto-refocus is paused. Use this when descendant text inputs need exclusive keyboard access (e.g. a search bar inside the spreadsheet).final - showColumnHeader → bool
-
Whether to draw the top header row.
final
- verticalIndexedController → IndexedScrollController?
-
Optional IndexedScrollController for vertical (row) index-based scrolling.
final
- verticalPhysics → ScrollPhysics?
-
Vertical list physics.
final
Methods
-
addMaterialWidget(
) → Material -
Available on Widget, provided by the GenericExtensions extension
-
addTooltipWidget(
String toolTip) → Tooltip -
Available on Widget, provided by the GenericExtensions extension
-
borderRadius(
[BorderRadiusGeometry? borderRadius]) → Widget -
Available on Widget, provided by the GenericExtensions extension
-
boxDecoration(
[BoxDecoration? boxDecoration]) → Widget -
Available on Widget, provided by the GenericExtensions extension
-
colorFilter(
[ColorFilter? colorFilter]) → Widget -
Available on Widget, provided by the GenericExtensions extension
set parent widget in center -
createElement(
) → StatefulElement -
Creates a StatefulElement to manage this widget's location in the tree.
inherited
-
createState(
) → State< SSpreadsheet> -
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