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; key: DataTableKey;
empty: boolean; empty: boolean;
display?: (item: 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; columnMenu?: boolean;
} }
@ -907,7 +907,7 @@ export interface DataTableNonEmptyHeader {
key: DataTableKey; key: DataTableKey;
value: DataTableValue; value: DataTableValue;
display?: (item: 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; columnMenu?: boolean;
} }
@ -958,10 +958,10 @@ export interface DataTableCell {
### Events ### Events
| Event name | Type | Detail | | Event name | Type | Detail |
| :------------------- | :--------- | :----------------------------------------------------------------------------------------------------- | | :------------------- | :--------- | :------------------------------------------------------------------------------------------------------ |
| click | dispatched | <code>{ header?: DataTableHeader; row?: DataTableRow; cell?: DataTableCell; }</code> | | click | dispatched | <code>{ header?: DataTableHeader; row?: DataTableRow; cell?: DataTableCell; }</code> |
| click:header--expand | dispatched | <code>{ expanded: boolean; }</code> | | click:header--expand | dispatched | <code>{ expanded: boolean; }</code> |
| click:header | dispatched | <code>{ header: DataTableHeader; sortDirection: "ascending" &#124; "descending" &#124; "none" }</code> | | click:header | dispatched | <code>{ header: DataTableHeader; sortDirection?: "ascending" &#124; "descending" &#124; "none" }</code> |
| click:row | dispatched | <code>DataTableRow</code> | | click:row | dispatched | <code>DataTableRow</code> |
| mouseenter:row | dispatched | <code>DataTableRow</code> | | mouseenter:row | dispatched | <code>DataTableRow</code> |
| mouseleave:row | dispatched | <code>DataTableRow</code> | | mouseleave:row | dispatched | <code>DataTableRow</code> |
@ -3773,7 +3773,8 @@ None.
### Props ### Props
| Prop name | Kind | Reactive | Type | Default value | Description | | 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 | | 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 | | 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 | | id | <code>let</code> | No | <code>string</code> | <code>"ccs-" + Math.random().toString(36)</code> | Set an id for the top-level element |

View file

@ -2081,7 +2081,7 @@
{ {
"type": "dispatched", "type": "dispatched",
"name": "click:header", "name": "click:header",
"detail": "{ header: DataTableHeader; sortDirection: \"ascending\" | \"descending\" | \"none\" }" "detail": "{ header: DataTableHeader; sortDirection?: \"ascending\" | \"descending\" | \"none\" }"
}, },
{ "type": "dispatched", "name": "click:row", "detail": "DataTableRow" }, { "type": "dispatched", "name": "click:row", "detail": "DataTableRow" },
{ {
@ -2117,14 +2117,14 @@
"ts": "type DataTableValue = any" "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", "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", "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", "type": "DataTableNonEmptyHeader | DataTableEmptyHeader",
@ -9441,6 +9441,16 @@
"moduleName": "TableHeader", "moduleName": "TableHeader",
"filePath": "src/DataTable/TableHeader.svelte", "filePath": "src/DataTable/TableHeader.svelte",
"props": [ "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", "name": "scope",
"kind": "let", "kind": "let",

View file

@ -550,12 +550,18 @@ The slot name for the table header cells is `"cell-header"`.
### Sortable ### 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 <DataTable sortable
headers="{[ headers="{[
{ key: "name", value: "Name" }, { key: "name", value: "Name" },
{ key: "protocol", value: "Protocol" }, { key: "protocol", value: "Protocol" },
{ key: "port", value: "Port" }, { key: "port", value: "Port" },
{ key: "rule", value: "Rule" } { key: "rule", value: "Rule", sort: false }
]}" ]}"
rows="{[ rows="{[
{ {

View file

@ -2,8 +2,8 @@
/** /**
* @typedef {string} DataTableKey * @typedef {string} DataTableKey
* @typedef {any} DataTableValue * @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; 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?: (a: DataTableValue, b: DataTableValue) => (0 | -1 | 1); columnMenu?: boolean; }} DataTableNonEmptyHeader * @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 {DataTableNonEmptyHeader | DataTableEmptyHeader} DataTableHeader
* @typedef {{ id: any; [key: string]: DataTableValue; }} DataTableRow * @typedef {{ id: any; [key: string]: DataTableValue; }} DataTableRow
* @typedef {string} DataTableRowId * @typedef {string} DataTableRowId
@ -13,7 +13,7 @@
* @slot {{ row: DataTableRow; cell: DataTableCell; }} cell * @slot {{ row: DataTableRow; cell: DataTableCell; }} cell
* @event {{ header?: DataTableHeader; row?: DataTableRow; cell?: DataTableCell; }} click * @event {{ header?: DataTableHeader; row?: DataTableRow; cell?: DataTableCell; }} click
* @event {{ expanded: boolean; }} click:header--expand * @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} click:row
* @event {DataTableRow} mouseenter:row * @event {DataTableRow} mouseenter:row
* @event {DataTableRow} mouseleave:row * @event {DataTableRow} mouseleave:row
@ -250,8 +250,13 @@
<th scope="col"></th> <th scope="col"></th>
{:else} {:else}
<TableHeader <TableHeader
disableSorting="{header.sort === false}"
on:click="{() => { on:click="{() => {
dispatch('click', { header }); dispatch('click', { header });
if (header.sort === false) {
dispatch('click:header', { header });
} else {
let active = header.key === $sortHeader.key; let active = header.key === $sortHeader.key;
let currentSortDirection = active let currentSortDirection = active
? $sortHeader.sortDirection ? $sortHeader.sortDirection
@ -264,6 +269,7 @@
sort: header.sort, sort: header.sort,
sortDirection, sortDirection,
}); });
}
}}" }}"
> >
<slot name="cell-header" header="{header}">{header.value}</slot> <slot name="cell-header" header="{header}">{header.value}</slot>

View file

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

View file

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

View file

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

View file

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