Skip to content

Table header

The table header defines the label for a column within the table. It helps users understand the meaning of the data below it and provides structure and clarity to the table's content.

Header 1
Header 2
Header 3
Cell 1×1
Cell 1×2
Cell 1×3

WARNING

This component is best used within a Table.

Accessible sorting

When is-sortable is set, the sort trigger is reachable with the keyboard and opens the sort flyout like any other Menu. Set data-type to numeric or date so the flyout shows ordering icons that match the column's data instead of the alphabetical default.

Column sizing

Headers define the width of their column. A column with width gets that exact width. A column with is-shrinking hugs its content. Otherwise the column shares the available space, optionally bounded by min-width and/or max-width. When the combined minimum widths exceed the table width, the table scrolls horizontally.

Column formatting

align, is-numeric and no-wrap on the header apply to every cell in the column, so there is no need to repeat them per cell. A cell's own align overrides the header's; is-numeric and no-wrap can only be turned on per cell, not off. Spanning cells (colspan) never inherit column formatting.

Required icons

arrow-down-1-9
arrow-down-a-z
arrow-down-short-wide
arrow-up-9-1
arrow-up-a-z
arrow-up-arrow-down
arrow-up-wide-short
circle-xmark

Props

align?: "start" | "center" | "end"
Horizontal alignment of the header content. Cells in the column without their own `align` inherit this value, so `align="end"` on the header aligns the whole column.

data-type?: "text" | "numeric" | "date"
The kind of data in the column. Switches the sort flyout icons to match. The options are alphabetical (`text`), numeric (`numeric`) or chronological (`date`). This only affects the sort flyout; pair it with `is-numeric` for tabular figures in the cells.
Default: text

is-numeric?: boolean
Renders every cell in the column with tabular figures. Column metadata only; the header label itself is unaffected.

is-shrinking?: boolean
If the header will shrink to fit its cell group.

is-sortable?: boolean
If the table header will render a sorting flyout.

max-width?: number
The maximum width of the column in pixels. The column shrinks below this value when needed.

min-width?: number
The minimum width of the column in pixels. The column still grows to fill available space.

no-wrap?: boolean
Prevents the content of every cell in the column from wrapping. Column metadata only; the header label itself is unaffected.

pinned?: boolean | "start" | "end"
Pins the column while scrolling horizontally. Use `start` (or `true`) to pin it to the left edge and `end` to pin it to the right edge. Multiple leading or trailing columns can be pinned; they stack side by side. The cells in the column follow the header automatically.

sort?: "ascending" | "descending"
The current sorting that is applied to the header.

width?: number
Fixed column width in pixels. Takes precedence over `is-shrinking`, `min-width` and `max-width`.

Emits

sort: [ascending | descending | null]
Triggered when the sorting type changes.

Slots

default
The content of the header.

Examples

Basic

A basic table header.

Header 1
Header 2
Header 3
Cell 1×1
Cell 1×2
Cell 1×3

<template>
    <FluxPane>
        <FluxTable>
            <template #header>
                <FluxTableHeader
                    v-for="header in 3"
                    :is-sortable="header === 2">
                    Header {{ header }}
                </FluxTableHeader>
            </template>

            <FluxTableRow>
                <FluxTableCell
                    v-for="cell in 3">
                    Cell 1&times;{{ cell }}
                </FluxTableCell>
            </FluxTableRow>
        </FluxTable>
    </FluxPane>
</template>

<script
    setup
    lang="ts">
    import { FluxPane, FluxTable, FluxTableCell, FluxTableHeader, FluxTableRow } from '@flux-ui/components';
</script>

Shrinking

A table header that shrinks to fit its cell group.

Header 1
Header 2
Header 3
Cell 1×1
Cell 1×2
Cell 1×3
...

<template>
    <FluxPane>
        <FluxTable>
            <template #header>
                <FluxTableHeader
                    v-for="header in 3">
                    Header {{ header }}
                </FluxTableHeader>
                <FluxTableHeader is-shrinking/>
            </template>

            <FluxTableRow>
                <FluxTableCell
                    v-for="cell in 3">
                    Cell 1&times;{{ cell }}
                </FluxTableCell>

                <FluxTableCell>
                    ...
                </FluxTableCell>
            </FluxTableRow>
        </FluxTable>
    </FluxPane>
