diff --git a/CHANGELOG.md b/CHANGELOG.md index fb56e0e..0c7fc53 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,27 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## 2025-01-30 + +### Changes + +--- + +Packages with breaking changes: + + - There are no breaking changes in this release. + +Packages with other changes: + + - [`tagflow_table` - `v0.0.3-dev.0`](#tagflow_table---v003-dev0) + +--- + +#### `tagflow_table` - `v0.0.3-dev.0` + + - **FEAT**(tagflow_table): add column and row spacing properties to TagflowTable. ([66989cf5](https://github.com/devaryakjha/tagflow/commit/66989cf5e67805c2b472dcfccd9bed84158fdf8d)) + + ## 2025-01-30 ### Changes diff --git a/examples/tagflow/pubspec.yaml b/examples/tagflow/pubspec.yaml index 4689aef..f29d744 100644 --- a/examples/tagflow/pubspec.yaml +++ b/examples/tagflow/pubspec.yaml @@ -13,7 +13,7 @@ dependencies: go_router: ^14.6.2 google_fonts: ^6.2.1 tagflow: ^0.0.1-dev.0+1 - tagflow_table: ^0.0.2-dev.0+1 + tagflow_table: ^0.0.3-dev.0 url_launcher: ^6.3.1 dev_dependencies: diff --git a/packages/tagflow_table/CHANGELOG.md b/packages/tagflow_table/CHANGELOG.md index e7c979b..3fb849d 100644 --- a/packages/tagflow_table/CHANGELOG.md +++ b/packages/tagflow_table/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.3-dev.0 + + - **FEAT**(tagflow_table): add column and row spacing properties to TagflowTable. ([66989cf5](https://github.com/devaryakjha/tagflow/commit/66989cf5e67805c2b472dcfccd9bed84158fdf8d)) + ## 0.0.2+1 - Graduate package to a stable release. See pre-releases prior to this version for changelog entries. diff --git a/packages/tagflow_table/lib/src/rendering/tagflow_table.dart b/packages/tagflow_table/lib/src/rendering/tagflow_table.dart index c85033b..099f662 100644 --- a/packages/tagflow_table/lib/src/rendering/tagflow_table.dart +++ b/packages/tagflow_table/lib/src/rendering/tagflow_table.dart @@ -336,6 +336,10 @@ class RenderTagflowTable extends RenderBox Color? _headerBackgroundColor; EdgeInsets _padding = EdgeInsets.zero; IndexedWidgetBuilder? _separatorBuilder; + double _columnSpacing = 0; + double _rowSpacing = 0; + + static const double _minimumColumnWidth = 40; // Adjust as needed void setSeparatorBuilder(IndexedWidgetBuilder? value) { if (_separatorBuilder == value) return; @@ -378,6 +382,18 @@ class RenderTagflowTable extends RenderBox markNeedsPaint(); } + void setColumnSpacing(double value) { + if (_columnSpacing == value) return; + _columnSpacing = value; + markNeedsLayout(); + } + + void setRowSpacing(double value) { + if (_rowSpacing == value) return; + _rowSpacing = value; + markNeedsLayout(); + } + @override void setupParentData(RenderBox child) { if (child.parentData is! TableCellData) { @@ -392,6 +408,12 @@ class RenderTagflowTable extends RenderBox return; } + // Calculate total spacing needed between columns + final totalColumnSpacing = (_columnCount - 1) * _columnSpacing; + + // Calculate available width for columns after accounting for spacing and padding + final availableWidth = constraints.maxWidth - totalColumnSpacing - _padding.horizontal; + // First pass: Calculate minimum and preferred column widths _columnWidths = List.filled(_columnCount, 0); final columnFlexibility = List.filled(_columnCount, 0); @@ -407,39 +429,47 @@ class RenderTagflowTable extends RenderBox // Update minimum widths for (var i = 0; i < childParentData.colSpan; i++) { final colIndex = childParentData.column + i; - _columnWidths[colIndex] = - _columnWidths[colIndex].clamp(widthPerColumn, double.infinity); - + _columnWidths[colIndex] = math.max(_columnWidths[colIndex], widthPerColumn); + // Track how flexible each column is based on content final flexibility = (maxWidth - minWidth) / childParentData.colSpan; - columnFlexibility[colIndex] = - math.max(columnFlexibility[colIndex], flexibility); + columnFlexibility[colIndex] = math.max(columnFlexibility[colIndex], flexibility); } } child = childParentData.nextSibling; } - // Calculate total minimum width and distribute extra space - final totalMinWidth = - _columnWidths.reduce((a, b) => a + b) + _padding.horizontal; - final extraWidth = - (constraints.maxWidth - totalMinWidth).clamp(0.0, double.infinity); - - if (extraWidth > 0) { - // Calculate total flexibility + // Calculate total current width and adjust if needed + final totalColumnWidth = _columnWidths.reduce((a, b) => a + b); + + if (totalColumnWidth > availableWidth) { + // Need to shrink columns - distribute reduction proportionally + final reduction = totalColumnWidth - availableWidth; + + // Calculate shrink factors based on current widths + final totalWidth = _columnWidths.reduce((a, b) => a + b); + for (var i = 0; i < _columnCount; i++) { + final proportion = _columnWidths[i] / totalWidth; + _columnWidths[i] = math.max( + _minimumColumnWidth, + _columnWidths[i] - (reduction * proportion), + ); + } + } else if (totalColumnWidth < availableWidth) { + // Extra space available - distribute using flexibility + final extraWidth = availableWidth - totalColumnWidth; final totalFlexibility = columnFlexibility.reduce((a, b) => a + b); if (totalFlexibility > 0) { - // Distribute extra space proportionally to column flexibility for (var i = 0; i < _columnCount; i++) { final proportion = columnFlexibility[i] / totalFlexibility; _columnWidths[i] += extraWidth * proportion; } } else { - // If no flexible columns found, distribute evenly - final widthPerColumn = extraWidth / _columnCount; + // If no flexible columns, distribute evenly + final extraPerColumn = extraWidth / _columnCount; for (var i = 0; i < _columnCount; i++) { - _columnWidths[i] += widthPerColumn; + _columnWidths[i] += extraPerColumn; } } } @@ -489,26 +519,32 @@ class RenderTagflowTable extends RenderBox } childParentData.offset = Offset(0, y); } else { - // Calculate cell width and height + // Calculate cell width and height including spacing var width = 0.0; for (var i = 0; i < childParentData.colSpan; i++) { width += _columnWidths[childParentData.column + i]; + if (i < childParentData.colSpan - 1) { + width += _columnSpacing; + } } var height = 0.0; for (var i = 0; i < childParentData.rowSpan; i++) { height += _rowHeights[childParentData.row + i]; + if (i < childParentData.rowSpan - 1) { + height += _rowSpacing; + } } - // Calculate cell position + // Calculate cell position with spacing var x = _padding.left; for (var i = 0; i < childParentData.column; i++) { - x += _columnWidths[i]; + x += _columnWidths[i] + _columnSpacing; } var y = _padding.top; for (var i = 0; i < childParentData.row; i++) { - y += _rowHeights[i]; + y += _rowHeights[i] + _rowSpacing; } // Layout child with tight constraints to prevent overflow @@ -519,13 +555,15 @@ class RenderTagflowTable extends RenderBox child = childParentData.nextSibling; } - // Set table size - size = constraints.constrain( - Size( - _columnWidths.reduce((a, b) => a + b) + _padding.horizontal, - _rowHeights.reduce((a, b) => a + b) + _padding.vertical, - ), - ); + // Update final table size to include spacing + final tableWidth = _columnWidths.reduce((a, b) => a + b) + + (_columnCount - 1) * _columnSpacing + + _padding.horizontal; + final tableHeight = _rowHeights.reduce((a, b) => a + b) + + (_rowCount - 1) * _rowSpacing + + _padding.vertical; + + size = constraints.constrain(Size(tableWidth, tableHeight)); } @override @@ -753,6 +791,7 @@ class RenderTagflowTable extends RenderBox rowHeights[childParentData.row + i] .clamp(childHeight, double.infinity); } + child = childParentData.nextSibling; } child = childParentData.nextSibling; } diff --git a/packages/tagflow_table/lib/src/widgets/converter.dart b/packages/tagflow_table/lib/src/widgets/converter.dart index 04a3455..0e836e8 100644 --- a/packages/tagflow_table/lib/src/widgets/converter.dart +++ b/packages/tagflow_table/lib/src/widgets/converter.dart @@ -30,6 +30,8 @@ final class TagflowTableConverter this.headerBackgroundColor, this.treatFirstRowAsHeader = false, this.separatorBuilder, + this.columnSpacing, + this.rowSpacing, }); /// The background color of the header row. @@ -47,6 +49,11 @@ final class TagflowTableConverter /// The separator is placed between each row. final material.IndexedWidgetBuilder? separatorBuilder; + final double? columnSpacing; + + /// + final double? rowSpacing; + @override Set get supportedTags => {'table'}; @@ -171,6 +178,8 @@ final class TagflowTableConverter headerBackgroundColor: headerBackgroundColor, padding: style.padding ?? material.EdgeInsets.zero, separatorBuilder: separatorBuilder, + columnSpacing: columnSpacing ?? 0, + rowSpacing: rowSpacing ?? 0, children: cells, ), ); diff --git a/packages/tagflow_table/lib/src/widgets/tagflow_table.dart b/packages/tagflow_table/lib/src/widgets/tagflow_table.dart index 1116fe9..fe2f0d0 100644 --- a/packages/tagflow_table/lib/src/widgets/tagflow_table.dart +++ b/packages/tagflow_table/lib/src/widgets/tagflow_table.dart @@ -72,6 +72,8 @@ final class TagflowTable extends MultiChildRenderObjectWidget { this.headerBackgroundColor, this.padding = EdgeInsets.zero, this.separatorBuilder, + this.columnSpacing = 0.0, // Add this + this.rowSpacing = 0.0, // Add this }) : border = border ?? TagflowTableBorder.none, super(children: children); @@ -82,6 +84,8 @@ final class TagflowTable extends MultiChildRenderObjectWidget { final Color? headerBackgroundColor; final EdgeInsets padding; final IndexedWidgetBuilder? separatorBuilder; + final double columnSpacing; + final double rowSpacing; @override RenderTagflowTable createRenderObject(BuildContext context) { @@ -91,7 +95,9 @@ final class TagflowTable extends MultiChildRenderObjectWidget { ..setTreatFirstRowAsHeader(value: treatFirstRowAsHeader) ..setHeaderBackgroundColor(headerBackgroundColor) ..setSeparatorBuilder(separatorBuilder) - ..setPadding(padding); + ..setPadding(padding) + ..setColumnSpacing(columnSpacing) // Add this + ..setRowSpacing(rowSpacing); // Add this } @override @@ -105,7 +111,9 @@ final class TagflowTable extends MultiChildRenderObjectWidget { ..setTreatFirstRowAsHeader(value: treatFirstRowAsHeader) ..setHeaderBackgroundColor(headerBackgroundColor) ..setSeparatorBuilder(separatorBuilder) - ..setPadding(padding); + ..setPadding(padding) + ..setColumnSpacing(columnSpacing) // Add this + ..setRowSpacing(rowSpacing); // Add this } @override @@ -128,6 +136,8 @@ final class TagflowTable extends MultiChildRenderObjectWidget { headerBackgroundColor, ), ) - ..add(DiagnosticsProperty('padding', padding)); + ..add(DiagnosticsProperty('padding', padding)) + ..add(DoubleProperty('columnSpacing', columnSpacing)) + ..add(DoubleProperty('rowSpacing', rowSpacing)); } } diff --git a/packages/tagflow_table/pubspec.yaml b/packages/tagflow_table/pubspec.yaml index cdabb54..79a6ef7 100644 --- a/packages/tagflow_table/pubspec.yaml +++ b/packages/tagflow_table/pubspec.yaml @@ -1,6 +1,6 @@ name: tagflow_table description: A pluggable package for tagflow to add support for advanced HTML tables. -version: 0.0.2+1 +version: 0.0.3-dev.0 repository: https://github.com/devaryakjha/tagflow homepage: https://docs.arya.run/tagflow issue_tracker: https://github.com/devaryakjha/tagflow/issues