From bab6a5df11ebb93758cb351f4cc7e1c9499af9d8 Mon Sep 17 00:00:00 2001 From: andresmr Date: Tue, 14 Jan 2025 12:30:50 +0100 Subject: [PATCH] docs: Update documentation version and URL --- .../component/table/model/TableModel.kt | 20 ++- .../component/table/ui/TableDimensions.kt | 62 +++++++-- .../component/table/ui/TableSelection.kt | 120 ++++++++++++++++++ .../component/table/ui/TableTheme.kt | 33 +++++ .../mobile/ui/designsystem/theme/Spacing.kt | 3 + 5 files changed, 226 insertions(+), 12 deletions(-) diff --git a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/table/model/TableModel.kt b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/table/model/TableModel.kt index ffc01c9a0..e562cbaba 100644 --- a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/table/model/TableModel.kt +++ b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/table/model/TableModel.kt @@ -38,6 +38,13 @@ data class TableModel( }.toMap() } + /** + * Get the next cell to be selected. + * + * @param cellSelection The current cell selection. + * @param successValidation The validation result. + * @return The next cell to be selected. + */ fun getNextCell( cellSelection: TableSelection.CellSelection, successValidation: Boolean, @@ -61,6 +68,12 @@ data class TableModel( } } + /** + * Check if a cell has an error. + * + * @param cell The cell to check. + * @return The cell with an error. + */ fun cellHasError(cell: TableSelection.CellSelection): TableCell? { return when { tableRows.size == 1 && tableRows.size == cell.rowIndex -> { @@ -73,7 +86,12 @@ data class TableModel( } } - // review whether this class is still needed + /** + * Check if the table has a cell with a specific ID. + * + * @param cellId The ID to check. + * @return True if the table has a cell with the ID, false otherwise. + */ fun hasCellWithId(cellId: String?): Boolean { return tableRows.any { row -> row.rowHeader.id?.let { diff --git a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/table/ui/TableDimensions.kt b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/table/ui/TableDimensions.kt index 6f7bcd43a..330eb2473 100644 --- a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/table/ui/TableDimensions.kt +++ b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/table/ui/TableDimensions.kt @@ -5,8 +5,8 @@ import androidx.compose.runtime.Immutable import androidx.compose.runtime.compositionLocalOf import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.TextUnit -import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import org.hisp.dhis.mobile.ui.designsystem.theme.Spacing /** * Data class representing the dimensions of the table component. @@ -38,22 +38,25 @@ import androidx.compose.ui.unit.sp */ @Immutable data class TableDimensions( - val tableHorizontalPadding: Dp = 16.dp, - val tableVerticalPadding: Dp = 16.dp, + val tableHorizontalPadding: Dp = Spacing.Spacing16, + val tableVerticalPadding: Dp = Spacing.Spacing16, val defaultCellWidth: Int = 160, - val defaultCellHeight: Dp = 36.dp, + val defaultCellHeight: Dp = Spacing.Spacing36, val defaultRowHeaderWidth: Int = 275, val defaultHeaderHeight: Int = 36, - val defaultLegendCornerSize: Dp = 2.dp, - val defaultLegendBorderWidth: Dp = 8.dp, + val defaultLegendCornerSize: Dp = Spacing.Spacing2, + val defaultLegendBorderWidth: Dp = Spacing.Spacing8, val defaultHeaderTextSize: TextUnit = 12.sp, val defaultRowHeaderTextSize: TextUnit = 12.sp, val defaultCellTextSize: TextUnit = 12.sp, val totalWidth: Int = 0, - val cellVerticalPadding: Dp = 4.dp, - val cellHorizontalPadding: Dp = 4.dp, - val headerCellPaddingValues: PaddingValues = PaddingValues(horizontal = 4.dp, vertical = 11.dp), - val tableBottomPadding: Dp = 200.dp, + val cellVerticalPadding: Dp = Spacing.Spacing4, + val cellHorizontalPadding: Dp = Spacing.Spacing4, + val headerCellPaddingValues: PaddingValues = PaddingValues( + horizontal = Spacing.Spacing4, + vertical = Spacing.Spacing11, + ), + val tableBottomPadding: Dp = Spacing.Spacing200, val extraWidths: Map = emptyMap(), val rowHeaderWidths: Map = emptyMap(), val columnWidth: Map> = emptyMap(), @@ -61,7 +64,7 @@ data class TableDimensions( val minColumnWidth: Int = 130, val maxRowHeaderWidth: Int = Int.MAX_VALUE, val maxColumnWidth: Int = Int.MAX_VALUE, - val tableEndExtraScroll: Dp = 6.dp, + val tableEndExtraScroll: Dp = Spacing.Spacing6, ) { private var currentExtraSize: MutableMap = mutableMapOf() @@ -69,6 +72,11 @@ data class TableDimensions( var textInputHeight = 0 + /** + * Update the width of the row header. + * @param tableId The ID of the table. + * @return The updated dimensions. + */ fun rowHeaderWidth(tableId: String): Int { return (rowHeaderWidths[tableId] ?: defaultRowHeaderWidth) + extraWidthInTable(tableId) } @@ -158,12 +166,22 @@ data class TableDimensions( return this.copy(columnWidth = newMap) } + /** + * Check if the table has overridden widths. + * @param tableId The ID of the table. + * @return `true` if the table has overridden widths, `false` otherwise. + */ fun hasOverriddenWidths(tableId: String): Boolean { return rowHeaderWidths.containsKey(tableId) || columnWidth.containsKey(tableId) || extraWidths.containsKey(tableId) } + /** + * Reset the widths of the table. + * @param tableId The ID of the table. + * @return The updated dimensions. + */ fun resetWidth(tableId: String): TableDimensions { val newExtraWidths = extraWidths.toMutableMap() val newColumnMap = columnWidth.toMutableMap() @@ -218,17 +236,39 @@ data class TableDimensions( } ?: true } + /** + * Get the width of the row header. + * + * @param tableId The ID of the table. + * @return The width of the row header. + */ fun getRowHeaderWidth(tableId: String): Int { return rowHeaderWidths[tableId] ?: defaultRowHeaderWidth } + /** + * Get the width of the column. + * + * @param tableId The ID of the table. + * @param column The index of the column. + * @return The width of the column. + */ fun getColumnWidth(tableId: String, column: Int): Int { return columnWidth[tableId]?.get(column) ?: defaultCellWidth } + /** + * Get the extra widths of the table. + * + * @param tableId The ID of the table. + * @return The extra widths of the table. + */ fun getExtraWidths(tableId: String): Int { return extraWidths[tableId] ?: 0 } } +/** + * Composition local for the table dimensions. + */ val LocalTableDimensions = compositionLocalOf { TableDimensions() } diff --git a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/table/ui/TableSelection.kt b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/table/ui/TableSelection.kt index e79396791..72c710e55 100644 --- a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/table/ui/TableSelection.kt +++ b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/table/ui/TableSelection.kt @@ -2,20 +2,50 @@ package org.hisp.dhis.mobile.ui.designsystem.component.table.ui import androidx.compose.runtime.staticCompositionLocalOf +/** + * Sealed class representing different types of table selections. + * + * @property tableId The ID of the table. + */ sealed class TableSelection(open val tableId: String) { + + /** + * Represents an unselected state with an optional previous selected table ID. + * + * @property previousSelectedTableId The ID of the previously selected table. + */ data class Unselected( val previousSelectedTableId: String? = null, ) : TableSelection(previousSelectedTableId ?: "") + /** + * Represents a selection of all cells in the table. + * + * @property tableId The ID of the table. + */ data class AllCellSelection( override val tableId: String, ) : TableSelection(tableId) + /** + * Represents a selection of a row in the table. + * + * @property tableId The ID of the table. + * @property rowIndex The index of the selected row. + */ data class RowSelection( override val tableId: String, val rowIndex: Int, ) : TableSelection(tableId) + /** + * Represents a selection of a column in the table. + * + * @property tableId The ID of the table. + * @property columnIndex The index of the selected column. + * @property columnHeaderRow The index of the header row of the selected column. + * @property childrenOfSelectedHeader The children of the selected header. + */ data class ColumnSelection( override val tableId: String, val columnIndex: Int, @@ -23,12 +53,34 @@ sealed class TableSelection(open val tableId: String) { val childrenOfSelectedHeader: Map, ) : TableSelection(tableId) + /** + * Represents a range of header cells. + * + * @property size The size of the range. + * @property firstIndex The first index of the range. + * @property lastIndex The last index of the range. + */ data class HeaderCellRange(val size: Int, val firstIndex: Int, val lastIndex: Int) { + + /** + * Checks if the given column index is within the range. + * + * @param columnIndex The index of the column to check. + * @return `true` if the column index is within the range, `false` otherwise. + */ fun isInRange(columnIndex: Int): Boolean { return columnIndex in firstIndex..lastIndex } } + /** + * Represents a selection of a cell in the table. + * + * @property tableId The ID of the table. + * @property columnIndex The index of the selected column. + * @property rowIndex The index of the selected row. + * @property globalIndex The global index of the selected cell. + */ data class CellSelection( override val tableId: String, val columnIndex: Int, @@ -36,6 +88,12 @@ sealed class TableSelection(open val tableId: String) { val globalIndex: Int, ) : TableSelection(tableId) + /** + * Gets the row index of the selected cell if the table ID matches. + * + * @param selectedTableId The ID of the selected table. + * @return The row index of the selected cell, or -1 if not selected. + */ fun getSelectedCellRowIndex(selectedTableId: String): Int = if (selectedTableId == tableId && this is CellSelection) { this.rowIndex @@ -43,15 +101,37 @@ sealed class TableSelection(open val tableId: String) { -1 } + /** + * Checks if the corner of the table is selected. + * + * @param selectedTableId The ID of the selected table. + * @return True if the corner is selected, false otherwise. + */ fun isCornerSelected(selectedTableId: String) = selectedTableId == tableId && (this is AllCellSelection) + /** + * Checks if a header cell is selected. + * + * @param selectedTableId The ID of the selected table. + * @param columnIndex The index of the column. + * @param columnHeaderRowIndex The row index of the column header. + * @return True if the header cell is selected, false otherwise. + */ fun isHeaderSelected(selectedTableId: String, columnIndex: Int, columnHeaderRowIndex: Int) = this.isCornerSelected(selectedTableId) || selectedTableId == tableId && (this is ColumnSelection) && this.columnIndex == columnIndex && this.columnHeaderRow == columnHeaderRowIndex + /** + * Checks if a parent header is selected. + * + * @param selectedTableId The ID of the selected table. + * @param columnIndex The index of the column. + * @param columnHeaderRowIndex The row index of the column header. + * @return True if the parent header is selected, false otherwise. + */ fun isParentHeaderSelected( selectedTableId: String, columnIndex: Int, @@ -67,20 +147,50 @@ sealed class TableSelection(open val tableId: String) { } ) + /** + * Checks if a row is selected. + * + * @param selectedTableId The ID of the selected table. + * @param rowHeaderIndex The index of the row header. + * @return True if the row is selected, false otherwise. + */ fun isRowSelected(selectedTableId: String, rowHeaderIndex: Int) = this.isCornerSelected(selectedTableId) || selectedTableId == tableId && (this is RowSelection) && this.rowIndex == rowHeaderIndex + /** + * Checks if another row is selected. + * + * @param selectedTableId The ID of the selected table. + * @param rowHeaderIndex The index of the row header. + * @return True if another row is selected, false otherwise. + */ fun isOtherRowSelected(selectedTableId: String, rowHeaderIndex: Int) = selectedTableId == tableId && (this is RowSelection) && this.rowIndex != rowHeaderIndex + /** + * Checks if a cell is selected. + * + * @param selectedTableId The ID of the selected table. + * @param columnIndex The index of the column. + * @param rowIndex The index of the row. + * @return True if the cell is selected, false otherwise. + */ fun isCellSelected(selectedTableId: String, columnIndex: Int, rowIndex: Int) = this.tableId == selectedTableId && (this is CellSelection) && this.columnIndex == columnIndex && this.rowIndex == rowIndex + /** + * Checks if a cell's parent is selected. + * + * @param selectedTableId The ID of the selected table. + * @param columnIndex The index of the column. + * @param rowIndex The index of the row. + * @return True if the cell's parent is selected, false otherwise. + */ fun isCellParentSelected(selectedTableId: String, columnIndex: Int, rowIndex: Int) = when (this) { is AllCellSelection -> isCornerSelected(selectedTableId) @@ -100,9 +210,19 @@ sealed class TableSelection(open val tableId: String) { else -> false } + /** + * Checks if a cell is valid. + * + * @param columnIndex The index of the column. + * @param rowIndex The index of the row. + * @return True if the cell is valid, false otherwise. + */ private fun isCellValid(columnIndex: Int, rowIndex: Int): Boolean { return columnIndex != -1 && rowIndex != -1 } } +/** + * CompositionLocal to provide [TableSelection] throughout the Compose hierarchy. + */ val LocalTableSelection = staticCompositionLocalOf { TableSelection.Unselected() } diff --git a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/table/ui/TableTheme.kt b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/table/ui/TableTheme.kt index 6b0a7d799..16b1dbbef 100644 --- a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/table/ui/TableTheme.kt +++ b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/component/table/ui/TableTheme.kt @@ -9,6 +9,16 @@ import org.hisp.dhis.mobile.ui.designsystem.component.table.actions.Validator import org.hisp.dhis.mobile.ui.designsystem.component.table.ui.compositions.LocalTableResizeActions import org.hisp.dhis.mobile.ui.designsystem.component.table.ui.compositions.LocalValidator +/** + * Composable function to provide table-related theme settings to the content. + * + * @param tableColors The colors to be used in the table. + * @param tableDimensions The dimensions to be used in the table. + * @param tableConfiguration The configuration settings for the table. + * @param tableValidator The validator to be used for table validation. + * @param tableResizeActions The actions to be used for table resizing. + * @param content The composable content to which the theme settings will be applied. + */ @Composable fun TableTheme( tableColors: TableColors?, @@ -32,19 +42,42 @@ fun TableTheme( } } +/** + * Object to access the current table theme settings. + */ object TableTheme { + + /** + * The current table colors. + */ val colors: TableColors @Composable get() = LocalTableColors.current + + /** + * The current table dimensions. + */ val dimensions: TableDimensions @Composable get() = LocalTableDimensions.current + + /** + * The current table configuration. + */ val configuration: TableConfiguration @Composable get() = LocalTableConfiguration.current + + /** + * The current table selection. + */ val tableSelection @Composable get() = LocalTableSelection.current + + /** + * The current table validator. + */ val validator @Composable get() = LocalValidator.current diff --git a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/theme/Spacing.kt b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/theme/Spacing.kt index ae7f9badc..89f2a71e3 100644 --- a/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/theme/Spacing.kt +++ b/designsystem/src/commonMain/kotlin/org/hisp/dhis/mobile/ui/designsystem/theme/Spacing.kt @@ -11,11 +11,13 @@ object Spacing { val Spacing6: Dp = 6.dp val Spacing8: Dp = 8.dp val Spacing10: Dp = 10.dp + val Spacing11: Dp = 11.dp val Spacing12: Dp = 12.dp val Spacing16: Dp = 16.dp val Spacing18: Dp = 18.dp val Spacing24: Dp = 24.dp val Spacing32: Dp = 32.dp + val Spacing36: Dp = 36.dp val Spacing40: Dp = 40.dp val Spacing48: Dp = 48.dp val Spacing56: Dp = 56.dp @@ -28,6 +30,7 @@ object Spacing { val Spacing112: Dp = 112.dp val Spacing120: Dp = 120.dp val Spacing160: Dp = 160.dp + val Spacing200: Dp = 200.dp val Spacing800: Dp = 800.dp val Spacing840: Dp = 840.dp }