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
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 autofocus attribute on Flutter Web. Defaults to true when 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 null to fall back to SInkButton's own default (currently Colors.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