question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Table element spec and design review

See original GitHub issue

Try it for yourself

Table element for Adaptive Cards

This is a proposal for a simple Table element. The main goals of this element are:

  • To allow the creation of table layouts in a straightforward way, as opposed to using a stack of ColumnSet elements which leads to a larger (potentially much larger) payload and potential headaches wrt column sizing
  • To allow accessibility software to present table layouts as such, which is currently impossible

This is NOT a proposal for an advanced Table with features such as:

  • Dynamic column sizing
  • Dynamic column reordering
  • Sorting by columns
  • Etc.

Design

Table

Name Type Required Description
columns ColumnDefinition[] No Defines the table’s columns (number of columns, and column sizes). See ColumnDefinition below.
rows TableRow[] No Defines the rows of the Table, each being a collection of cells. See TableRow below. Rows are not required, which allows empty Tables to be generated via templating without breaking the rendering of the whole card.
showGridLines Boolean No Specifies if grid lines should be displayed around the table and its cells. Defaults to true.
gridStyle string No When showGridLines is set to true, gridStyle controls the color of the grid. Its value must be a valid container style name (emphasis, accent, etc.). If gridStyle isn’t specified, the style used is inherited from the Table’s parent container. This feature requires adding support for border colors in HostConfig (see below).
horizontalCellContentAlignment HorizontalAlignment No Specifies how the content of each cell should be horizontally aligned by default. Defaults to left. This value can be overridden by setting horizontalCellContentAlignment on a column or row, or by setting the horizontalAlignment property on each individual element in a cell.
verticalCellContentAlignment VerticalAlignment No Specifies how the content of each cell should be vertically aligned by default. Defaults to top. This value can be overridden by setting verticalCellContentAlignment on a column, row or cell.
firstRowAsHeaders Boolean No Defines whether the first row of the Table should be treated as a header row. Defaults to true. When firstRowAsHeaders is set to true, that row and its cells will be recognized as such by accessibility software. A cell belonging to the header row will also apply the “columnHeader” text styles to all text blocks it contains.

Notes on rendering Table

  • When showGridLines is set to false, there should be space added between columns and rows in order for the content of the table to be clearly separated.
    • The amount of space used will be defined via the new HostConfig.table.cellSpacing property, of type number, representing an explicit number of pixels.
    • cellSpacing must be greater than or equal to zero. Any other value will be interpreted as 0
    • The suggested default value is 8
    • Each cell can have its own style (and thus background color). When rendering space between styled columns, empty space must visually appear.

Examples: image image

  • When showGridLines is set to true (the default) a 1px wide grid should appear all around the table and in between cells
    • HostConfig.table.cellSpacing does not apply and is ignored when grid lines are displayed
    • Each cell gets padding in order for their content to not be “stuck” against the grid lines

Example: image

ColumnDefinition

Name Type Required Description
horizontalCellContentAlignment HorizontalAlignment No Specifies how the content of each cell should be horizontally aligned by default within the column. Defaults to left. This value override the table setting, and can itself be overridden by setting horizontalCellContentAlignment on a row or by setting the horizontalAlignment property on each individual element in a cell.
verticalCellContentAlignment VerticalAlignment No Specifies how the content of each cell should be vertically aligned by default within the column. Defaults to top. This value overrides the table setting and can itself be overridden by setting verticalCellContentAlignment on a row or cell.
width number or string No Defines the width of the column. When expressed as a string, width represents an explicit number of pixels, and must be in the format “<positive number>px”, e.g. “80px”. When expressed as a number, width represents the weight of the column within the table.

Computing effective column widths

  • First, all explicitly sized columns are get the space they request
  • The remaining space is then split between weighted columns according to their individual weight
    • Weights can be expressed as any positive number
    • The sum of all weights in a Table does not have to equal 100

TableRow

Name Type Required Description
cells TableCell[] No Defines the cells for this particular row. See TableCell below. When a row doesn’t contain as many cells as there are columns defined on the Table, the remaining columns remain empty for that row. If there are more cells in a row than there are columns defined on the Table, the extra cells are not rendered.
horizontalCellContentAlignment HorizontalAlignment No Specifies how the content of each cell should be horizontally aligned by default within the row. Defaults to left. This value override the table and column settings, and can itself be overridden by setting the horizontalAlignment property on each individual element in a cell.
verticalCellContentAlignment VerticalAlignment No Specifies how the content of each cell should be vertically aligned by default within the row. Defaults to top. This value overrides the table and column settings and can itself be overridden by setting verticalCellContentAlignment on a cell.
style string No Specifies the style of that row in terms of background color. style must be set to a valid container style name. When not specified, style is inherited from the row’s parent container.

TableCell

TableCell extends Container, and thus inherits Container’s properties. It doesn’t introduce additional properties.

As a descendent of Container, TableCell can contain any Adaptive Card element, including ColumnSet or even other Table elements.

HostConfig changes

Introducing borderColor in container styles

In order to support grid lines (and furthermore stylable grid lines), a new borderColor property needs to be added in container style definitions in HostConfig.

