mirror of
https://github.com/carbon-design-system/carbon-components-svelte.git
synced 2025-09-14 18:01:06 +00:00
feat(data-table): allow custom column widths (#1265)
* feat(data-table): allow header column `width`, `minWidth` values * Run "yarn build:docs" * test(data-table): assert width, minWidth properties * docs(data-table): add "Custom column widths" example
This commit is contained in:
parent
6239c11024
commit
c6f210899b
9 changed files with 90 additions and 14 deletions
|
@ -927,6 +927,8 @@ export interface DataTableEmptyHeader {
|
||||||
display?: (item: Value) => DataTableValue;
|
display?: (item: Value) => DataTableValue;
|
||||||
sort?: false | ((a: DataTableValue, b: DataTableValue) => 0 | -1 | 1);
|
sort?: false | ((a: DataTableValue, b: DataTableValue) => 0 | -1 | 1);
|
||||||
columnMenu?: boolean;
|
columnMenu?: boolean;
|
||||||
|
width?: string;
|
||||||
|
minWidth?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DataTableNonEmptyHeader {
|
export interface DataTableNonEmptyHeader {
|
||||||
|
@ -935,6 +937,8 @@ export interface DataTableNonEmptyHeader {
|
||||||
display?: (item: Value) => DataTableValue;
|
display?: (item: Value) => DataTableValue;
|
||||||
sort?: false | ((a: DataTableValue, b: DataTableValue) => 0 | -1 | 1);
|
sort?: false | ((a: DataTableValue, b: DataTableValue) => 0 | -1 | 1);
|
||||||
columnMenu?: boolean;
|
columnMenu?: boolean;
|
||||||
|
width?: string;
|
||||||
|
minWidth?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type DataTableHeader = DataTableNonEmptyHeader | DataTableEmptyHeader;
|
export type DataTableHeader = DataTableNonEmptyHeader | DataTableEmptyHeader;
|
||||||
|
@ -3748,13 +3752,14 @@ None.
|
||||||
|
|
||||||
### Props
|
### Props
|
||||||
|
|
||||||
| Prop name | Kind | Reactive | Type | Default value | Description |
|
| Prop name | Kind | Reactive | Type | Default value | Description |
|
||||||
| :------------- | :--------------- | :------- | :------------------------------------------------------------------ | ---------------------- | --------------------------------------- |
|
| :------------- | :--------------- | :------- | :------------------------------------------------------------------ | ---------------------- | ---------------------------------------------- |
|
||||||
| size | <code>let</code> | No | <code>"compact" | "short" | "medium" | "tall"</code> | <code>undefined</code> | Set the size of the table |
|
| size | <code>let</code> | No | <code>"compact" | "short" | "medium" | "tall"</code> | <code>undefined</code> | Set the size of the table |
|
||||||
| zebra | <code>let</code> | No | <code>boolean</code> | <code>false</code> | Set to `true` to use zebra styles |
|
| zebra | <code>let</code> | No | <code>boolean</code> | <code>false</code> | Set to `true` to use zebra styles |
|
||||||
| 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 |
|
||||||
| sortable | <code>let</code> | No | <code>boolean</code> | <code>false</code> | Set to `true` for the sortable variant |
|
| sortable | <code>let</code> | No | <code>boolean</code> | <code>false</code> | Set to `true` for the sortable variant |
|
||||||
| 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 |
|
||||||
|
| tableStyle | <code>let</code> | No | <code>string</code> | <code>undefined</code> | Set the style attribute on the `table` element |
|
||||||
|
|
||||||
### Slots
|
### Slots
|
||||||
|
|
||||||
|
|
|
@ -2495,14 +2495,14 @@
|
||||||
"ts": "type DataTableValue = any"
|
"ts": "type DataTableValue = any"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "{ key: DataTableKey; empty: boolean; display?: (item: Value) => DataTableValue; sort?: false | ((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; width?: string; minWidth?: string; }",
|
||||||
"name": "DataTableEmptyHeader",
|
"name": "DataTableEmptyHeader",
|
||||||
"ts": "interface DataTableEmptyHeader { key: DataTableKey; empty: boolean; display?: (item: Value) => DataTableValue; sort?: false | ((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; width?: string; minWidth?: string; }"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "{ key: DataTableKey; value: DataTableValue; 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?: false | ((a: DataTableValue, b: DataTableValue) => (0 | -1 | 1)); columnMenu?: boolean; width?: string; minWidth?: string; }",
|
||||||
"name": "DataTableNonEmptyHeader",
|
"name": "DataTableNonEmptyHeader",
|
||||||
"ts": "interface DataTableNonEmptyHeader { key: DataTableKey; value: DataTableValue; display?: (item: Value) => DataTableValue; sort?: false | ((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; width?: string; minWidth?: string; }"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "DataTableNonEmptyHeader | DataTableEmptyHeader",
|
"type": "DataTableNonEmptyHeader | DataTableEmptyHeader",
|
||||||
|
@ -10863,6 +10863,16 @@
|
||||||
"isFunctionDeclaration": false,
|
"isFunctionDeclaration": false,
|
||||||
"constant": false,
|
"constant": false,
|
||||||
"reactive": false
|
"reactive": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "tableStyle",
|
||||||
|
"kind": "let",
|
||||||
|
"description": "Set the style attribute on the `table` element",
|
||||||
|
"type": "string",
|
||||||
|
"isFunction": false,
|
||||||
|
"isFunctionDeclaration": false,
|
||||||
|
"constant": false,
|
||||||
|
"reactive": false
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"moduleExports": [],
|
"moduleExports": [],
|
||||||
|
|
|
@ -328,6 +328,14 @@ title="Load balancers" description="Your organization's active load balancers."
|
||||||
]}"
|
]}"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
### Custom column widths
|
||||||
|
|
||||||
|
Specify a `width` or `minWidth` property in the `headers` object to customize the width of each column.
|
||||||
|
|
||||||
|
A [table-layout: fixed](https://developer.mozilla.org/en-US/docs/Web/CSS/table-layout#values) rule will be applied to the `table` element when using custom widths.
|
||||||
|
|
||||||
|
<FileSource src="/framed/DataTable/DataTableHeaderWidth" />
|
||||||
|
|
||||||
### Sticky header
|
### Sticky header
|
||||||
|
|
||||||
Set `stickyHeader` to `true` for the header to be fixed in place.
|
Set `stickyHeader` to `true` for the header to be fixed in place.
|
||||||
|
|
19
docs/src/pages/framed/DataTable/DataTableHeaderWidth.svelte
Normal file
19
docs/src/pages/framed/DataTable/DataTableHeaderWidth.svelte
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<script>
|
||||||
|
import { DataTable } from "carbon-components-svelte";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<DataTable
|
||||||
|
headers="{[
|
||||||
|
{ key: 'name', value: 'Name', width: '50%', minWidth: '200px' },
|
||||||
|
{ key: 'protocol', value: 'Protocol', width: '60px' },
|
||||||
|
{ key: 'port', value: 'Port', width: '60px' },
|
||||||
|
{ key: 'rule', value: 'Rule', width: '10rem' },
|
||||||
|
]}"
|
||||||
|
rows="{Array.from({ length: 6 }).map((_, i) => ({
|
||||||
|
id: i,
|
||||||
|
name: 'Load Balancer ' + (i + 1),
|
||||||
|
protocol: 'HTTP',
|
||||||
|
port: i % 3 ? (i % 2 ? 3000 : 80) : 443,
|
||||||
|
rule: i % 3 ? 'Round robin' : 'DNS delegation',
|
||||||
|
}))}"
|
||||||
|
/>
|
|
@ -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?: false | ((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; width?: string; minWidth?: string; }} DataTableEmptyHeader
|
||||||
* @typedef {{ key: DataTableKey; value: DataTableValue; display?: (item: Value) => DataTableValue; sort?: false | ((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; width?: string; minWidth?: string; }} DataTableNonEmptyHeader
|
||||||
* @typedef {DataTableNonEmptyHeader | DataTableEmptyHeader} DataTableHeader
|
* @typedef {DataTableNonEmptyHeader | DataTableEmptyHeader} DataTableHeader
|
||||||
* @typedef {{ id: any; [key: string]: DataTableValue; }} DataTableRow
|
* @typedef {{ id: any; [key: string]: DataTableValue; }} DataTableRow
|
||||||
* @typedef {any} DataTableRowId
|
* @typedef {any} DataTableRowId
|
||||||
|
@ -240,6 +240,20 @@
|
||||||
: rows;
|
: rows;
|
||||||
$: displayedRows = getDisplayedRows($tableRows, page, pageSize);
|
$: displayedRows = getDisplayedRows($tableRows, page, pageSize);
|
||||||
$: displayedSortedRows = getDisplayedRows(sortedRows, page, pageSize);
|
$: displayedSortedRows = getDisplayedRows(sortedRows, page, pageSize);
|
||||||
|
|
||||||
|
$: hasCustomHeaderWidth = headers.some(
|
||||||
|
(header) => header.width || header.minWidth
|
||||||
|
);
|
||||||
|
|
||||||
|
/** @type {(header: DataTableHeader) => undefined | string} */
|
||||||
|
const formatHeaderWidth = (header) => {
|
||||||
|
const styles = [
|
||||||
|
header.width && `width: ${header.width}`,
|
||||||
|
header.minWidth && `min-width: ${header.minWidth}`,
|
||||||
|
].filter(Boolean);
|
||||||
|
if (styles.length === 0) return undefined;
|
||||||
|
return styles.join(";");
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<TableContainer useStaticWidth="{useStaticWidth}" {...$$restProps}>
|
<TableContainer useStaticWidth="{useStaticWidth}" {...$$restProps}>
|
||||||
|
@ -264,6 +278,7 @@
|
||||||
stickyHeader="{stickyHeader}"
|
stickyHeader="{stickyHeader}"
|
||||||
sortable="{sortable}"
|
sortable="{sortable}"
|
||||||
useStaticWidth="{useStaticWidth}"
|
useStaticWidth="{useStaticWidth}"
|
||||||
|
tableStyle="{hasCustomHeaderWidth && 'table-layout: fixed'}"
|
||||||
>
|
>
|
||||||
<TableHead>
|
<TableHead>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
|
@ -322,6 +337,7 @@
|
||||||
{:else}
|
{:else}
|
||||||
<TableHeader
|
<TableHeader
|
||||||
id="{header.key}"
|
id="{header.key}"
|
||||||
|
style="{formatHeaderWidth(header)}"
|
||||||
disableSorting="{header.sort === false}"
|
disableSorting="{header.sort === false}"
|
||||||
on:click="{() => {
|
on:click="{() => {
|
||||||
dispatch('click', { header });
|
dispatch('click', { header });
|
||||||
|
|
|
@ -16,6 +16,12 @@
|
||||||
|
|
||||||
/** Set to `true` to enable a sticky header */
|
/** Set to `true` to enable a sticky header */
|
||||||
export let stickyHeader = false;
|
export let stickyHeader = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the style attribute on the `table` element
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
export let tableStyle = undefined;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if stickyHeader}
|
{#if stickyHeader}
|
||||||
|
@ -30,6 +36,7 @@
|
||||||
class:bx--data-table--zebra="{zebra}"
|
class:bx--data-table--zebra="{zebra}"
|
||||||
class:bx--data-table--static="{useStaticWidth}"
|
class:bx--data-table--static="{useStaticWidth}"
|
||||||
class:bx--data-table--sticky-header="{stickyHeader}"
|
class:bx--data-table--sticky-header="{stickyHeader}"
|
||||||
|
style="{tableStyle}"
|
||||||
>
|
>
|
||||||
<slot />
|
<slot />
|
||||||
</table>
|
</table>
|
||||||
|
@ -46,6 +53,7 @@
|
||||||
class:bx--data-table--static="{useStaticWidth}"
|
class:bx--data-table--static="{useStaticWidth}"
|
||||||
class:bx--data-table--sticky-header="{stickyHeader}"
|
class:bx--data-table--sticky-header="{stickyHeader}"
|
||||||
{...$$restProps}
|
{...$$restProps}
|
||||||
|
style="{tableStyle}"
|
||||||
>
|
>
|
||||||
<slot />
|
<slot />
|
||||||
</table>
|
</table>
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
const headers: DataTableHeader[] = [
|
const headers: DataTableHeader[] = [
|
||||||
{ key: "name", value: "Name" },
|
{ key: "name", value: "Name" },
|
||||||
{ key: "protocol", value: "Protocol" },
|
{ key: "protocol", value: "Protocol", width: "400px", minWidth: "40%" },
|
||||||
{ key: "port", value: "Port" },
|
{ key: "port", value: "Port" },
|
||||||
{ key: "rule", value: "Rule", sort: false },
|
{ key: "rule", value: "Rule", sort: false },
|
||||||
];
|
];
|
||||||
|
|
4
types/DataTable/DataTable.svelte.d.ts
vendored
4
types/DataTable/DataTable.svelte.d.ts
vendored
|
@ -11,6 +11,8 @@ export interface DataTableEmptyHeader {
|
||||||
display?: (item: Value) => DataTableValue;
|
display?: (item: Value) => DataTableValue;
|
||||||
sort?: false | ((a: DataTableValue, b: DataTableValue) => 0 | -1 | 1);
|
sort?: false | ((a: DataTableValue, b: DataTableValue) => 0 | -1 | 1);
|
||||||
columnMenu?: boolean;
|
columnMenu?: boolean;
|
||||||
|
width?: string;
|
||||||
|
minWidth?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DataTableNonEmptyHeader {
|
export interface DataTableNonEmptyHeader {
|
||||||
|
@ -19,6 +21,8 @@ export interface DataTableNonEmptyHeader {
|
||||||
display?: (item: Value) => DataTableValue;
|
display?: (item: Value) => DataTableValue;
|
||||||
sort?: false | ((a: DataTableValue, b: DataTableValue) => 0 | -1 | 1);
|
sort?: false | ((a: DataTableValue, b: DataTableValue) => 0 | -1 | 1);
|
||||||
columnMenu?: boolean;
|
columnMenu?: boolean;
|
||||||
|
width?: string;
|
||||||
|
minWidth?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type DataTableHeader = DataTableNonEmptyHeader | DataTableEmptyHeader;
|
export type DataTableHeader = DataTableNonEmptyHeader | DataTableEmptyHeader;
|
||||||
|
|
6
types/DataTable/Table.svelte.d.ts
vendored
6
types/DataTable/Table.svelte.d.ts
vendored
|
@ -32,6 +32,12 @@ export interface TableProps
|
||||||
* @default false
|
* @default false
|
||||||
*/
|
*/
|
||||||
stickyHeader?: boolean;
|
stickyHeader?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the style attribute on the `table` element
|
||||||
|
* @default undefined
|
||||||
|
*/
|
||||||
|
tableStyle?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class Table extends SvelteComponentTyped<
|
export default class Table extends SvelteComponentTyped<
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue