feat(data-table): support non-selectable rows (#1166)

Closes #1148
This commit is contained in:
metonym 2022-03-12 19:36:02 -08:00 committed by GitHub
commit 95a1dfa1af
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 129 additions and 28 deletions

View file

@ -997,6 +997,7 @@ export interface DataTableCell {
| nonExpandableRowIds | <code>let</code> | No | <code>DataTableRowId[]</code> | <code>[]</code> | Specify the ids for rows that should not be expandable | | nonExpandableRowIds | <code>let</code> | No | <code>DataTableRowId[]</code> | <code>[]</code> | Specify the ids for rows that should not be expandable |
| radio | <code>let</code> | No | <code>boolean</code> | <code>false</code> | Set to `true` for the radio selection variant | | radio | <code>let</code> | No | <code>boolean</code> | <code>false</code> | Set to `true` for the radio selection variant |
| batchSelection | <code>let</code> | No | <code>boolean</code> | <code>false</code> | Set to `true` to enable batch selection | | batchSelection | <code>let</code> | No | <code>boolean</code> | <code>false</code> | Set to `true` to enable batch selection |
| nonSelectableRowIds | <code>let</code> | No | <code>DataTableRowId[]</code> | <code>[]</code> | Specify the ids of rows that should not be selectable |
| stickyHeader | <code>let</code> | No | <code>boolean</code> | <code>false</code> | Set to `true` to enable a sticky header | | stickyHeader | <code>let</code> | No | <code>boolean</code> | <code>false</code> | Set to `true` to enable a sticky header |
| useStaticWidth | <code>let</code> | No | <code>boolean</code> | <code>false</code> | Set to `true` to use static width | | useStaticWidth | <code>let</code> | No | <code>boolean</code> | <code>false</code> | Set to `true` to use static width |
| pageSize | <code>let</code> | No | <code>number</code> | <code>0</code> | Specify the number of items to display in a page | | pageSize | <code>let</code> | No | <code>number</code> | <code>0</code> | Specify the number of items to display in a page |

View file

@ -2367,6 +2367,17 @@
"constant": false, "constant": false,
"reactive": true "reactive": true
}, },
{
"name": "nonSelectableRowIds",
"kind": "let",
"description": "Specify the ids of rows that should not be selectable",
"type": "DataTableRowId[]",
"value": "[]",
"isFunction": false,
"isFunctionDeclaration": false,
"constant": false,
"reactive": false
},
{ {
"name": "stickyHeader", "name": "stickyHeader",
"kind": "let", "kind": "let",

View file

@ -1044,6 +1044,12 @@ In the following example, each row in the sortable data table has an overflow me
<FileSource src="/framed/DataTable/RadioSelectableDataTable" /> <FileSource src="/framed/DataTable/RadioSelectableDataTable" />
### Non-selectable rows
Use `nonSelectableRowIds` to specify the ids for rows that should not be selectable.
<FileSource src="/framed/DataTable/DataTableNonSelectableRows" />
### Expandable ### Expandable
<DataTable expandable <DataTable expandable

View file

@ -0,0 +1,62 @@
<script>
import { DataTable } from "carbon-components-svelte";
const rows = [
{
id: "a",
name: "Load Balancer 3",
protocol: "HTTP",
port: 3000,
rule: "Round robin",
},
{
id: "b",
name: "Load Balancer 1",
protocol: "HTTP",
port: 443,
rule: "Round robin",
},
{
id: "c",
name: "Load Balancer 2",
protocol: "HTTP",
port: 80,
rule: "DNS delegation",
},
{
id: "d",
name: "Load Balancer 6",
protocol: "HTTP",
port: 3000,
rule: "Round robin",
},
{
id: "e",
name: "Load Balancer 4",
protocol: "HTTP",
port: 443,
rule: "Round robin",
},
{
id: "f",
name: "Load Balancer 5",
protocol: "HTTP",
port: 80,
rule: "DNS delegation",
},
];
</script>
<DataTable
batchSelection
nonSelectableRowIds="{rows
.filter((row) => row.port === 3000)
.map((row) => row.id)}"
headers="{[
{ key: 'name', value: 'Name' },
{ key: 'protocol', value: 'Protocol' },
{ key: 'port', value: 'Port' },
{ key: 'rule', value: 'Rule' },
]}"
rows="{rows}"
/>