Example:

{
    ...
    "containerStyles": {
        ...
        "accent": {
            "borderColor": "#62A8F7",
            "backgroundColor": "#C7DEF9",
            "foregroundColors": {
                "default": {
                    "default": "#333333",
                    "subtle": "#EE333333"
                },
                ...
            }
        },
        ...
    }
    ...
}

NOTE: given the above, we should consider adding the ability to put a border on any container.

Introducing the “columnHeader” text style

As mentioned above, cells that belong to the header row should apply a specific style to the TextBlocks they contains by default. Typically, text in header cells will be bold.

This will be done by applying by default a new “columnHeader” text style to header cells. Like with all text styles, it can be overridden by each individual TextBlock by setting their size, weight, color, isSubtle and fontType properties.

Example host config text styles section:

{
    ...
    "textStyles": {
        "columnHeadet": {
            "size": "default",
            "weight": "bolder",
            "color": "default",
            "isSubtle": "false",
            "fontType": "default"
        },
        ...
    }
    ...
}

Sample card

{
    "type": "AdaptiveCard",
    "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
    "version": "1.3",
    "body": [
        {
            "type": "Table",
            "columns": [
                {
                    "width": 1
                },
                {
                    "width": 1
                },
                {
                    "width": 3
                }
            ],
            "rows": [
                {
                    "type": "TableRow",
                    "cells": [
                        {
                            "type": "TableCell",
                            "items": [
                                {
                                    "type": "TextBlock",
                                    "text": "Name",
                                    "wrap": true,
                                    "weight": "Bolder"
                                }
                            ]
                        },
                        {
                            "type": "TableCell",
                            "items": [
                                {
                                    "type": "TextBlock",
                                    "text": "Type",
                                    "wrap": true,
                                    "weight": "Bolder"
                                }
                            ]
                        },
                        {
                            "type": "TableCell",
                            "items": [
                                {
                                    "type": "TextBlock",
                                    "text": "Description",
                                    "wrap": true,
                                    "weight": "Bolder"
                                }
                            ]
                        }
                    ],
                    "style": "accent"
                },
                {
                    "type": "TableRow",
                    "cells": [
                        {
                            "type": "TableCell",
                            "items": [
                                {
                                    "type": "TextBlock",
                                    "text": "columns",
                                    "wrap": true
                                }
                            ]
                        },
                        {
                            "type": "TableCell",
                            "items": [
                                {
                                    "type": "TextBlock",
                                    "text": "ColumnDefinition[]",
                                    "wrap": true
                                }
                            ]
                        },
                        {
                            "type": "TableCell",
                            "items": [
                                {
                                    "type": "TextBlock",
                                    "text": "Defines the table's columns (number of columns, and column sizes).",
                                    "wrap": true
                                }
                            ]
                        }
                    ]
                },
                {
                    "type": "TableRow",
                    "cells": [
                        {
                            "type": "TableCell",
                            "items": [
                                {
                                    "type": "TextBlock",
                                    "text": "rows",
                                    "wrap": true
                                }
                            ]
                        },
                        {
                            "type": "TableCell",
                            "items": [
                                {
                                    "type": "TextBlock",
                                    "text": "TableRow[]",
                                    "wrap": true
                                }
                            ]
                        },
                        {
                            "type": "TableCell",
                            "items": [
                                {
                                    "type": "TextBlock",
                                    "text": "Defines the rows of the Table, each being a collection of cells. Rows are not required, which allows empty Tables to be generated via templating without breaking the rendering of the whole card.",
                                    "wrap": true
                                }
                            ]
                        }
                    ]
                }
            ],
            "gridStyle": "accent"
        }
    ]
}

As rendered: image

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:9 (9 by maintainers)

github_iconTop GitHub Comments

1reaction
paulcam206commented, May 4, 2021

@RebeccaAnne - can we get a little time in the next design review to go over bleed, rtl, selectAction, etc.? I imagine it should only take a few minutes…

0reactions
paulcam206commented, May 5, 2021

it would seem odd to me that you could build an RTL-aware fake table using ColumnSet, but not a real one.

You could just the same. rtl isn’t an explicit property on ColumnSet and ColumnSet is essentially the equivalent of TableRow. You just need to set rtl on the parent of the ColumnSet or Table.

Fair enough – thanks!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Design Review Process Essentials
The design review package contains product development specifications, relevant engineering data, competitive analysis of existing products, ...
Read more >
Table of Specifications | Special Connections
A Table of Specifications is a two-way chart which describes the topics to be covered by a test and the number of items...
Read more >
Specification Guide - Table Topics
Use our simple Specification Guide below to choose your inset, frame, décor, colors, finish and table size. Of course, our experienced design team...
Read more >
Designing The Perfect Feature Comparison Table
Feature comparison tables are helpful not only in their primary function, though. When designed properly, they can aid in decision-making ...
Read more >
9 Best WordPress Table Plugins in 2023 (Reviewed & Rated)
Create stunning and user-friendly tables on your website with our top picks for best WordPress table plugins (features and pricing compared)
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found