Documentation
Column Width
Set each column's width to "auto", a fixed size, or "1fr". Optionally fill the container with autoExpandColumns.
Content-fit ("auto")
Use width: "auto" to size from the header and sampled cell content. Cap growth with maxWidth when you want truncation.
{accessor: "email",label: "Email",width: "auto",maxWidth: 300,}
{accessor: "email",label: "Email",width: "auto",maxWidth: 300,}
{accessor: "email",label: "Email",width: "auto",maxWidth: 300,}
{accessor: "email",label: "Email",width: "auto",maxWidth: 300,}
{accessor: "email",label: "Email",width: "auto",maxWidth: 300,}
{accessor: "email",label: "Email",width: "auto",maxWidth: 300,}
Fixed width
Pass a number for a pixel width. Best for IDs, dates, and other short columns.
{ accessor: "id", label: "ID", width: 60 }
{ accessor: "id", label: "ID", width: 60 }
{ accessor: "id", label: "ID", width: 60 }
{ accessor: "id", label: "ID", width: 60 }
{ accessor: "id", label: "ID", width: 60 }
{ accessor: "id", label: "ID", width: 60 }
Flexible width ("1fr")
Use width: "1fr" so the column shares leftover space with other flexible columns. Pair with minWidthso it doesn't get too narrow.
{accessor: "name",label: "Name",width: "1fr",minWidth: 120,}
{accessor: "name",label: "Name",width: "1fr",minWidth: 120,}
{accessor: "name",label: "Name",width: "1fr",minWidth: 120,}
{accessor: "name",label: "Name",width: "1fr",minWidth: 120,}
{accessor: "name",label: "Name",width: "1fr",minWidth: 120,}
{accessor: "name",label: "Name",width: "1fr",minWidth: 120,}
Fill the container
Set autoExpandColumns to scale all column widths proportionally so the table fills its container with no horizontal scroll. Prefer falseon small screens (< 768px).
<SimpleTable columns={columns} rows={rows} height="400px" autoExpandColumns={true} />
<simple-table[columns]="columns"[rows]="rows"height="400px"[autoExpandColumns]="true"></simple-table>
<SimpleTable:columns="columns":rows="rows"height="400px":auto-expand-columns="true"/>
<SimpleTable {columns} {rows} height="400px" autoExpandColumns={true} />
<SimpleTable columns={columns} rows={rows} height="400px" autoExpandColumns={true} />
const table = new SimpleTableVanilla(container, {columns,rows,height: "400px",autoExpandColumns: true,});table.mount();
Example
Fixed, flexible, and auto columns together. On wider viewports the demo enables autoExpandColumns.
1import { useState, useEffect } from "react";2import { SimpleTable } from "@simple-table/react";3import type { Theme } from "@simple-table/react";4import { columnWidthConfig } from "./column-width.demo-data";5import "@simple-table/react/styles.css";67const ColumnWidthDemo = ({8 height = "400px",9 theme10}: {11 height?: string | number;12 theme?: Theme;13}) => {14 const [isMobile, setIsMobile] = useState(false);1516 useEffect(() => {17 const check = () => setIsMobile(window.innerWidth < 768);18 check();19 window.addEventListener("resize", check);20 return () => window.removeEventListener("resize", check);21 }, []);2223 return (24 <SimpleTable25 autoExpandColumns={!isMobile}26 columnResizing27 columns={columnWidthConfig.headers}28 height={height}29 rows={columnWidthConfig.rows}30 theme={theme}31 getRowId={({ row }) => row.id}32 />33 );34};3536export default ColumnWidthDemo;
1import { Component, Input, OnInit, OnDestroy } from "@angular/core";2import {SimpleTableComponent} from "@simple-table/angular";import type { AngularColumnDef, GetRowIdParams, Theme } from "@simple-table/angular";3import { columnWidthConfig } from "./column-width.demo-data";4import "@simple-table/angular/styles.css";5import type { StartupEmployee } from "./column-width.demo-data";67@Component({8 selector: "column-width-demo",9 standalone: true,10 imports: [SimpleTableComponent],11 template: `12 <simple-table13 [getRowId]="getRowId"14 [autoExpandColumns]="!isMobile"15 [columnResizing]="true"16 [rows]="rows"17 [columns]="headers"18 [height]="height"19 [theme]="theme"20 ></simple-table>21 `,22})23export class ColumnWidthDemoComponent implements OnInit, OnDestroy {24 @Input() height: string | number = "400px";25 @Input() theme?: Theme;2627 readonly rows: StartupEmployee[] = columnWidthConfig.rows;28 readonly headers: AngularColumnDef<StartupEmployee>[] = columnWidthConfig.headers;29 isMobile = false;3031 private checkMobile = () => { this.isMobile = window.innerWidth < 768; };3233 ngOnInit() {34 this.checkMobile();35 window.addEventListener("resize", this.checkMobile);36 }3738 ngOnDestroy() {39 window.removeEventListener("resize", this.checkMobile);40 }41}424344// column-width.demo-data.ts45// Self-contained demo table setup for this example.46import type { AngularColumnDef } from "@simple-table/angular";4748export interface StartupEmployee {49 id: number;50 name: string;51 email: string;52 age: number;53 department: string;54 salary: string;55}5657export const columnWidthHeaders: AngularColumnDef<StartupEmployee>[] = [58 { accessor: "id", label: "ID", width: 60, type: "number" },59 { accessor: "name", label: "Name", width: "1fr", minWidth: 120, type: "string" },60 { accessor: "email", label: "Email", width: "1fr", minWidth: 180, type: "string" },61 { accessor: "age", label: "Age", width: 80, type: "number" },62 { accessor: "department", label: "Department", width: "auto", minWidth: 100, type: "string" },63 { accessor: "salary", label: "Salary", width: 120, align: "right", type: "number" },64];6566export const columnWidthData = [67 { id: 1, name: "Alexandra Reeves", email: "alex.reeves@techstartup.io", age: 32, department: "AI Research", salary: "$145,000" },68 { id: 2, name: "Zephyr Kim", email: "zephyr.kim@techstartup.io", age: 28, department: "Product Design", salary: "$125,000" },69 { id: 3, name: "Phoenix Okafor", email: "phoenix.okafor@techstartup.io", age: 35, department: "Platform Engineering", salary: "$160,000" },70 { id: 4, name: "Luna Tanaka", email: "luna.tanaka@techstartup.io", age: 29, department: "DevOps & Infrastructure", salary: "$138,000" },71 { id: 5, name: "River Stone", email: "river.stone@techstartup.io", age: 31, department: "Growth Engineering", salary: "$142,000" },72 { id: 6, name: "Sage Morrison", email: "sage.morrison@techstartup.io", age: 27, department: "Customer Success", salary: "$95,000" },73 { id: 7, name: "Atlas Chen", email: "atlas.chen@techstartup.io", age: 33, department: "Security & Compliance", salary: "$155,000" },74 { id: 8, name: "Nova Patel", email: "nova.patel@techstartup.io", age: 30, department: "Data Science", salary: "$148,000" },75 { id: 9, name: "Isabella Patel", email: "isabella.patel@techstartup.io", age: 29, department: "Marketing", salary: "$130,000" },76 { id: 10, name: "Leo Patel", email: "leo.patel@techstartup.io", age: 30, department: "Sales", salary: "$125,000" },77 { id: 11, name: "Oliver Patel", email: "oliver.patel@techstartup.io", age: 31, department: "HR", salary: "$115,000" },78 { id: 12, name: "Sophia Patel", email: "sophia.patel@techstartup.io", age: 28, department: "Finance", salary: "$120,000" },79 { id: 13, name: "William Patel", email: "william.patel@techstartup.io", age: 32, department: "Marketing", salary: "$135,000" },80];8182export const columnWidthConfig = {83 headers: columnWidthHeaders,84 rows: columnWidthData,85 tableProps: { columnResizing: true },86};87
1<template>2 <SimpleTable3 :auto-expand-columns="!isMobile"4 :column-resizing="true"5 :columns="columnWidthConfig.headers"6 :height="height"7 :rows="columnWidthConfig.rows"8 :get-row-id="getRowId"9 :theme="theme"10 />11</template>1213<script setup lang="ts">14import { ref, onMounted, onUnmounted } from "vue";15import { SimpleTable } from "@simple-table/vue";16import type { Theme, GetRowIdParams } from "@simple-table/vue";17import { columnWidthConfig } from "./column-width.demo-data";18import type { StartupEmployee } from "./column-width.demo-data";19import "@simple-table/vue/styles.css";2021withDefaults(defineProps<{ height?: string | number; theme?: Theme }>(), {22 height: "400px",23});2425const getRowId = ({ row }: GetRowIdParams<StartupEmployee>) => row.id;2627const isMobile = ref(false);2829function checkMobile() {30 isMobile.value = window.innerWidth < 768;31}3233onMounted(() => {34 checkMobile();35 window.addEventListener("resize", checkMobile);36});3738onUnmounted(() => {39 window.removeEventListener("resize", checkMobile);40});41</script>
1<script lang="ts">2 import { SimpleTable } from "@simple-table/svelte";3 import type { Theme, GetRowIdParams } from "@simple-table/svelte";4 import { columnWidthConfig } from "./column-width.demo-data";5 import type { StartupEmployee } from "./column-width.demo-data";6 import "@simple-table/svelte/styles.css";78 let { height = "400px", theme }: { height?: string | number; theme?: Theme } = $props();9 let isMobile = $state(false);1011 const getRowId = ({ row }: GetRowIdParams<StartupEmployee>) => row.id;1213 function checkMobile() {14 isMobile = window.innerWidth < 768;15 }1617 $effect(() => {18 checkMobile();19 window.addEventListener("resize", checkMobile);20 return () => window.removeEventListener("resize", checkMobile);21 });22</script>2324<SimpleTable25 autoExpandColumns={!isMobile}26 columnResizing={true}27 columns={columnWidthConfig.headers}28 rows={columnWidthConfig.rows}29 getRowId={getRowId}30 {height}31 {theme}32/>
1import { createSignal, onMount, onCleanup } from "solid-js";2import {SimpleTable} from "@simple-table/solid";import type { Theme } from "@simple-table/solid";3import { columnWidthConfig } from "./column-width.demo-data";4import "@simple-table/solid/styles.css";56export default function ColumnWidthDemo(props: { height?: string | number; theme?: Theme }) {7 const [isMobile, setIsMobile] = createSignal(false);89 const check = () => setIsMobile(window.innerWidth < 768);1011 onMount(() => {12 check();13 window.addEventListener("resize", check);14 });1516 onCleanup(() => {17 window.removeEventListener("resize", check);18 });1920 return (21 <SimpleTable22 autoExpandColumns={!isMobile()}23 columnResizing24 columns={columnWidthConfig.headers}25 getRowId={({ row }) => row.id}26 height={props.height ?? "400px"}27 rows={columnWidthConfig.rows}28 theme={props.theme}29 />30 );31}
1import { SimpleTableVanilla } from "simple-table-core";2import type { StartupEmployee } from "./column-width.demo-data";3import type { Theme, GetRowIdParams } from "simple-table-core";4import { columnWidthConfig } from "./column-width.demo-data";5import "simple-table-core/styles.css";678const getRowId = ({ row }: GetRowIdParams<StartupEmployee>) => row.id;9export function renderColumnWidthDemo(10 container: HTMLElement,11 options?: { height?: string | number; theme?: Theme },12): SimpleTableVanilla<StartupEmployee> {13 const isMobile = window.innerWidth < 768;1415 const table = new SimpleTableVanilla(container, {16 getRowId,17 columns: columnWidthConfig.headers,18 rows: columnWidthConfig.rows,19 height: options?.height ?? "400px",20 theme: options?.theme,21 autoExpandColumns: !isMobile,22 columnResizing: true,23 });2425 const check = () => {26 const mobile = window.innerWidth < 768;27 table.update({ autoExpandColumns: !mobile });28 };29 window.addEventListener("resize", check);3031 return table;32}333435// column-width.demo-data.ts36// Self-contained demo table setup for this example.37import type { ColumnDef } from "simple-table-core";3839export interface StartupEmployee {40 id: number;41 name: string;42 email: string;43 age: number;44 department: string;45 salary: string;46}4748export const columnWidthHeaders: ColumnDef<StartupEmployee>[] = [49 { accessor: "id", label: "ID", width: 60, type: "number" },50 { accessor: "name", label: "Name", width: "1fr", minWidth: 120, type: "string" },51 { accessor: "email", label: "Email", width: "1fr", minWidth: 180, type: "string" },52 { accessor: "age", label: "Age", width: 80, type: "number" },53 { accessor: "department", label: "Department", width: "auto", minWidth: 100, type: "string" },54 { accessor: "salary", label: "Salary", width: 120, align: "right", type: "number" },55];5657export const columnWidthData = [58 { id: 1, name: "Alexandra Reeves", email: "alex.reeves@techstartup.io", age: 32, department: "AI Research", salary: "$145,000" },59 { id: 2, name: "Zephyr Kim", email: "zephyr.kim@techstartup.io", age: 28, department: "Product Design", salary: "$125,000" },60 { id: 3, name: "Phoenix Okafor", email: "phoenix.okafor@techstartup.io", age: 35, department: "Platform Engineering", salary: "$160,000" },61 { id: 4, name: "Luna Tanaka", email: "luna.tanaka@techstartup.io", age: 29, department: "DevOps & Infrastructure", salary: "$138,000" },62 { id: 5, name: "River Stone", email: "river.stone@techstartup.io", age: 31, department: "Growth Engineering", salary: "$142,000" },63 { id: 6, name: "Sage Morrison", email: "sage.morrison@techstartup.io", age: 27, department: "Customer Success", salary: "$95,000" },64 { id: 7, name: "Atlas Chen", email: "atlas.chen@techstartup.io", age: 33, department: "Security & Compliance", salary: "$155,000" },65 { id: 8, name: "Nova Patel", email: "nova.patel@techstartup.io", age: 30, department: "Data Science", salary: "$148,000" },66 { id: 9, name: "Isabella Patel", email: "isabella.patel@techstartup.io", age: 29, department: "Marketing", salary: "$130,000" },67 { id: 10, name: "Leo Patel", email: "leo.patel@techstartup.io", age: 30, department: "Sales", salary: "$125,000" },68 { id: 11, name: "Oliver Patel", email: "oliver.patel@techstartup.io", age: 31, department: "HR", salary: "$115,000" },69 { id: 12, name: "Sophia Patel", email: "sophia.patel@techstartup.io", age: 28, department: "Finance", salary: "$120,000" },70 { id: 13, name: "William Patel", email: "william.patel@techstartup.io", age: 32, department: "Marketing", salary: "$135,000" },71];7273export const columnWidthConfig = {74 headers: columnWidthHeaders,75 rows: columnWidthData,76 tableProps: { columnResizing: true },77};78
How "1fr" splits space
Fixed columns take their pixels first. Remaining width is split equally among 1fr columns. In a 1000px table with fixed 100px + 150px and two 1fr columns, each flexible column gets 375px.
autoExpandColumns trade-offs
Column width values are the scale base. minWidth /maxWidth are not enforced while scaling.
Props
Column Width Properties
| Property | Required | Description | Example |
|---|---|---|---|
Property | Required | Description | Example |
ColumnDef.width | Required | Column width: a pixel number, '1fr' to share leftover space, or 'auto' to fit content (clamped by minWidth/maxWidth). | |
ColumnDef.minWidthnumber | Optional | Minimum width for '1fr' and 'auto' columns. Not enforced during autoExpandColumns scaling. | |
ColumnDef.maxWidthnumber | Optional | Maximum width. With width: 'auto', content past the cap truncates. Ignored when autoExpandColumns is enabled. | |
autoExpandColumns | Optional | Scale all column widths proportionally to fill the container. Recommended off on mobile (< 768px). |