mirror of
https://github.com/carbon-design-system/carbon-components-svelte.git
synced 2025-09-18 11:36:36 +00:00
feat(data-table): allow sorting to be disabled for a specific header
This commit is contained in:
parent
2d5ef94e71
commit
766ee936ed
8 changed files with 79 additions and 46 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -957,16 +957,16 @@ 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" | "descending" | "none" }</code> |
|
| click:header | dispatched | <code>{ header: DataTableHeader; sortDirection?: "ascending" | "descending" | "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> |
|
||||||
| click:row--expand | dispatched | <code>{ expanded: boolean; row: DataTableRow; }</code> |
|
| click:row--expand | dispatched | <code>{ expanded: boolean; row: DataTableRow; }</code> |
|
||||||
| click:cell | dispatched | <code>DataTableCell</code> |
|
| click:cell | dispatched | <code>DataTableCell</code> |
|
||||||
|
|
||||||
## `DataTableSkeleton`
|
## `DataTableSkeleton`
|
||||||
|
|
||||||
|
@ -3772,11 +3772,12 @@ None.
|
||||||
|
|
||||||
### Props
|
### Props
|
||||||
|
|
||||||
| Prop name | Kind | Reactive | Type | Default value | Description |
|
| Prop name | Kind | Reactive | Type | Default value | Description |
|
||||||
| :-------------- | :--------------- | :------- | :------------------------ | ------------------------------------------------ | ------------------------------------ |
|
| :-------------- | :--------------- | :------- | :------------------------ | ------------------------------------------------ | ------------------------------------------------------ |
|
||||||
| scope | <code>let</code> | No | <code>string</code> | <code>"col"</code> | Specify the `scope` attribute |
|
| disableSorting | <code>let</code> | No | <code>boolean</code> | <code>false</code> | Set to `true` to disable sorting on this specific cell |
|
||||||
| translateWithId | <code>let</code> | No | <code>() => string</code> | <code>() => ""</code> | Override the default id translations |
|
| scope | <code>let</code> | No | <code>string</code> | <code>"col"</code> | Specify the `scope` attribute |
|
||||||
| id | <code>let</code> | No | <code>string</code> | <code>"ccs-" + Math.random().toString(36)</code> | Set an id for the top-level element |
|
| 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
|
### Slots
|
||||||
|
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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="{[
|
||||||
{
|
{
|
||||||
|
|
|
@ -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,20 +250,26 @@
|
||||||
<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 });
|
||||||
let active = header.key === $sortHeader.key;
|
|
||||||
let currentSortDirection = active
|
if (header.sort === false) {
|
||||||
? $sortHeader.sortDirection
|
dispatch('click:header', { header });
|
||||||
: 'none';
|
} else {
|
||||||
let sortDirection = sortDirectionMap[currentSortDirection];
|
let active = header.key === $sortHeader.key;
|
||||||
dispatch('click:header', { header, sortDirection });
|
let currentSortDirection = active
|
||||||
sortHeader.set({
|
? $sortHeader.sortDirection
|
||||||
id: sortDirection === 'none' ? null : $thKeys[header.key],
|
: 'none';
|
||||||
key: header.key,
|
let sortDirection = sortDirectionMap[currentSortDirection];
|
||||||
sort: header.sort,
|
dispatch('click:header', { header, sortDirection });
|
||||||
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>
|
<slot name="cell-header" header="{header}">{header.value}</slot>
|
||||||
|
|
|
@ -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}"
|
||||||
|
|
|
@ -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 = [
|
||||||
{
|
{
|
||||||
|
|
6
types/DataTable/DataTable.d.ts
vendored
6
types/DataTable/DataTable.d.ts
vendored
|
@ -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>;
|
||||||
|
|
6
types/DataTable/TableHeader.d.ts
vendored
6
types/DataTable/TableHeader.d.ts
vendored
|
@ -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"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue