Skip to content

Table #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 16 commits into from
Feb 7, 2022
Merged
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
177 changes: 177 additions & 0 deletions table-component.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
- Start Date: 2021-10-01
- Specification: ([Table](<https://wwnorton1.sharepoint.com/:w:/g/DP/products_and_projects/nds/EUXxmi6yZvBLiSLZLKo7M2cBuFiWRXtQ_lM1_OW0Smm5mQ?e=nutOb4>))
- Design: ([Table](https://app.zeplin.io/project/5d66e28439bbe3139aa846ad/screen/6148d737ee5b5557ca49792c))
- RFC PR:

## Summary

Table component is a web component that enables you to create rows and columns of known data. Table components consist of as many columns and rows you need, with the column being used to specify the type of values like text, number, date or custom and the rows being used to contain the values themselves.Tables must have at least 2 columns. Now a day most of the applications expecting data table, this table component also work as a manual table and data table. DataSource and DataColumn JSON array properties convert a table into the data table.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really appreciate the motivation for why tables are built with data here. 👍

Are we also creating a compositional API? If so, what's the shape of it? For instance, could I do this?

<Table>
  <TableHeader>
    <TableRow>
      <TableCell>First Name</TableCell>
      <TableCell>Last Name</TableCell>
    </TableRow>
  </TableHeader>
  <TableRow>
    <TableCell>Anand</TableCell>
    <TableCell>Patil</TableCell>
  </TableRow>
  <TableRow>
    <TableCell>Evan</TableCell>
    <TableCell>Yamanishi</TableCell>
  </TableRow>
</Table>

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is the example last time we finalized for table tag, Once get datasource will convert into following tags. Difference only is inside TableHeader there is no TableRow. As per the discussion Table Header component create table row.

<Table>
  <TableHeader>
      <TableCell>First Name</TableCell>
      <TableCell>Last Name</TableCell>
  </TableHeader>
  <TableRow>
    <TableCell>Anand</TableCell>
    <TableCell>Patil</TableCell>
  </TableRow>
  <TableRow>
    <TableCell>Evan</TableCell>
    <TableCell>Yamanishi</TableCell>
  </TableRow>
</Table>


- `<Table>` - A table with one header and simple data are fairly accessible out of the box and may not need additional accessibility updates.
- `<TableHeader>` - Is a row at the top of a table contains column title, with sorting, sticky header properties.
- `<TableRow>` - A table row can contain as many cells as required, each one defined in a different column. There must be at least one column defined.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is also in the anatomy, so try to adapt that description here.

- `<TableCell>` - This should contain the data or information required for each relevant column and row.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not part of the anatomy, so I think your description is good 👍


## Detailed design

### Table

`<Table>` extends the `React.forwardRef<HTMLTableElement>` following are properties:

| Name | Description | Required | Default |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not clear to me what API you're proposing here. For instance, what happens if I do this?

<Table TableHeader={true} TableRow={<TableRow>Apple</TableRow>} />

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess I have to add property type so would be clear, TableHeader and TableRow are the child nodes. Expecting following format.

<Table>  
	<TableHeader>    
		<TableCell>
		</TableCell>   
	</TableHeader> 
 	<TableRow>    
		<TableCell header >
		</TableCell>    
	</TableRow>
</Table>

| -------- | ---------------------------------------- | -------- | ----------- |
| `TableHeader` | Top row component. | `false` | `undefined` |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Props should be camelCase with a lowercase first letter.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My bad.

| `TableRow` | Element defines a row of cells | `false` | `undefined` |
| `DataSource` | Indicates array of JSON formatted row data | `false` | `undefined` |
| `DataColumn` | Indicates array of JSON formatted column data | `false` | `undefined` |
| `ClassName` | Override or extend existing table style. | `false` | `undefined` |
| `Border` | Indicates whether table with or without border. | `false` | `undefined` |
| `Sort` | Indicates support of sort by column. | `false` | `undefined` |
| `NoDataLabel` | Display label when no data. | `false` | `undefined` |

#### Render Example

```
<table>
<thead>
<tr>
<th></th>
<th colspan="2"></th>
</tr>
</thead>
<tr>
<th scope="row"></th>
<td></td>
<td></td>
</tr>
</table>
```

#### DataColumn JSON

RowKey is the mapping between DataSource and DataColumn based on this mapping table convert all the json data in to rows and columns format. A cellFormatter formate cell as per the requirment.

```
[
{
name: "User Name",
rowKey: "userName",
},
{
name: "Address",
rowKey: "address",
cellFormatter: row => <AddressFormate row={row} />,
}
]
```

#### DataSource JSON

```
[
{
userName: "Marissa Keep",
address: "306 Campbell Hall, Michigan State University",
},
{
userName: "John Smith",
dataColumn: "21 2nd Street, New York"
}
]
```

### TableHeader

`<TableHeader>` extends the `React.forwardRef<HTMLTableRowElement>` following are properties:

| Name | Description | Required | Default |
| -------- | ---------------------------------------- | -------- | ----------- |
| `TableCell` | Element defines a cell of data in a table. | `false` | `undefined` |
| `Variant` | Define header style Ghost, Outline and Solid. | `false` | `Solid` |
| `StickyHeader` | Indicates whether the table header is sticky. | `false` | `undefined` |
| `ClassName` | Override or extend existing table style. | `false` | `undefined` |

#### Render Example

```
<thead>
<tr>
<th></th>
<th colspan="2"></th>
</tr>
</thead>
```

### TableRow

`<TableRow>` extends the `React.forwardRef<HTMLTableRowElement>` following are properties:

| Name | Description | Required | Default |
| -------- | ---------------------------------------- | -------- | ----------- |
| `TableCell` | Element defines a cell of data in a table. | `false` | `undefined` |
| `ClassName` | Override or extend existing table style. | `false` | `undefined` |
| `DataColumn` | Indicates array of JSON formatted column data | `false` | `undefined` |

#### Render Example

```
<tr>
<th scope="row"></th>
<td></td>
<td></td>
</tr>
```

### TableCell

`<TableCell>` extends the `React.forwardRef<HTMLTableColElement>` following are properties:

| Name | Description | Required | Default |
| -------- | ---------------------------------------- | -------- | ----------- |
| `ColSpan` | Specifies the number of columns a cell should span. | `false` | `undefined` |
| `Header` | Indicates a cell is header, header converts in `<th>` by default `<td>` | `false` | `<td>` |
| `ClassName` | Override or extend existing table style. | `false` | `undefined` |
| `Alignment` | Indicates cell alignment. | `false` | `Left` |
| `Type` | Indicates cell type whether `Text,Number,Date,Boolean,Custom` | `false` | `Text` |
| `CellFormatter` | Indicates React component or string. | `false` | `undefined` |
| `Data` | Indicates array of JSON formatted data | `false` | `undefined` |

#### Render Example

```
<td></td>
```

Table cell use in header element.

```
<th></th>
```

## Drawbacks
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be drawbacks to the design, not the feature set.

For instance, if the design doesn't allow for paging to be implemented later on or makes it difficult to do in user-space (at the application level), you should explain why that is here. The fact that it doesn't currently support paging isn't really a drawback unless something about the design makes paging impossible or difficult to implement.


- Not supporting paging.
- Not supporting column filter but developer can write own filters using cellFormatter.
- Not supporting nested table.
- Not supporting virtual scrolling.

## Alternatives
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This shouldn't be about alternatives on the market, it should be about alternative designs.

You could put an alternative here like, "Extend the Ant Design table" where the design is essentially an NDS <Table> element that wraps the Ant Design one and then I would expect an explanation for why you chose not to do that here. What benefits does your API have over extending an existing one? (things like, "we would be dependent on the development of Ant in order to implement new features" would be a good argument)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And to be even more clear, I'd expect other APIs that you may have considered like using render functions for a rows prop on the <Table>, along with an explanation of why you chose not to go that route.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's just remove this section.


There are many alternatives avalible in the market.

- User can create manual table using simple table html tags.
- [Ant design](https://ant.design/components/table/)
- [Shopify](https://polaris.shopify.com/components/lists-and-tables/data-table#navigation)
- [Chakra](https://chakra-ui.com/docs/data-display/table)

## Adoption strategy

A purpose of this table maintains uniformity in Norton applications. Following are application where we can replace existing third party tables.

- SW5
- Helpdesk
- Testmaker

## Unresolved questions

What are the expected events.