Skip to content

Commit f7807a0

Browse files
committed
clip content to not cover header/footer
1 parent 82c95b5 commit f7807a0

8 files changed

Lines changed: 141 additions & 54 deletions

File tree

data-table-material3/src/commonMain/kotlin/com/seanproctor/datatable/material3/DataTable.kt

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,16 @@ package com.seanproctor.datatable.material3
1818

1919
import androidx.compose.foundation.layout.PaddingValues
2020
import androidx.compose.material3.HorizontalDivider
21-
import androidx.compose.material3.MaterialTheme
2221
import androidx.compose.runtime.Composable
2322
import androidx.compose.ui.Modifier
2423
import androidx.compose.ui.graphics.Color
2524
import androidx.compose.ui.unit.Dp
2625
import androidx.compose.ui.unit.dp
27-
import com.seanproctor.datatable.*
26+
import com.seanproctor.datatable.BasicDataTable
27+
import com.seanproctor.datatable.DataColumn
28+
import com.seanproctor.datatable.DataTableScope
29+
import com.seanproctor.datatable.DataTableState
30+
import com.seanproctor.datatable.rememberDataTableState
2831

2932
/**
3033
* Layout model that arranges its children into rows and columns.
@@ -38,9 +41,8 @@ fun DataTable(
3841
headerHeight: Dp = 56.dp,
3942
rowHeight: Dp = 52.dp,
4043
contentPadding: PaddingValues = PaddingValues(horizontal = 16.dp),
41-
headerBackgroundColor: Color = MaterialTheme.colorScheme.surface,
42-
footerBackgroundColor: Color = MaterialTheme.colorScheme.surface,
43-
rowBackgroundColor: @Composable (Int) -> Color = { MaterialTheme.colorScheme.surface },
44+
headerBackgroundColor: Color = Color.Unspecified,
45+
footerBackgroundColor: Color = Color.Unspecified,
4446
footer: @Composable () -> Unit = { },
4547
sortColumnIndex: Int? = null,
4648
sortAscending: Boolean = true,
@@ -57,7 +59,6 @@ fun DataTable(
5759
contentPadding = contentPadding,
5860
headerBackgroundColor = headerBackgroundColor,
5961
footerBackgroundColor = footerBackgroundColor,
60-
rowBackgroundColor = rowBackgroundColor,
6162
footer = footer,
6263
cellContentProvider = Material3CellContentProvider,
6364
sortColumnIndex = sortColumnIndex,

data-table-material3/src/commonMain/kotlin/com/seanproctor/datatable/material3/LazyPaginatedDataTable.kt

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,21 @@
11
package com.seanproctor.datatable.material3
22

3-
import androidx.compose.foundation.layout.*
3+
import androidx.compose.foundation.layout.Arrangement
4+
import androidx.compose.foundation.layout.PaddingValues
5+
import androidx.compose.foundation.layout.Row
6+
import androidx.compose.foundation.layout.fillMaxWidth
7+
import androidx.compose.foundation.layout.height
8+
import androidx.compose.foundation.layout.padding
49
import androidx.compose.material.icons.Icons
510
import androidx.compose.material.icons.automirrored.filled.LastPage
611
import androidx.compose.material.icons.filled.ChevronLeft
712
import androidx.compose.material.icons.filled.ChevronRight
813
import androidx.compose.material.icons.filled.FirstPage
9-
import androidx.compose.material3.*
14+
import androidx.compose.material3.HorizontalDivider
15+
import androidx.compose.material3.Icon
16+
import androidx.compose.material3.IconButton
17+
import androidx.compose.material3.MaterialTheme
18+
import androidx.compose.material3.Text
1019
import androidx.compose.runtime.Composable
1120
import androidx.compose.runtime.remember
1221
import androidx.compose.ui.Alignment
@@ -48,7 +57,6 @@ fun LazyPaginatedDataTable(
4857
contentPadding = contentPadding,
4958
headerBackgroundColor = headerBackgroundColor,
5059
footerBackgroundColor = footerBackgroundColor,
51-
rowBackgroundColor = rowBackgroundColor,
5260
footer = {
5361
Row(
5462
modifier = Modifier.height(rowHeight).padding(horizontal = 16.dp).fillMaxWidth(),
@@ -92,4 +100,4 @@ fun LazyPaginatedDataTable(
92100
) {
93101
fetchPage(state)
94102
}
95-
}
103+
}

data-table-material3/src/commonMain/kotlin/com/seanproctor/datatable/material3/PaginatedDataTable.kt

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,21 @@
11
package com.seanproctor.datatable.material3
22

3-
import androidx.compose.foundation.layout.*
3+
import androidx.compose.foundation.layout.Arrangement
4+
import androidx.compose.foundation.layout.PaddingValues
5+
import androidx.compose.foundation.layout.Row
6+
import androidx.compose.foundation.layout.fillMaxWidth
7+
import androidx.compose.foundation.layout.height
8+
import androidx.compose.foundation.layout.padding
49
import androidx.compose.material.icons.Icons
510
import androidx.compose.material.icons.automirrored.filled.LastPage
611
import androidx.compose.material.icons.filled.ChevronLeft
712
import androidx.compose.material.icons.filled.ChevronRight
813
import androidx.compose.material.icons.filled.FirstPage
9-
import androidx.compose.material3.*
14+
import androidx.compose.material3.HorizontalDivider
15+
import androidx.compose.material3.Icon
16+
import androidx.compose.material3.IconButton
17+
import androidx.compose.material3.MaterialTheme
18+
import androidx.compose.material3.Text
1019
import androidx.compose.runtime.Composable
1120
import androidx.compose.ui.Alignment
1221
import androidx.compose.ui.Modifier
@@ -45,7 +54,6 @@ fun PaginatedDataTable(
4554
contentPadding = contentPadding,
4655
headerBackgroundColor = headerBackgroundColor,
4756
footerBackgroundColor = footerBackgroundColor,
48-
rowBackgroundColor = rowBackgroundColor,
4957
state = state,
5058
footer = {
5159
Row(
@@ -89,4 +97,4 @@ fun PaginatedDataTable(
8997
logger = logger,
9098
content = content
9199
)
92-
}
100+
}

data-table/src/commonMain/kotlin/com/seanproctor/datatable/BasicDataTable.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ fun BasicDataTable(
5959
contentPadding: PaddingValues = PaddingValues(horizontal = 16.dp),
6060
headerBackgroundColor: Color = Color.Unspecified,
6161
footerBackgroundColor: Color = Color.Unspecified,
62-
rowBackgroundColor: @Composable (Int) -> Color = { Color.Unspecified },
6362
footer: (@Composable () -> Unit)? = null,
6463
cellContentProvider: CellContentProvider = DefaultCellContentProvider,
6564
sortColumnIndex: Int? = null,
@@ -239,7 +238,7 @@ fun BasicDataTable(
239238
} else {
240239
val rowData = tableScope.tableRows[row - 1]
241240
Box(Modifier
242-
.background(rowBackgroundColor(row - 1))
241+
.background(rowData.backgroundColor)
243242
.fillMaxSize()
244243
.then(if (rowData.onClick != null) Modifier.clickable { rowData.onClick?.invoke() } else Modifier)
245244
) {
@@ -317,14 +316,15 @@ fun BasicDataTable(
317316
offset += row.height
318317
if (y > -row.height && y < state.verticalScrollState.viewportSize) {
319318
row.position(offsetX, y + headerOffset)
320-
row.place(this@SubcomposeLayout, this)
321319
}
322320
}
323321
}
324322
// Place headers and footers last
325323
measuredRows.forEach { row ->
326324
if (row.isHeader || row.isFooter) {
327-
row.place(this@SubcomposeLayout, this)
325+
row.place(this@SubcomposeLayout, this, 0, state.verticalScrollState.viewportSize)
326+
} else {
327+
row.place(this@SubcomposeLayout, this, upperBound = headerOffset, lowerBound = footerOffset)
328328
}
329329
}
330330
}

data-table/src/commonMain/kotlin/com/seanproctor/datatable/DataTableDsl.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ interface TableRowScope {
2727
var height: Dp
2828
var isHeader: Boolean
2929
var isFooter: Boolean
30-
var color: Color
30+
var backgroundColor: Color
3131

3232
fun cell(content: @Composable () -> Unit)
3333
}
@@ -55,7 +55,7 @@ internal class TableRowScopeImpl(
5555
override var height: Dp = Dp.Unspecified
5656
override var isHeader: Boolean = false
5757
override var isFooter: Boolean = false
58-
override var color: Color = Color.Unspecified
58+
override var backgroundColor: Color = Color.Unspecified
5959
val cells = mutableListOf<@Composable () -> Unit>()
6060

6161
init {

data-table/src/commonMain/kotlin/com/seanproctor/datatable/DataTableMeasuredRow.kt

Lines changed: 71 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,14 @@ package com.seanproctor.datatable
22

33
import androidx.compose.runtime.Composable
44
import androidx.compose.ui.Alignment
5+
import androidx.compose.ui.geometry.Size
6+
import androidx.compose.ui.geometry.toRect
7+
import androidx.compose.ui.graphics.Outline
8+
import androidx.compose.ui.graphics.Shape
59
import androidx.compose.ui.layout.Placeable
610
import androidx.compose.ui.layout.SubcomposeMeasureScope
711
import androidx.compose.ui.unit.Constraints
12+
import androidx.compose.ui.unit.Density
813
import androidx.compose.ui.unit.IntOffset
914
import androidx.compose.ui.unit.IntSize
1015
import androidx.compose.ui.unit.LayoutDirection
@@ -54,24 +59,59 @@ class DataTableMeasuredRow(
5459
return IntOffset(placeableOffsets[index * 2], placeableOffsets[index * 2 + 1])
5560
}
5661

57-
override fun place(subcomposeScope: SubcomposeMeasureScope, placementBlock: Placeable.PlacementScope) {
62+
override fun place(
63+
subcomposeScope: SubcomposeMeasureScope, placementBlock: Placeable.PlacementScope,
64+
upperBound: Int,
65+
lowerBound: Int,
66+
) {
5867
with(placementBlock) {
5968
with(subcomposeScope) {
6069
subcompose(key, background).map {
61-
it.measure(
70+
val placeable = it.measure(
6271
Constraints(
6372
minHeight = height,
6473
maxHeight = height,
6574
minWidth = tableWidth,
6675
maxWidth = tableWidth,
6776
)
6877
)
69-
.place(0, backgroundOffset)
78+
// .place(0, backgroundOffset)
79+
// if (upperBound >= backgroundOffset && lowerBound < backgroundOffset) {
80+
// placeable.place(0, backgroundOffset)
81+
// } else {
82+
placeable.placeWithLayer(0, backgroundOffset) {
83+
shape = object : Shape {
84+
override fun createOutline(size: Size, layoutDirection: LayoutDirection, density: Density): Outline {
85+
val sizeRect = size.toRect()
86+
return Outline.Rectangle(
87+
sizeRect.copy(
88+
top = maxOf(sizeRect.top, sizeRect.top + upperBound.toFloat() - backgroundOffset),
89+
bottom = minOf(sizeRect.bottom, sizeRect.bottom - backgroundOffset - height + lowerBound.toFloat()),
90+
)
91+
)
92+
}
93+
}
94+
clip = true
95+
// }
96+
}
7097
}
7198
}
7299
placeables.forEachIndexed { index, placeable ->
73100
val offset = getOffset(index)
74-
placeable?.place(offset)
101+
placeable?.placeWithLayer(offset) {
102+
shape = object : Shape {
103+
override fun createOutline(size: Size, layoutDirection: LayoutDirection, density: Density): Outline {
104+
val sizeRect = size.toRect()
105+
return Outline.Rectangle(
106+
sizeRect.copy(
107+
top = maxOf(sizeRect.top, sizeRect.top + upperBound.toFloat() - offset.y),
108+
bottom = minOf(sizeRect.bottom, sizeRect.bottom - offset.y - placeable.height.toFloat() + lowerBound.toFloat()),
109+
)
110+
)
111+
}
112+
}
113+
clip = true
114+
}
75115
}
76116
}
77117
}
@@ -96,7 +136,12 @@ class DataTableMeasuredSimple(
96136
this.offset = offset
97137
}
98138

99-
override fun place(subcomposeScope: SubcomposeMeasureScope, placementBlock: Placeable.PlacementScope) {
139+
override fun place(
140+
subcomposeScope: SubcomposeMeasureScope,
141+
placementBlock: Placeable.PlacementScope,
142+
upperBound: Int,
143+
lowerBound: Int,
144+
) {
100145
with(placementBlock) {
101146
with(subcomposeScope) {
102147
subcompose(key, background).map {
@@ -112,7 +157,20 @@ class DataTableMeasuredSimple(
112157
}
113158
}
114159
placeables.forEach { placeable ->
115-
placeable.place(offset)
160+
placeable.placeWithLayer(offset) {
161+
shape = object : Shape {
162+
override fun createOutline(size: Size, layoutDirection: LayoutDirection, density: Density): Outline {
163+
val sizeRect = size.toRect()
164+
return Outline.Rectangle(
165+
sizeRect.copy(
166+
top = maxOf(sizeRect.top, sizeRect.top + upperBound.toFloat() - offset.y),
167+
bottom = minOf(sizeRect.bottom, sizeRect.bottom - offset.y - placeable.height.toFloat() + lowerBound.toFloat()),
168+
)
169+
)
170+
}
171+
}
172+
clip = true
173+
}
116174
}
117175
}
118176
}
@@ -129,5 +187,10 @@ interface DataTableMeasuredElement {
129187
position(IntOffset(x, y))
130188
}
131189

132-
fun place(subcomposeScope: SubcomposeMeasureScope, placementBlock: Placeable.PlacementScope)
133-
}
190+
fun place(
191+
subcomposeScope: SubcomposeMeasureScope,
192+
placementBlock: Placeable.PlacementScope,
193+
upperBound: Int,
194+
lowerBound: Int,
195+
)
196+
}

data-table/src/commonMain/kotlin/com/seanproctor/datatable/paging/BasicPaginatedDataTable.kt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ fun BasicPaginatedDataTable(
1919
contentPadding: PaddingValues = PaddingValues(horizontal = 16.dp),
2020
headerBackgroundColor: Color = Color.Unspecified,
2121
footerBackgroundColor: Color = Color.Unspecified,
22-
rowBackgroundColor: @Composable (Int) -> Color = { Color.Unspecified },
2322
footer: @Composable () -> Unit = { },
2423
cellContentProvider: CellContentProvider = DefaultCellContentProvider,
2524
sortColumnIndex: Int? = null,
@@ -37,7 +36,6 @@ fun BasicPaginatedDataTable(
3736
contentPadding = contentPadding,
3837
headerBackgroundColor = headerBackgroundColor,
3938
footerBackgroundColor = footerBackgroundColor,
40-
rowBackgroundColor = rowBackgroundColor,
4139
footer = footer,
4240
cellContentProvider = cellContentProvider,
4341
sortColumnIndex = sortColumnIndex,

0 commit comments

Comments
 (0)