View file

@ -94,6 +94,12 @@
*/ */
export let selectedRowIds = []; export let selectedRowIds = [];
/**
* Specify the ids of rows that should not be selectable
* @type {DataTableRowId[]}
*/
export let nonSelectableRowIds = [];
/** Set to `true` to enable a sticky header */ /** Set to `true` to enable a sticky header */
export let stickyHeader = false; export let stickyHeader = false;
@ -164,15 +170,22 @@
{} {}
); );
$: selectAll = rows.length > 0 && selectedRowIds.length === rows.length;
let refSelectAll = null; let refSelectAll = null;
$: batchSelectedIds.set(selectedRowIds); $: batchSelectedIds.set(selectedRowIds);
$: expandableRowIds = rows $: rowIds = rows.map((row) => row.id);
.map((row) => row.id) $: expandableRowIds = rowIds.filter(
.filter((id) => !nonExpandableRowIds.includes(id)); (id) => !nonExpandableRowIds.includes(id)
);
$: selectableRowIds = rowIds.filter(
(id) => !nonSelectableRowIds.includes(id)
);
$: selectAll =
selectableRowIds.length > 0 &&
selectedRowIds.length === selectableRowIds.length;
$: indeterminate = $: indeterminate =
selectedRowIds.length > 0 && selectedRowIds.length < rows.length; selectedRowIds.length > 0 &&
selectedRowIds.length < selectableRowIds.length;
$: if (batchExpansion) { $: if (batchExpansion) {
expandable = true; expandable = true;
expanded = expandedRowIds.length === expandableRowIds.length; expanded = expandedRowIds.length === expandableRowIds.length;
@ -293,7 +306,7 @@
} }
if (e.target.checked) { if (e.target.checked) {
selectedRowIds = rows.map((row) => row.id); selectedRowIds = selectableRowIds;
} else { } else {
selectedRowIds = []; selectedRowIds = [];
} }
@ -405,28 +418,30 @@
class:bx--table-column-checkbox="{true}" class:bx--table-column-checkbox="{true}"
class:bx--table-column-radio="{radio}" class:bx--table-column-radio="{radio}"
> >
{#if radio} {#if !nonSelectableRowIds.includes(row.id)}
<RadioButton {#if radio}
name="select-row-{row.id}" <RadioButton
checked="{selectedRowIds.includes(row.id)}" name="select-row-{row.id}"
on:change="{() => { checked="{selectedRowIds.includes(row.id)}"
selectedRowIds = [row.id]; on:change="{() => {
}}" selectedRowIds = [row.id];
/> }}"
{:else} />
<InlineCheckbox {:else}
name="select-row-{row.id}" <InlineCheckbox
checked="{selectedRowIds.includes(row.id)}" name="select-row-{row.id}"
on:change="{() => { checked="{selectedRowIds.includes(row.id)}"
if (selectedRowIds.includes(row.id)) { on:change="{() => {
selectedRowIds = selectedRowIds.filter( if (selectedRowIds.includes(row.id)) {
(id) => id !== row.id selectedRowIds = selectedRowIds.filter(
); (id) => id !== row.id
} else { );
selectedRowIds = [...selectedRowIds, row.id]; } else {
} selectedRowIds = [...selectedRowIds, row.id];
}}" }
/> }}"
/>
{/if}
{/if} {/if}
</td> </td>
{/if} {/if}

View file

@ -131,6 +131,12 @@ export interface DataTableProps
*/ */
selectedRowIds?: DataTableRowId[]; selectedRowIds?: DataTableRowId[];
/**
* Specify the ids of rows that should not be selectable
* @default []
*/
nonSelectableRowIds?: DataTableRowId[];
/** /**
* Set to `true` to enable a sticky header * Set to `true` to enable a sticky header
* @default false * @default false