feat(data-table): allow sorting to be disabled for a specific header

This commit is contained in:
Eric Y Liu 2021-04-02 11:51:32 -07:00
commit 766ee936ed
8 changed files with 79 additions and 46 deletions

View file

@ -899,7 +899,7 @@ export interface DataTableEmptyHeader {
key: DataTableKey;
empty: boolean;
display?: (item: Value) => DataTableValue;
sort?: (a: DataTableValue, b: DataTableValue) => 0 | -1 | 1;
sort?: false | ((a: DataTableValue, b: DataTableValue) => 0 | -1 | 1);
columnMenu?: boolean;
}
@ -907,7 +907,7 @@ export interface DataTableNonEmptyHeader {
key: DataTableKey;
value: DataTableValue;
display?: (item: Value) => DataTableValue;
sort?: (a: DataTableValue, b: DataTableValue) => 0 | -1 | 1;
sort?: false | ((a: DataTableValue, b: DataTableValue) => 0 | -1 | 1);
columnMenu?: boolean;
}
@ -957,16 +957,16 @@ export interface DataTableCell {
### Events
| Event name | Type | Detail |
| :------------------- | :--------- | :----------------------------------------------------------------------------------------------------- |
| click | dispatched | <code>{ header?: DataTableHeader; row?: DataTableRow; cell?: DataTableCell; }</code> |
| click:header--expand | dispatched | <code>{ expanded: boolean; }</code> |
| click:header | dispatched | <code>{ header: DataTableHeader; sortDirection: "ascending" &#124; "descending" &#124; "none" }</code> |
| click:row | dispatched | <code>DataTableRow</code> |
| mouseenter:row | dispatched | <code>DataTableRow</code> |
| mouseleave:row | dispatched | <code>DataTableRow</code> |
| click:row--expand | dispatched | <code>{ expanded: boolean; row: DataTableRow; }</code> |
| click:cell | dispatched | <code>DataTableCell</code> |
| Event name | Type | Detail |
| :------------------- | :--------- | :------------------------------------------------------------------------------------------------------ |
| click | dispatched | <code>{ header?: DataTableHeader; row?: DataTableRow; cell?: DataTableCell; }</code> |
| click:header--expand | dispatched | <code>{ expanded: boolean; }</code> |
| click:header | dispatched | <code>{ header: DataTableHeader; sortDirection?: "ascending" &#124; "descending" &#124; "none" }</code> |
| click:row | dispatched | <code>DataTableRow</code> |
| mouseenter:row | dispatched | <code>DataTableRow</code> |
| mouseleave:row | dispatched | <code>DataTableRow</code> |
| click:row--expand | dispatched | <code>{ expanded: boolean; row: DataTableRow; }</code> |
| click:cell | dispatched | <code>DataTableCell</code> |
## `DataTableSkeleton`
@ -3772,11 +3772,12 @@ None.
### Props
| Prop name | Kind | Reactive | Type | Default value | Description |
| :-------------- | :--------------- | :------- | :------------------------ | ------------------------------------------------ | ------------------------------------ |
| scope | <code>let</code> | No | <code>string</code> | <code>"col"</code> | Specify the `scope` attribute |
| translateWithId | <code>let</code> | No | <code>() => string</code> | <code>() => ""</code> | Override the default id translations |
| id | <code>let</code> | No | <code>string</code> | <code>"ccs-" + Math.random().toString(36)</code> | Set an id for the top-level element |
| Prop name | Kind | Reactive | Type | Default value | Description |
| :-------------- | :--------------- | :------- | :------------------------ | ------------------------------------------------ | ------------------------------------------------------ |
| disableSorting | <code>let</code> | No | <code>boolean</code> | <code>false</code> | Set to `true` to disable sorting on this specific cell |
| scope | <code>let</code> | No | <code>string</code> | <code>"col"</code> | Specify the `scope` attribute |
| translateWithId | <code>let</code> | No | <code>() => string</code> | <code>() => ""</code> | Override the default id translations |
| id | <code>let</code> | No | <code>string</code> | <code>"ccs-" + Math.random().toString(36)</code> | Set an id for the top-level element |
### Slots

View file

@ -2081,7 +2081,7 @@
{
"type": "dispatched",
"name": "click:header",
"detail": "{ header: DataTableHeader; sortDirection: \"ascending\" | \"descending\" | \"none\" }"
"detail": "{ header: DataTableHeader; sortDirection?: \"ascending\" | \"descending\" | \"none\" }"
},
{ "type": "dispatched", "name": "click:row", "detail": "DataTableRow" },
{
@ -2117,14 +2117,14 @@
"ts": "type DataTableValue = any"
},
{
"type": "{ key: DataTableKey; empty: boolean; display?: (item: Value) => DataTableValue; sort?: (a: DataTableValue, b: DataTableValue) => (0 | -1 | 1); columnMenu?: boolean; }",
"type": "{ key: DataTableKey; empty: boolean; display?: (item: Value) => DataTableValue; sort?: false | ((a: DataTableValue, b: DataTableValue) => (0 | -1 | 1)); columnMenu?: boolean; }",
"name": "DataTableEmptyHeader",
"ts": "interface DataTableEmptyHeader { key: DataTableKey; empty: boolean; display?: (item: Value) => DataTableValue; sort?: (a: DataTableValue, b: DataTableValue) => (0 | -1 | 1); columnMenu?: boolean; }"
"ts": "interface DataTableEmptyHeader { key: DataTableKey; empty: boolean; display?: (item: Value) => DataTableValue; sort?: false | ((a: DataTableValue, b: DataTableValue) => (0 | -1 | 1)); columnMenu?: boolean; }"
},
{
"type": "{ key: DataTableKey; value: DataTableValue; display?: (item: Value) => DataTableValue; sort?: (a: DataTableValue, b: DataTableValue) => (0 | -1 | 1); columnMenu?: boolean; }",
"type": "{ key: DataTableKey; value: DataTableValue; display?: (item: Value) => DataTableValue; sort?: false | ((a: DataTableValue, b: DataTableValue) => (0 | -1 | 1)); columnMenu?: boolean; }",
"name": "DataTableNonEmptyHeader",
"ts": "interface DataTableNonEmptyHeader { key: DataTableKey; value: DataTableValue; display?: (item: Value) => DataTableValue; sort?: (a: DataTableValue, b: DataTableValue) => (0 | -1 | 1); columnMenu?: boolean; }"
"ts": "interface DataTableNonEmptyHeader { key: DataTableKey; value: DataTableValue; display?: (item: Value) => DataTableValue; sort?: false | ((a: DataTableValue, b: DataTableValue) => (0 | -1 | 1)); columnMenu?: boolean; }"
},
{
"type": "DataTableNonEmptyHeader | DataTableEmptyHeader",
@ -9441,6 +9441,16 @@
"moduleName": "TableHeader",
"filePath": "src/DataTable/TableHeader.svelte",
"props": [
{
"name": "disableSorting",
"kind": "let",
"description": "Set to `true` to disable sorting on this specific cell",
"type": "boolean",
"value": "false",
"isFunction": false,
"constant": false,
"reactive": false
},
{
"name": "scope",
"kind": "let",

View file

@ -550,12 +550,18 @@ The slot name for the table header cells is `"cell-header"`.
### Sortable
Set `sortable` to `true` to enable table column sorting.
To disable sorting on a specific column, set `sort` to `false` in the header object passed to `headers`.
In the example below, the "Rule" column is not sortable.
<DataTable sortable
headers="{[
{ key: "name", value: "Name" },
{ key: "protocol", value: "Protocol" },
{ key: "port", value: "Port" },
{ key: "rule", value: "Rule" }
{ key: "rule", value: "Rule", sort: false }
]}"
rows="{[
{

View file

@ -2,8 +2,8 @@
/**
* @typedef {string} DataTableKey
* @typedef {any} DataTableValue
* @typedef {{ key: DataTableKey; empty: boolean; display?: (item: Value) => DataTableValue; sort?: (a: DataTableValue, b: DataTableValue) => (0 | -1 | 1); columnMenu?: boolean; }} DataTableEmptyHeader
* @typedef {{ key: DataTableKey; value: DataTableValue; display?: (item: Value) => DataTableValue; sort?: (a: DataTableValue, b: DataTableValue) => (0 | -1 | 1); columnMenu?: boolean; }} DataTableNonEmptyHeader
* @typedef {{ key: DataTableKey; empty: boolean; display?: (item: Value) => DataTableValue; sort?: false | ((a: DataTableValue, b: DataTableValue) => (0 | -1 | 1)); columnMenu?: boolean; }} DataTableEmptyHeader
* @typedef {{ key: DataTableKey; value: DataTableValue; display?: (item: Value) => DataTableValue; sort?: false | ((a: DataTableValue, b: DataTableValue) => (0 | -1 | 1)); columnMenu?: boolean; }} DataTableNonEmptyHeader
* @typedef {DataTableNonEmptyHeader | DataTableEmptyHeader} DataTableHeader
* @typedef {{ id: any; [key: string]: DataTableValue; }} DataTableRow
* @typedef {string} DataTableRowId
@ -13,7 +13,7 @@
* @slot {{ row: DataTableRow; cell: DataTableCell; }} cell
* @event {{ header?: DataTableHeader; row?: DataTableRow; cell?: DataTableCell; }} click
* @event {{ expanded: boolean; }} click:header--expand
* @event {{ header: DataTableHeader; sortDirection: "ascending" | "descending" | "none" }} click:header
* @event {{ header: DataTableHeader; sortDirection?: "ascending" | "descending" | "none" }} click:header
* @event {DataTableRow} click:row
* @event {DataTableRow} mouseenter:row
* @event {DataTableRow} mouseleave:row
@ -250,20 +250,26 @@
<th scope="col"></th>
{:else}
<TableHeader
disableSorting="{header.sort === false}"
on:click="{() => {
dispatch('click', { header });
let active = header.key === $sortHeader.key;
let currentSortDirection = active
? $sortHeader.sortDirection
: 'none';
let sortDirection = sortDirectionMap[currentSortDirection];
dispatch('click:header', { header, sortDirection });
sortHeader.set({
id: sortDirection === 'none' ? null : $thKeys[header.key],
key: header.key,
sort: header.sort,
sortDirection,
});
if (header.sort === false) {
dispatch('click:header', { header });
} else {
let active = header.key === $sortHeader.key;
let currentSortDirection = active
? $sortHeader.sortDirection
: 'none';
let sortDirection = sortDirectionMap[currentSortDirection];
dispatch('click:header', { header, sortDirection });
sortHeader.set({
id: sortDirection === 'none' ? null : $thKeys[header.key],
key: header.key,
sort: header.sort,
sortDirection,
});
}
}}"
>
<slot name="cell-header" header="{header}">{header.value}</slot>

View file

@ -1,4 +1,7 @@
<script>
/** Set to `true` to disable sorting on this specific cell */
export let disableSorting = false;
/** Specify the `scope` attribute */
export let scope = "col";
@ -12,8 +15,8 @@
export let id = "ccs-" + Math.random().toString(36);
import { getContext } from "svelte";
import ArrowUp20 from "carbon-icons-svelte/lib/ArrowUp20";
import ArrowsVertical20 from "carbon-icons-svelte/lib/ArrowsVertical20";
import ArrowUp20 from "carbon-icons-svelte/lib/ArrowUp20/ArrowUp20.svelte";
import ArrowsVertical20 from "carbon-icons-svelte/lib/ArrowsVertical20/ArrowsVertical20.svelte";
const { sortHeader, tableSortable, add } = getContext("DataTable");
@ -24,7 +27,7 @@
$: ariaLabel = translateWithId();
</script>
{#if $tableSortable}
{#if $tableSortable && !disableSorting}
<th
aria-sort="{active ? $sortHeader.sortDirection : 'none'}"
scope="{scope}"

View file

@ -10,13 +10,14 @@
Button,
Link,
} from "../types";
import type { DataTableHeader } from "../types/DataTable/DataTable";
import Launch16 from "carbon-icons-svelte/lib/Launch16";
const headers = [
const headers: DataTableHeader[] = [
{ key: "name", value: "Name" },
{ key: "protocol", value: "Protocol" },
{ key: "port", value: "Port" },
{ key: "rule", value: "Rule" },
{ key: "rule", value: "Rule", sort: false },
];
const rows = [
{

View file

@ -9,7 +9,7 @@ export interface DataTableEmptyHeader {
key: DataTableKey;
empty: boolean;
display?: (item: Value) => DataTableValue;
sort?: (a: DataTableValue, b: DataTableValue) => 0 | -1 | 1;
sort?: false | ((a: DataTableValue, b: DataTableValue) => 0 | -1 | 1);
columnMenu?: boolean;
}
@ -17,7 +17,7 @@ export interface DataTableNonEmptyHeader {
key: DataTableKey;
value: DataTableValue;
display?: (item: Value) => DataTableValue;
sort?: (a: DataTableValue, b: DataTableValue) => 0 | -1 | 1;
sort?: false | ((a: DataTableValue, b: DataTableValue) => 0 | -1 | 1);
columnMenu?: boolean;
}
@ -141,7 +141,7 @@ export default class DataTable extends SvelteComponentTyped<
["click:header--expand"]: CustomEvent<{ expanded: boolean }>;
["click:header"]: CustomEvent<{
header: DataTableHeader;
sortDirection: "ascending" | "descending" | "none";
sortDirection?: "ascending" | "descending" | "none";
}>;
["click:row"]: CustomEvent<DataTableRow>;
["mouseenter:row"]: CustomEvent<DataTableRow>;

View file

@ -3,6 +3,12 @@ import { SvelteComponentTyped } from "svelte";
export interface TableHeaderProps
extends svelte.JSX.HTMLAttributes<HTMLElementTagNameMap["th"]> {
/**
* Set to `true` to disable sorting on this specific cell
* @default false
*/
disableSorting?: boolean;
/**
* Specify the `scope` attribute
* @default "col"