</template>

<script
    setup
    lang="ts">
    import { FluxPane, FluxTable, FluxTableCell, FluxTableHeader, FluxTableRow } from '@flux-ui/components';
</script>

Sortable

A table header that can be sorted.

Header 1
Header 2
Header 3
Cell 1×1
Cell 1×2
Cell 1×3

<template>
    <FluxPane>
        <FluxTable>
            <template #header>
                <FluxTableHeader
                    :sort="sort"
                    v-for="header in 3"
                    :is-sortable="header === 2"
                    @sort="updateSorting">
                    Header {{ header }}
                </FluxTableHeader>
            </template>

            <FluxTableRow>
                <FluxTableCell
                    v-for="cell in 3">
                    Cell 1&times;{{ cell }}
                </FluxTableCell>
            </FluxTableRow>
        </FluxTable>
    </FluxPane>
</template>

<script
    setup
    lang="ts">
    import { FluxPane, FluxTable, FluxTableCell, FluxTableHeader, FluxTableRow } from '@flux-ui/components';
    import { ref } from 'vue';

    const sort = ref<'ascending' | 'descending'>("ascending");

    function updateSorting(sorting: 'ascending' | 'descending' | null): void {
        sort.value = sorting ?? "ascending";
    }
</script>

Data type

Sortable headers whose flyout icons match the column's data type.

Name
Commits
Joined
Ada Lovelace
1,287
2021-04-08

<template>
    <FluxPane>
        <FluxTable>
            <template #header>
                <FluxTableHeader
                    is-sortable
                    data-type="text"
                    :sort="column === 'name' ? direction : undefined"
                    @sort="setSort('name', $event)">
                    Name
                </FluxTableHeader>

                <FluxTableHeader
                    align="end"
                    is-sortable
                    data-type="numeric"
                    :sort="column === 'commits' ? direction : undefined"
                    @sort="setSort('commits', $event)">
                    Commits
                </FluxTableHeader>

                <FluxTableHeader
                    is-sortable
                    data-type="date"
                    :sort="column === 'joined' ? direction : undefined"
                    @sort="setSort('joined', $event)">
                    Joined
                </FluxTableHeader>
            </template>

            <FluxTableRow>
                <FluxTableCell>Ada Lovelace</FluxTableCell>
                <FluxTableCell
                    align="end"
                    is-numeric>
                    1,287
                </FluxTableCell>
                <FluxTableCell>2021-04-08</FluxTableCell>
            </FluxTableRow>
        </FluxTable>
    </FluxPane>
</template>

<script
    setup
    lang="ts">
    import { FluxPane, FluxTable, FluxTableCell, FluxTableHeader, FluxTableRow } from '@flux-ui/components';
    import { ref } from 'vue';

    type SortDirection = 'ascending' | 'descending';

    const column = ref<'name' | 'commits' | 'joined'>('name');
    const direction = ref<SortDirection>('ascending');

    function setSort(next: 'name' | 'commits' | 'joined', value: SortDirection | null): void {
        if (value === null) {
            return;
        }

        column.value = next;
        direction.value = value;
    }
</script>

Width

Columns with a fixed, minimum and maximum width.

Fixed 150
Min 210
Max 240
Cell 1×1
Cell 1×2
Cell 1×3

<template>
    <FluxPane>
        <FluxTable>
            <template #header>
                <FluxTableHeader :width="150">
                    Fixed 150
                </FluxTableHeader>

                <FluxTableHeader :min-width="210">
                    Min 210
                </FluxTableHeader>

                <FluxTableHeader :max-width="240">
                    Max 240
                </FluxTableHeader>
            </template>

            <FluxTableRow>
                <FluxTableCell
                    v-for="cell in 3">
                    Cell 1&times;{{ cell }}
                </FluxTableCell>
            </FluxTableRow>
        </FluxTable>
    </FluxPane>
</template>

<script
    setup
    lang="ts">
    import { FluxPane, FluxTable, FluxTableCell, FluxTableHeader, FluxTableRow } from '@flux-ui/components';
</script>

Used components