feat(data-table): support radio, selectable variants with batch actions

This commit is contained in:
Eric Liu 2020-10-24 13:37:00 -07:00
commit f43b132088
15 changed files with 662 additions and 156 deletions

View file

@ -1,6 +1,6 @@
# Component Index
> 150 components exported from carbon-components-svelte 0.19.0
> 152 components exported from carbon-components-svelte 0.19.0
- Accordion
- [Accordion](#accordion)
@ -42,6 +42,8 @@
- [TableHeader](#tableheader)
- [TableRow](#tablerow)
- [Toolbar](#toolbar)
- [ToolbarBatchActions](#toolbarbatchactions)
- [ToolbarContent](#toolbarcontent)
- [ToolbarSearch](#toolbarsearch)
- [DataTableSkeleton](#datatableskeleton)
- DatePicker
@ -982,19 +984,23 @@ import { DataTable } from "carbon-components-svelte";
### Props
| Prop name | Type | Default value | Description |
| :------------- | :----------------------------------------------------------------------------------------------- | :------------ | :--------------------------------------------------------------------------------------------------- |
| headers | <code>{key: string; value: string; display?: (item) => string; sort?: (a, b) => number}[]</code> | `[]` | Specify the data table headers. |
| rows | <code>Object[]</code> | `[]` | Specify the rows the data table should render. keys defined in `headers` are used for the row ids. |
| size | <code>"compact" &#124; "short" &#124; "tall"</code> | -- | Set the size of the data table. |
| title | <code>string</code> | `""` | Specify the title of the data table. |
| description | <code>string</code> | `""` | Specify the description of the data table. |
| zebra | <code>boolean</code> | `false` | Set to `true` to use zebra styles. |
| sortable | <code>boolean</code> | `false` | Set to `true` for the sortable variant. |
| expandable | <code>boolean</code> | `false` | Set to `true` for the expandable variant. Automatically set to `true` if `batchExpansion` is `true`. |
| batchExpansion | <code>boolean</code> | `false` | Set to `true` to enable batch expansion. |
| expandedRowIds | <code>string[]</code> | `[]` | Specify the row ids to be expanded. |
| stickyHeader | <code>boolean</code> | `false` | Set to `true` to enable a sticky header. |
| Prop name | Type | Default value | Description |
| :------------- | :----------------------------------------------------------------------------------------------- | :------------ | :--------------------------------------------------------------------------------------------------------------- |
| headers | <code>{key: string; value: string; display?: (item) => string; sort?: (a, b) => number}[]</code> | `[]` | Specify the data table headers. |
| rows | <code>Object[]</code> | `[]` | Specify the rows the data table should render. keys defined in `headers` are used for the row ids. |
| size | <code>"compact" &#124; "short" &#124; "tall"</code> | -- | Set the size of the data table. |
| title | <code>string</code> | `""` | Specify the title of the data table. |
| description | <code>string</code> | `""` | Specify the description of the data table. |
| zebra | <code>boolean</code> | `false` | Set to `true` to use zebra styles. |
| sortable | <code>boolean</code> | `false` | Set to `true` for the sortable variant. |
| expandable | <code>boolean</code> | `false` | Set to `true` for the expandable variant. Automatically set to `true` if `batchExpansion` is `true`. |
| batchExpansion | <code>boolean</code> | `false` | Set to `true` to enable batch expansion. |
| expandedRowIds | <code>string[]</code> | `[]` | Specify the row ids to be expanded. |
| radio | <code>boolean</code> | `false` | Set to `true` for the radio selection variant. |
| selectable | <code>boolean</code> | `false` | Set to `true` for the selectable variant. Automatically set to `true` if `radio` or `batchSelection` are `true`. |
| batchSelection | <code>boolean</code> | `false` | Set to `true` to enable batch selection. |
| selectedRowIds | <code>string[]</code> | `[]` | Specify the row ids to be selected. |
| stickyHeader | <code>boolean</code> | `false` | Set to `true` to enable a sticky header. |
### Slots
@ -5250,6 +5256,60 @@ No dispatched events.
---
## ToolbarBatchActions
### Import path
```js
import { ToolbarBatchActions } from "carbon-components-svelte";
```
### Props
| Prop name | Type | Default value | Description |
| :------------------ | :--------------------------------------------- | :------------ | :-------------------------------------- |
| formatTotalSelected | <code>(totalSelected: number) => string</code> | -- | Override the total items selected text. |
### Slots
- `<slot>...</slot>`
### Forwarded events
No forwarded events.
### Dispatched events
No dispatched events.
---
## ToolbarContent
### Import path
```js
import { ToolbarContent } from "carbon-components-svelte";
```
### Props
No exported props.
### Slots
- `<slot>...</slot>`
### Forwarded events
No forwarded events.
### Dispatched events
No dispatched events.
---
## ToolbarSearch
### Import path

View file

@ -2596,6 +2596,42 @@
"description": "Specify the row ids to be expanded"
}
],
[
"radio",
{
"kind": "let",
"value": "false",
"type": "boolean",
"description": "Set to `true` for the radio selection variant"
}
],
[
"selectable",
{
"kind": "let",
"value": "false",
"type": "boolean",
"description": "Set to `true` for the selectable variant\nAutomatically set to `true` if `radio` or `batchSelection` are `true`"
}
],
[
"batchSelection",
{
"kind": "let",
"value": "false",
"type": "boolean",
"description": "Set to `true` to enable batch selection"
}
],
[
"selectedRowIds",
{
"kind": "let",
"value": "[]",
"type": "string[]",
"description": "Specify the row ids to be selected"
}
],
[
"stickyHeader",
{
@ -2621,14 +2657,14 @@
{
"attributes": [
{
"start": 5619,
"end": 5637,
"start": 7497,
"end": 7515,
"type": "Attribute",
"name": "name",
"value": [
{
"start": 5625,
"end": 5636,
"start": 7503,
"end": 7514,
"type": "Text",
"raw": "cell-header",
"data": "cell-header"
@ -2636,26 +2672,26 @@
]
},
{
"start": 5638,
"end": 5655,
"start": 7516,
"end": 7533,
"type": "Attribute",
"name": "header",
"value": [
{
"start": 5646,
"end": 5654,
"start": 7524,
"end": 7532,
"type": "MustacheTag",
"expression": {
"type": "Identifier",
"start": 5647,
"end": 5653,
"start": 7525,
"end": 7531,
"loc": {
"start": {
"line": 199,
"line": 263,
"column": 46
},
"end": {
"line": 199,
"line": 263,
"column": 52
}
},
@ -2667,34 +2703,34 @@
],
"children": [
{
"start": 5656,
"end": 5670,
"start": 7534,
"end": 7548,
"type": "MustacheTag",
"expression": {
"type": "MemberExpression",
"start": 5657,
"end": 5669,
"start": 7535,
"end": 7547,
"loc": {
"start": {
"line": 199,
"line": 263,
"column": 56
},
"end": {
"line": 199,
"line": 263,
"column": 68
}
},
"object": {
"type": "Identifier",
"start": 5657,
"end": 5663,
"start": 7535,
"end": 7541,
"loc": {
"start": {
"line": 199,
"line": 263,
"column": 56
},
"end": {
"line": 199,
"line": 263,
"column": 62
}
},
@ -2702,15 +2738,15 @@
},
"property": {
"type": "Identifier",
"start": 5664,
"end": 5669,
"start": 7542,
"end": 7547,
"loc": {
"start": {
"line": 199,
"line": 263,
"column": 63
},
"end": {
"line": 199,
"line": 263,
"column": 68
}
},
@ -2730,14 +2766,14 @@
{
"attributes": [
{
"start": 7374,
"end": 7385,
"start": 10262,
"end": 10273,
"type": "Attribute",
"name": "name",
"value": [
{
"start": 7380,
"end": 7384,
"start": 10268,
"end": 10272,
"type": "Text",
"raw": "cell",
"data": "cell"
@ -2745,26 +2781,26 @@
]
},
{
"start": 7386,
"end": 7397,
"start": 10274,
"end": 10285,
"type": "Attribute",
"name": "row",
"value": [
{
"start": 7391,
"end": 7396,
"start": 10279,
"end": 10284,
"type": "MustacheTag",
"expression": {
"type": "Identifier",
"start": 7392,
"end": 7395,
"start": 10280,
"end": 10283,
"loc": {
"start": {
"line": 245,
"line": 337,
"column": 38
},
"end": {
"line": 245,
"line": 337,
"column": 41
}
},
@ -2774,26 +2810,26 @@
]
},
{
"start": 7398,
"end": 7411,
"start": 10286,
"end": 10299,
"type": "Attribute",
"name": "cell",
"value": [
{
"start": 7404,
"end": 7410,
"start": 10292,
"end": 10298,
"type": "MustacheTag",
"expression": {
"type": "Identifier",
"start": 7405,
"end": 7409,
"start": 10293,
"end": 10297,
"loc": {
"start": {
"line": 245,
"line": 337,
"column": 51
},
"end": {
"line": 245,
"line": 337,
"column": 55
}
},
@ -2805,69 +2841,69 @@
],
"children": [
{
"start": 7412,
"end": 7429,
"start": 10300,
"end": 10317,
"type": "Text",
"raw": "\n ",
"data": "\n "
},
{
"start": 7429,
"end": 7495,
"start": 10317,
"end": 10383,
"type": "MustacheTag",
"expression": {
"type": "ConditionalExpression",
"start": 7430,
"end": 7494,
"start": 10318,
"end": 10382,
"loc": {
"start": {
"line": 246,
"line": 338,
"column": 17
},
"end": {
"line": 246,
"line": 338,
"column": 81
}
},
"test": {
"type": "MemberExpression",
"start": 7430,
"end": 7448,
"start": 10318,
"end": 10336,
"loc": {
"start": {
"line": 246,
"line": 338,
"column": 17
},
"end": {
"line": 246,
"line": 338,
"column": 35
}
},
"object": {
"type": "MemberExpression",
"start": 7430,
"end": 7440,
"start": 10318,
"end": 10328,
"loc": {
"start": {
"line": 246,
"line": 338,
"column": 17
},
"end": {
"line": 246,
"line": 338,
"column": 27
}
},
"object": {
"type": "Identifier",
"start": 7430,
"end": 7437,
"start": 10318,
"end": 10325,
"loc": {
"start": {
"line": 246,
"line": 338,
"column": 17
},
"end": {
"line": 246,
"line": 338,
"column": 24
}
},
@ -2875,15 +2911,15 @@
},
"property": {
"type": "Identifier",
"start": 7438,
"end": 7439,
"start": 10326,
"end": 10327,
"loc": {
"start": {
"line": 246,
"line": 338,
"column": 25
},
"end": {
"line": 246,
"line": 338,
"column": 26
}
},
@ -2894,15 +2930,15 @@
},
"property": {
"type": "Identifier",
"start": 7441,
"end": 7448,
"start": 10329,
"end": 10336,
"loc": {
"start": {
"line": 246,
"line": 338,
"column": 28
},
"end": {
"line": 246,
"line": 338,
"column": 35
}
},
@ -2913,57 +2949,57 @@
},
"consequent": {
"type": "CallExpression",
"start": 7451,
"end": 7481,
"start": 10339,
"end": 10369,
"loc": {
"start": {
"line": 246,
"line": 338,
"column": 38
},
"end": {
"line": 246,
"line": 338,
"column": 68
}
},
"callee": {
"type": "MemberExpression",
"start": 7451,
"end": 7469,
"start": 10339,
"end": 10357,
"loc": {
"start": {
"line": 246,
"line": 338,
"column": 38
},
"end": {
"line": 246,
"line": 338,
"column": 56
}
},
"object": {
"type": "MemberExpression",
"start": 7451,
"end": 7461,
"start": 10339,
"end": 10349,
"loc": {
"start": {
"line": 246,
"line": 338,
"column": 38
},
"end": {
"line": 246,
"line": 338,
"column": 48
}
},
"object": {
"type": "Identifier",
"start": 7451,
"end": 7458,
"start": 10339,
"end": 10346,
"loc": {
"start": {
"line": 246,
"line": 338,
"column": 38
},
"end": {
"line": 246,
"line": 338,
"column": 45
}
},
@ -2971,15 +3007,15 @@
},
"property": {
"type": "Identifier",
"start": 7459,
"end": 7460,
"start": 10347,
"end": 10348,
"loc": {
"start": {
"line": 246,
"line": 338,
"column": 46
},
"end": {
"line": 246,
"line": 338,
"column": 47
}
},
@ -2990,15 +3026,15 @@
},
"property": {
"type": "Identifier",
"start": 7462,
"end": 7469,
"start": 10350,
"end": 10357,
"loc": {
"start": {
"line": 246,
"line": 338,
"column": 49
},
"end": {
"line": 246,
"line": 338,
"column": 56
}
},
@ -3010,29 +3046,29 @@
"arguments": [
{
"type": "MemberExpression",
"start": 7470,
"end": 7480,
"start": 10358,
"end": 10368,
"loc": {
"start": {
"line": 246,
"line": 338,
"column": 57
},
"end": {
"line": 246,
"line": 338,
"column": 67
}
},
"object": {
"type": "Identifier",
"start": 7470,
"end": 7474,
"start": 10358,
"end": 10362,
"loc": {
"start": {
"line": 246,
"line": 338,
"column": 57
},
"end": {
"line": 246,
"line": 338,
"column": 61
}
},
@ -3040,15 +3076,15 @@
},
"property": {
"type": "Identifier",
"start": 7475,
"end": 7480,
"start": 10363,
"end": 10368,
"loc": {
"start": {
"line": 246,
"line": 338,
"column": 62
},
"end": {
"line": 246,
"line": 338,
"column": 67
}
},
@ -3062,29 +3098,29 @@
},
"alternate": {
"type": "MemberExpression",
"start": 7484,
"end": 7494,
"start": 10372,
"end": 10382,
"loc": {
"start": {
"line": 246,
"line": 338,
"column": 71
},
"end": {
"line": 246,
"line": 338,
"column": 81
}
},
"object": {
"type": "Identifier",
"start": 7484,
"end": 7488,
"start": 10372,
"end": 10376,
"loc": {
"start": {
"line": 246,
"line": 338,
"column": 71
},
"end": {
"line": 246,
"line": 338,
"column": 75
}
},
@ -3092,15 +3128,15 @@
},
"property": {
"type": "Identifier",
"start": 7489,
"end": 7494,
"start": 10377,
"end": 10382,
"loc": {
"start": {
"line": 246,
"line": 338,
"column": 76
},
"end": {
"line": 246,
"line": 338,
"column": 81
}
},
@ -3112,8 +3148,8 @@
}
},
{
"start": 7495,
"end": 7510,
"start": 10383,
"end": 10398,
"type": "Text",
"raw": "\n ",
"data": "\n "
@ -3128,14 +3164,14 @@
{
"attributes": [
{
"start": 8046,
"end": 8065,
"start": 10934,
"end": 10953,
"type": "Attribute",
"name": "name",
"value": [
{
"start": 8052,
"end": 8064,
"start": 10940,
"end": 10952,
"type": "Text",
"raw": "expanded-row",
"data": "expanded-row"
@ -3143,26 +3179,26 @@
]
},
{
"start": 8066,
"end": 8077,
"start": 10954,
"end": 10965,
"type": "Attribute",
"name": "row",
"value": [
{
"start": 8071,
"end": 8076,
"start": 10959,
"end": 10964,
"type": "MustacheTag",
"expression": {
"type": "Identifier",
"start": 8072,
"end": 8075,
"start": 10960,
"end": 10963,
"loc": {
"start": {
"line": 265,
"line": 357,
"column": 48
},
"end": {
"line": 265,
"line": 357,
"column": 51
}
},
@ -15504,6 +15540,49 @@
"forwarded_events": [],
"dispatched_events": []
},
"ToolbarBatchActions": {
"moduleName": "ToolbarBatchActions",
"props": [
[
"formatTotalSelected",
{
"kind": "let",
"type": "(totalSelected: number) => string",
"description": "Override the total items selected text"
}
]
],
"slots": [
[
"default",
{
"attributes": [],
"children": [],
"default": true,
"default_value": ""
}
]
],
"forwarded_events": [],
"dispatched_events": []
},
"ToolbarContent": {
"moduleName": "ToolbarContent",
"props": [],
"slots": [
[
"default",
{
"attributes": [],
"children": [],
"default": true,
"default_value": ""
}
]
],
"forwarded_events": [],
"dispatched_events": []
},
"ToolbarSearch": {
"moduleName": "ToolbarSearch",
"props": [

View file

@ -1,9 +1,9 @@
---
components: ["DataTable", "Toolbar", "ToolbarSearch"]
components: ["DataTable", "Toolbar", "ToolbarContent", "ToolbarSearch", "ToolbarBatchActions"]
---
<script>
import { DataTable, DataTableSkeleton, Toolbar, ToolbarSearch, Button, Link } from "carbon-components-svelte";
import { DataTable, DataTableSkeleton, Toolbar, ToolbarContent, ToolbarSearch, Button, Link } from "carbon-components-svelte";
import Launch16 from "carbon-icons-svelte/lib/Launch16";
import Preview from "../../components/Preview.svelte";
</script>
@ -247,8 +247,10 @@ The slot name for the table header cells is `"cell-header"`.
]}"
>
<Toolbar>
<ToolbarSearch />
<Button>Create</Button>
<ToolbarContent>
<ToolbarSearch />
<Button>Create</Button>
</ToolbarContent>
</Toolbar>
</DataTable>
@ -307,8 +309,10 @@ The slot name for the table header cells is `"cell-header"`.
]}"
>
<Toolbar size="sm">
<ToolbarSearch />
<Button size="small">Create</Button>
<ToolbarContent>
<ToolbarSearch />
<Button>Create</Button>
</ToolbarContent>
</Toolbar>
</DataTable>
@ -587,6 +591,23 @@ The slot name for the table header cells is `"cell-header"`.
]}"
/>
### Selectable
<FileSource src="/framed/DataTable/SelectableDataTable" />
### Initial selected rows
<FileSource src="/framed/DataTable/DataTableBatchSelection" />
### Selectable with batch actions
<FileSource src="/framed/DataTable/DataTableBatchSelectionToolbar" />
### Selectable (radio)
<FileSource src="/framed/DataTable/RadioSelectableDataTable" />
### Expandable
<DataTable expandable

View file

@ -0,0 +1,29 @@
<script>
import { DataTable } from "carbon-components-svelte";
const headers = [
{ key: "name", value: "Name" },
{ key: "port", value: "Port" },
{ key: "rule", value: "Rule" },
];
const rows = [
{ id: "a", name: "Load Balancer 3", port: 3000, rule: "Round robin" },
{ id: "b", name: "Load Balancer 1", port: 443, rule: "Round robin" },
{ id: "c", name: "Load Balancer 2", port: 80, rule: "DNS delegation" },
{ id: "d", name: "Load Balancer 6", port: 3000, rule: "Round robin" },
{ id: "e", name: "Load Balancer 4", port: 443, rule: "Round robin" },
{ id: "f", name: "Load Balancer 5", port: 80, rule: "DNS delegation" },
];
let selectedRowIds = [rows[0].id, rows[1].id];
$: console.log("selectedRowIds", selectedRowIds);
</script>
<DataTable
batchSelection
bind:selectedRowIds
headers="{headers}"
rows="{rows}"
/>

View file

@ -0,0 +1,42 @@
<script>
import {
DataTable,
Toolbar,
ToolbarContent,
ToolbarSearch,
ToolbarBatchActions,
Button,
} from "carbon-components-svelte";
import Save16 from "carbon-icons-svelte/lib/Save16";
const headers = [
{ key: "name", value: "Name" },
{ key: "port", value: "Port" },
{ key: "rule", value: "Rule" },
];
const rows = [
{ id: "a", name: "Load Balancer 3", port: 3000, rule: "Round robin" },
{ id: "b", name: "Load Balancer 1", port: 443, rule: "Round robin" },
{ id: "c", name: "Load Balancer 2", port: 80, rule: "DNS delegation" },
{ id: "d", name: "Load Balancer 6", port: 3000, rule: "Round robin" },
{ id: "e", name: "Load Balancer 4", port: 443, rule: "Round robin" },
{ id: "f", name: "Load Balancer 5", port: 80, rule: "DNS delegation" },
];
let selectedRowIds = [rows[0].id, rows[1].id];
$: console.log("selectedRowIds", selectedRowIds);
</script>
<DataTable batchSelection bind:selectedRowIds headers="{headers}" rows="{rows}">
<Toolbar>
<ToolbarBatchActions>
<Button icon="{Save16}">Save</Button>
</ToolbarBatchActions>
<ToolbarContent>
<ToolbarSearch />
<Button>Create</Button>
</ToolbarContent>
</Toolbar>
</DataTable>

View file

@ -0,0 +1,24 @@
<script>
import { DataTable } from "carbon-components-svelte";
const headers = [
{ key: "name", value: "Name" },
{ key: "port", value: "Port" },
{ key: "rule", value: "Rule" },
];
const rows = [
{ id: "a", name: "Load Balancer 3", port: 3000, rule: "Round robin" },
{ id: "b", name: "Load Balancer 1", port: 443, rule: "Round robin" },
{ id: "c", name: "Load Balancer 2", port: 80, rule: "DNS delegation" },
{ id: "d", name: "Load Balancer 6", port: 3000, rule: "Round robin" },
{ id: "e", name: "Load Balancer 4", port: 443, rule: "Round robin" },
{ id: "f", name: "Load Balancer 5", port: 80, rule: "DNS delegation" },
];
let selectedRowIds = [rows[1].id];
$: console.log("selectedRowIds", selectedRowIds);
</script>
<DataTable radio bind:selectedRowIds headers="{headers}" rows="{rows}" />

View file

@ -0,0 +1,24 @@
<script>
import { DataTable } from "carbon-components-svelte";
const headers = [
{ key: "name", value: "Name" },
{ key: "port", value: "Port" },
{ key: "rule", value: "Rule" },
];
const rows = [
{ id: "a", name: "Load Balancer 3", port: 3000, rule: "Round robin" },
{ id: "b", name: "Load Balancer 1", port: 443, rule: "Round robin" },
{ id: "c", name: "Load Balancer 2", port: 80, rule: "DNS delegation" },
{ id: "d", name: "Load Balancer 6", port: 3000, rule: "Round robin" },
{ id: "e", name: "Load Balancer 4", port: 443, rule: "Round robin" },
{ id: "f", name: "Load Balancer 5", port: 80, rule: "DNS delegation" },
];
let selectedRowIds = [];
$: console.log("selectedRowIds", selectedRowIds);
</script>
<DataTable selectable bind:selectedRowIds headers="{headers}" rows="{rows}" />

View file

@ -0,0 +1,43 @@
<script>
/**
* Specify whether the checkbox is checked
* @type {boolean} [checked=false]
*/
export let checked = false;
/**
* Specify whether the checkbox is indeterminate
* @type {boolean} [indeterminate=false]
*/
export let indeterminate = false;
/**
* Specify the title attribute for the label element
* @type {string} [title]
*/
export let title = undefined;
/**
* Set an id for the input label
* @type {string} [id]
*/
export let id = "ccs-" + Math.random().toString(36);
</script>
<input
type="checkbox"
class:bx--checkbox="{true}"
checked="{indeterminate ? false : checked}"
indeterminate="{indeterminate}"
id="{id}"
{...$$restProps}
aria-label="{undefined}"
aria-checked="{indeterminate ? 'mixed' : checked}"
on:change
/>
<label
for="{id}"
title="{title}"
aria-label="{$$props['aria-label']}"
class:bx--checkbox-label="{true}"
></label>

View file

@ -1,2 +1,3 @@
export { default as Checkbox } from "./Checkbox.svelte";
export { default as CheckboxSkeleton } from "./Checkbox.Skeleton.svelte";
export { default as InlineCheckbox } from "./InlineCheckbox.svelte";

View file

@ -61,6 +61,31 @@
*/
export let expandedRowIds = [];
/**
* Set to `true` for the radio selection variant
* @type {boolean} [radio=false]
*/
export let radio = false;
/**
* Set to `true` for the selectable variant
* Automatically set to `true` if `radio` or `batchSelection` are `true`
* @type {boolean} [selectable=false]
*/
export let selectable = false;
/**
* Set to `true` to enable batch selection
* @type {boolean} [batchSelection=false]
*/
export let batchSelection = false;
/**
* Specify the row ids to be selected
* @type {string[]} [selectedRowIds=[]]
*/
export let selectedRowIds = [];
/**
* Set to `true` to enable a sticky header
* @type {boolean} [stickyHeader=false]
@ -70,6 +95,8 @@
import { createEventDispatcher, setContext } from "svelte";
import { writable, derived } from "svelte/store";
import ChevronRight16 from "carbon-icons-svelte/lib/ChevronRight16";
import { InlineCheckbox } from "../Checkbox";
import { RadioButton } from "../RadioButton";
import Table from "./Table.svelte";
import TableBody from "./TableBody.svelte";
import TableCell from "./TableCell.svelte";
@ -84,6 +111,7 @@
descending: "none",
};
const dispatch = createEventDispatcher();
const batchSelectedIds = writable(false);
const tableSortable = writable(sortable);
const sortHeader = writable({
id: null,
@ -101,6 +129,10 @@
setContext("DataTable", {
sortHeader,
tableSortable,
batchSelectedIds,
resetSelectedRowIds: () => {
selectedRowIds = [];
},
add: (id) => {
headerItems.update((_) => [..._, id]);
},
@ -113,7 +145,13 @@
(a, id) => ({ ...a, [id]: true }),
{}
);
let selectAll = false;
$: batchSelectedIds.set(selectedRowIds);
$: indeterminate =
selectedRowIds.length > 0 && selectedRowIds.length < rows.length;
$: if (batchExpansion) expandable = true;
$: if (radio || batchSelection) selectable = true;
$: tableSortable.set(sortable);
$: headerKeys = headers.map(({ key }) => key);
$: rows = rows.map((row) => ({
@ -180,6 +218,32 @@
{/if}
</th>
{/if}
{#if selectable && !batchSelection}
<th scope="col"></th>
{/if}
{#if batchSelection && !radio}
<th scope="col" class:bx--table-column-checkbox="{true}">
<InlineCheckbox
aria-label="Select all rows"
checked="{selectAll}"
indeterminate="{indeterminate}"
on:change="{(e) => {
if (indeterminate) {
e.target.checked = false;
selectAll = false;
selectedRowIds = [];
return;
}
if (e.target.checked) {
selectedRowIds = rows.map((row) => row.id);
} else {
selectedRowIds = [];
}
}}"
/>
</th>
{/if}
{#each headers as header, i (header.key)}
<TableHeader
on:click="{() => {
@ -235,6 +299,34 @@
</button>
</TableCell>
{/if}
{#if selectable}
<td
class:bx--table-column-checkbox="{true}"
class:bx--table-column-radio="{radio}"
>
{#if radio}
<RadioButton
name="select-row-{row.id}"
checked="{selectedRowIds.includes(row.id)}"
on:change="{() => {
selectedRowIds = [row.id];
}}"
/>
{:else}
<InlineCheckbox
name="select-row-{row.id}"
checked="{selectedRowIds.includes(row.id)}"
on:change="{() => {
if (selectedRowIds.includes(row.id)) {
selectedRowIds = selectedRowIds.filter((id) => id !== row.id);
} else {
selectedRowIds = [...selectedRowIds, row.id];
}
}}"
/>
{/if}
</td>
{/if}
{#each row.cells as cell, j (cell.key)}
<TableCell
on:click="{() => {

View file

@ -0,0 +1,44 @@
<script>
/**
* Override the total items selected text
* @type {(totalSelected: number) => string} [formatTotalSelected = (totalSelected: number) => string]
*/
export let formatTotalSelected = (totalSelected) =>
`${totalSelected} item${totalSelected === 1 ? "" : "s"} selected`;
import { onMount, getContext } from "svelte";
import { Button } from "../Button";
let batchSelectedIds = [];
$: showActions = batchSelectedIds.length > 0;
const ctx = getContext("DataTable");
const unsubscribe = ctx.batchSelectedIds.subscribe((value) => {
batchSelectedIds = value;
});
onMount(() => unsubscribe);
</script>
<div
class:bx--batch-actions="{true}"
class:bx--batch-actions--active="{showActions}"
{...$$restProps}
>
<div class:bx--batch-summary="{true}">
<p class:bx--batch-summary__para="{true}">
<span> {formatTotalSelected(batchSelectedIds.length)} </span>
</p>
</div>
<div class:bx--action-list="{true}">
<slot />
<Button
class="bx--batch-summary__cancel"
tabindex="{showActions ? '0' : '-1'}"
on:click="{ctx.resetSelectedRowIds}"
>
Cancel
</Button>
</div>
</div>

View file

@ -0,0 +1,3 @@
<div class:bx--toolbar-content="{true}">
<slot />
</div>

View file

@ -7,4 +7,6 @@ export { default as TableHead } from "./TableHead.svelte";
export { default as TableHeader } from "./TableHeader.svelte";
export { default as TableRow } from "./TableRow.svelte";
export { default as Toolbar } from "./Toolbar.svelte";
export { default as ToolbarContent } from "./ToolbarContent.svelte";
export { default as ToolbarSearch } from "./ToolbarSearch.svelte";
export { default as ToolbarBatchActions } from "./ToolbarBatchActions.svelte";

View file

@ -24,7 +24,9 @@ export {
TableHeader,
TableRow,
Toolbar,
ToolbarContent,
ToolbarSearch,
ToolbarBatchActions,
} from "./DataTable";
export { DataTableSkeleton } from "./DataTableSkeleton";
export { DatePicker, DatePickerInput, DatePickerSkeleton } from "./DatePicker";

40
types/index.d.ts vendored
View file

@ -849,6 +849,31 @@ export class DataTable extends CarbonSvelteComponent {
*/
expandedRowIds?: string[];
/**
* Set to `true` for the radio selection variant
* @default false
*/
radio?: boolean;
/**
* Set to `true` for the selectable variant
* Automatically set to `true` if `radio` or `batchSelection` are `true`
* @default false
*/
selectable?: boolean;
/**
* Set to `true` to enable batch selection
* @default false
*/
batchSelection?: boolean;
/**
* Specify the row ids to be selected
* @default []
*/
selectedRowIds?: string[];
/**
* Set to `true` to enable a sticky header
* @default false
@ -5091,6 +5116,21 @@ export class Toolbar extends CarbonSvelteComponent {
$$slot_def: { default: {} };
}
export class ToolbarBatchActions extends CarbonSvelteComponent {
$$prop_def: {
/**
* Override the total items selected text
*/
formatTotalSelected?: (totalSelected: number) => string;
};
$$slot_def: { default: {} };
}
export class ToolbarContent extends CarbonSvelteComponent {
$$slot_def: { default: {} };
}
export class ToolbarSearch extends CarbonSvelteComponent {
$$prop_def: {
/**