mirror of
https://github.com/carbon-design-system/carbon-components-svelte.git
synced 2025-09-15 10:21:05 +00:00
feat(data-table): support radio, selectable variants with batch actions
This commit is contained in:
parent
611d72bcf3
commit
f43b132088
15 changed files with 662 additions and 156 deletions
|
@ -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="{() => {
|
||||
|
|
44
src/DataTable/ToolbarBatchActions.svelte
Normal file
44
src/DataTable/ToolbarBatchActions.svelte
Normal 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>
|
3
src/DataTable/ToolbarContent.svelte
Normal file
3
src/DataTable/ToolbarContent.svelte
Normal file
|
@ -0,0 +1,3 @@
|
|||
<div class:bx--toolbar-content="{true}">
|
||||
<slot />
|
||||
</div>
|
|
@ -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";
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue