Skip to content

Table: Consider adding a notion of column value #125

@dpikhulya

Description

@dpikhulya

TLDR: Adding an (optional) notion of column values could be a natural evolution of the component. For now it could just slightly improve declarations of sortable tables, but it could be of greater importance as the table gets extended with more column-related features over time (e.g., built-in filtering, type-based renderers, conditional cell styling).

So far the table is designed to display a list of entities and specify a set of columns to be displayed per each entity, like this:

class UsersTable : Table<User>() {

    init {
        columns = listOf(
            TableColumn(
                name = "Name",
                sorting = TableColumnSorting(compareBy(User::name))
            ) { user ->
                Text(user.name)
            },
            TableColumn(
                name = "Created",
                sorting = TableColumnSorting(
                    comparator = compareBy(User::createdAt),
                    initialDirection = DESCENDING
                )
            ) { user ->
                Text(user.createdAt)
            }
        )
    }
}

This is sufficiently good for a really basic table that doesn't have sorting. In case of sorting we already start to have a small amount of code duplication per column: the specification of which entity's property (or other derived expression) should be displayed within each column. See User::name and user.name for the first column, and User::createdAt and user.createdAt in the second column.

The general idea in this issue is that a notion of "column value" could be a natural semantic property of a table column's design, which could naturallyl simplify column-related features as the table gets more of them.

In context of the sorting feature, the example above could look like this:

class UsersTable : Table<User>() {

    init {
        columns = listOf(
            TableColumn(
                name = "Name",
                value = { it.name }
            ) { user ->
                Text(user.name)
            },
            TableColumn(
                name = "Created",
                value = { it.createdAt },
                sorting = TableColumnSorting(initialDirection = DESCENDING) 
            ) { user ->
                Text(user.createdAt)
            }
        )
    }
}

This could also let us create a default Text-based cell renderer, so if nothing more complex than texgt is required the example aboe could be like this:

class UsersTable : Table<User>() {

    init {
        columns = listOf(
            TableColumn(
                name = "Name",
                value = { it.name }
            ),
            TableColumn(
                name = "Created",
                value = { it.createdAt },
                sorting = TableColumnSorting(initialDirection = DESCENDING) 
            )
        )
    }
}

It should be optinal though so we could still resort to having current "verbose" declarations.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions