Documentation
Animations
Cells slide into place on sort, column reorder, and visibility changes. On by default — no prop required.
Disable animations
Animations are on by default. Set enabled: false when you want cells to snap instantly.
React TSX
Copy
<SimpleTablecolumns={columns}rows={rows}animations={{ enabled: false }}/>
Angular
Copy
<simple-table[columns]="columns"[rows]="rows"[animations]="{ enabled: false }"></simple-table>
Vue SFC
Copy
<SimpleTable:columns="columns":rows="rows":animations="{ enabled: false }"/>
Svelte
Copy
<SimpleTable{columns}{rows}animations={{ enabled: false }}/>
Solid TSX
Copy
<SimpleTablecolumns={columns}rows={rows()}animations={{ enabled: false }}/>
TypeScript
Copy
new SimpleTableVanilla(container, {columns,rows,animations: { enabled: false },});
Custom timing
Override the default 240 ms duration and easing to match your product motion.
React TSX
Copy
<SimpleTablecolumns={columns}rows={rows}animations={{ duration: 320, easing: "ease-out" }}/>
Angular
Copy
<simple-table[columns]="columns"[rows]="rows"[animations]="{ duration: 320, easing: "ease-out" }"></simple-table>
Vue SFC
Copy
<SimpleTable:columns="columns":rows="rows":animations="{ duration: 320, easing: "ease-out" }"/>
Svelte
Copy
<SimpleTable{columns}{rows}animations={{ duration: 320, easing: "ease-out" }}/>
Solid TSX
Copy
<SimpleTablecolumns={columns}rows={rows()}animations={{ duration: 320, easing: "ease-out" }}/>
TypeScript
Copy
new SimpleTableVanilla(container, {columns,rows,animations: { duration: 320, easing: "ease-out" },});
What animates
Sort, drag reorder (neighbors only), programmatic column order, and column visibility. Scroll and cell content updates do not animate. For value-change flashes, see Live Updates (cellUpdateFlash).
prefers-reduced-motion disables motion automatically.
Example
Sort or drag a column to see cells slide. Use Code or StackBlitz for the full example.
React TSX
Copy
1import { useState } from "react";2import { SimpleTable } from "@simple-table/react";3import type { Theme, ReactColumnDef } from "@simple-table/react";4import { animationsConfig, type AnimationsCrewMember } from "./animations.demo-data";5import "@simple-table/react/styles.css";67const AnimationsDemo = ({8 height = "400px",9 theme10}: {11 height?: string | number;12 theme?: Theme;13}) => {14 const [headers, setHeaders] = useState(() => [...animationsConfig.headers]);1516 const handleColumnOrderChange = (newHeaders: ReactColumnDef<AnimationsCrewMember>[]) => {17 setHeaders(newHeaders);18 };1920 return (21 <SimpleTable22 columnReordering={animationsConfig.tableProps.columnReordering}23 columns={headers}24 enableColumnEditor={animationsConfig.tableProps.enableColumnEditor}25 enableColumnEditorInitOpen={animationsConfig.tableProps.enableColumnEditorInitOpen}26 getRowId={({ row }) => row.id}27 rows={animationsConfig.rows}28 height={height}29 theme={theme}30 onColumnOrderChange={handleColumnOrderChange}31 />32 );33};3435export default AnimationsDemo;
Angularanimations-demo.component.ts
Copy
1import { Component, Input } from "@angular/core";2import { SimpleTableComponent } from "@simple-table/angular";3import type { AngularColumnDef, GetRowIdParams, Theme } from "@simple-table/angular";4import { animationsConfig } from "./animations.demo-data";5import "@simple-table/angular/styles.css";6import type { AnimationsCrewMember } from "./animations.demo-data";78@Component({9 selector: "animations-demo",10 standalone: true,11 imports: [SimpleTableComponent],12 template: `13 <simple-table14 [getRowId]="getRowId"15 [rows]="rows"16 [columns]="headers"17 [height]="height"18 [theme]="theme"19 [columnReordering]="true"20 [enableColumnEditor]="true"21 [enableColumnEditorInitOpen]="true"22 (columnOrderChange)="onColumnOrderChange($event)"23 ></simple-table>24 `,25})26export class AnimationsDemoComponent {27 @Input() height: string | number = "400px";28 @Input() theme?: Theme;2930 readonly rows: AnimationsCrewMember[] = animationsConfig.rows;31 headers: AngularColumnDef<AnimationsCrewMember>[] = [...animationsConfig.headers];3233 onColumnOrderChange(newHeaders: AngularColumnDef<AnimationsCrewMember>[]): void {34 this.headers = newHeaders;35 }3637 getRowId = ({ row }: GetRowIdParams<AnimationsCrewMember>) => row.id;38}394041// animations.demo-data.ts42// Self-contained demo table setup for this example.43import type { AngularColumnDef } from "@simple-table/angular";4445export interface AnimationsCrewMember {46 id: number;47 name: string;48 age: number;49 role: string;50 department: string;51}5253export const animationsHeaders: AngularColumnDef<AnimationsCrewMember>[] = [54 { accessor: "id", label: "ID", width: 60, sortable: true, type: "number" },55 { accessor: "name", label: "Name", minWidth: 140, width: "1fr", sortable: true, type: "string" },56 { accessor: "age", label: "Age", width: 80, align: "right", sortable: true, type: "number" },57 { accessor: "role", label: "Role", minWidth: 140, width: "1fr", sortable: true, type: "string" },58 {59 accessor: "department",60 disableReorder: true,61 sortable: true,62 label: "Department",63 minWidth: 140,64 width: "1fr",65 type: "string",66 },67];6869export const animationsData: AnimationsCrewMember[] = [70 { id: 1, name: "Captain Stella Vega", age: 38, role: "Mission Commander", department: "Flight Operations" },71 { id: 2, name: "Dr. Cosmos Rivera", age: 34, role: "Astrophysicist", department: "Science" },72 { id: 3, name: "Commander Nebula Johnson", age: 42, role: "Operations Director", department: "Mission Control" },73 { id: 4, name: "Cadet Orbit Williams", age: 26, role: "Flight Engineer", department: "Engineering" },74 { id: 5, name: "Dr. Galaxy Chen", age: 31, role: "Life Support Specialist", department: "Engineering" },75 { id: 6, name: "Lt. Meteor Lee", age: 29, role: "Navigation Officer", department: "Flight Operations" },76 { id: 7, name: "Dr. Comet Hassan", age: 33, role: "Mission Planner", department: "Planning" },77 { id: 8, name: "Major Pulsar White", age: 36, role: "Communications Director", department: "Communications" },78 { id: 9, name: "Specialist Quasar Black", age: 28, role: "Systems Analyst", department: "Technology" },79 { id: 10, name: "Engineer Supernova Blue", age: 35, role: "Propulsion Engineer", department: "Engineering" },80 { id: 11, name: "Dr. Aurora Kumar", age: 30, role: "Planetary Geologist", department: "Science" },81 { id: 12, name: "Admiral Cosmos Silver", age: 45, role: "Program Director", department: "Leadership" },82];8384export const animationsConfig = {85 headers: animationsHeaders,86 rows: animationsData,87 tableProps: { columnReordering: true, enableColumnEditor: true, enableColumnEditorInitOpen: true },88};89
Vue SFC
Copy
1<template>2 <SimpleTable3 :column-reordering="animationsConfig.tableProps.columnReordering"4 :columns="headers"5 :enable-column-editor="animationsConfig.tableProps.enableColumnEditor"6 :enable-column-editor-init-open="animationsConfig.tableProps.enableColumnEditorInitOpen"7 :rows="animationsConfig.rows"8 :get-row-id="getRowId"9 :height="height"10 :theme="theme"11 @column-order-change="handleColumnOrderChange"12 />13</template>1415<script setup lang="ts">16import { ref } from "vue";17import { SimpleTable } from "@simple-table/vue";18import type { Theme, VueColumnDef, GetRowIdParams } from "@simple-table/vue";19import { animationsConfig } from "./animations.demo-data";20import type { AnimationsCrewMember } from "./animations.demo-data";21import "@simple-table/vue/styles.css";2223withDefaults(defineProps<{ height?: string | number; theme?: Theme }>(), {24 height: "400px",25});2627const headers = ref<VueColumnDef<AnimationsCrewMember>[]>([...animationsConfig.headers]);2829const handleColumnOrderChange = (newHeaders: VueColumnDef<AnimationsCrewMember>[]) => {30 headers.value = newHeaders;31};3233const getRowId = ({ row }: GetRowIdParams<AnimationsCrewMember>) => row.id;34</script>
Svelte
Copy
1<script lang="ts">2 import { SimpleTable } from "@simple-table/svelte";3 import type { Theme, SvelteColumnDef, GetRowIdParams } from "@simple-table/svelte";4 import { animationsConfig } from "./animations.demo-data";5 import type { AnimationsCrewMember } from "./animations.demo-data";6 import "@simple-table/svelte/styles.css";78 let { height = "400px", theme }: { height?: string | number; theme?: Theme } = $props();9 let headers: SvelteColumnDef<AnimationsCrewMember>[] = $state([...animationsConfig.headers]);1011 const getRowId = ({ row }: GetRowIdParams<AnimationsCrewMember>) => row.id;1213 function handleColumnOrderChange(newHeaders: SvelteColumnDef<AnimationsCrewMember>[]) {14 headers = newHeaders;15 }16</script>1718<SimpleTable19 columnReordering20 columns={headers}21 enableColumnEditor22 enableColumnEditorInitOpen23 {getRowId}24 rows={animationsConfig.rows}25 {height}26 {theme}27 onColumnOrderChange={handleColumnOrderChange}28/>
Solid TSX
Copy
1import { createSignal } from "solid-js";2import { SimpleTable } from "@simple-table/solid";3import type { Theme, SolidColumnDef } from "@simple-table/solid";4import { animationsConfig, type AnimationsCrewMember } from "./animations.demo-data";5import "@simple-table/solid/styles.css";67export default function AnimationsDemo(props: { height?: string | number; theme?: Theme }) {8 const [headers, setHeaders] = createSignal([...animationsConfig.headers]);910 const handleColumnOrderChange = (newHeaders: SolidColumnDef<AnimationsCrewMember>[]) => {11 setHeaders(newHeaders);12 };1314 return (15 <SimpleTable16 columnReordering={animationsConfig.tableProps.columnReordering}17 columns={headers()}18 enableColumnEditor={animationsConfig.tableProps.enableColumnEditor}19 enableColumnEditorInitOpen={animationsConfig.tableProps.enableColumnEditorInitOpen}20 getRowId={({ row }) => row.id}21 rows={animationsConfig.rows}22 height={props.height ?? "400px"}23 theme={props.theme}24 onColumnOrderChange={handleColumnOrderChange}25 />26 );27}
TypeScriptAnimationsDemo.ts
Copy
1import { SimpleTableVanilla } from "simple-table-core";2import type { AnimationsCrewMember } from "./animations.demo-data";3import type { Theme, GetRowIdParams } from "simple-table-core";4import { animationsConfig } from "./animations.demo-data";5import "simple-table-core/styles.css";678const getRowId = ({ row }: GetRowIdParams<AnimationsCrewMember>) => row.id;9export function renderAnimationsDemo(10 container: HTMLElement,11 options?: { height?: string | number; theme?: Theme }12): SimpleTableVanilla<AnimationsCrewMember> {13 const table = new SimpleTableVanilla(container, {14 getRowId,15 columns: animationsConfig.headers,16 rows: animationsConfig.rows,17 height: options?.height ?? "400px",18 theme: options?.theme,19 columnReordering: true,20 enableColumnEditor: true,21 enableColumnEditorInitOpen: true,22 });23 return table;24}252627// animations.demo-data.ts28// Self-contained demo table setup for this example.29import type { ColumnDef } from "simple-table-core";3031export interface AnimationsCrewMember {32 id: number;33 name: string;34 age: number;35 role: string;36 department: string;37}3839export const animationsHeaders: ColumnDef<AnimationsCrewMember>[] = [40 { accessor: "id", label: "ID", width: 60, sortable: true, type: "number" },41 { accessor: "name", label: "Name", minWidth: 140, width: "1fr", sortable: true, type: "string" },42 { accessor: "age", label: "Age", width: 80, align: "right", sortable: true, type: "number" },43 { accessor: "role", label: "Role", minWidth: 140, width: "1fr", sortable: true, type: "string" },44 {45 accessor: "department",46 disableReorder: true,47 sortable: true,48 label: "Department",49 minWidth: 140,50 width: "1fr",51 type: "string",52 },53];5455export const animationsData: AnimationsCrewMember[] = [56 { id: 1, name: "Captain Stella Vega", age: 38, role: "Mission Commander", department: "Flight Operations" },57 { id: 2, name: "Dr. Cosmos Rivera", age: 34, role: "Astrophysicist", department: "Science" },58 { id: 3, name: "Commander Nebula Johnson", age: 42, role: "Operations Director", department: "Mission Control" },59 { id: 4, name: "Cadet Orbit Williams", age: 26, role: "Flight Engineer", department: "Engineering" },60 { id: 5, name: "Dr. Galaxy Chen", age: 31, role: "Life Support Specialist", department: "Engineering" },61 { id: 6, name: "Lt. Meteor Lee", age: 29, role: "Navigation Officer", department: "Flight Operations" },62 { id: 7, name: "Dr. Comet Hassan", age: 33, role: "Mission Planner", department: "Planning" },63 { id: 8, name: "Major Pulsar White", age: 36, role: "Communications Director", department: "Communications" },64 { id: 9, name: "Specialist Quasar Black", age: 28, role: "Systems Analyst", department: "Technology" },65 { id: 10, name: "Engineer Supernova Blue", age: 35, role: "Propulsion Engineer", department: "Engineering" },66 { id: 11, name: "Dr. Aurora Kumar", age: 30, role: "Planetary Geologist", department: "Science" },67 { id: 12, name: "Admiral Cosmos Silver", age: 45, role: "Program Director", department: "Leadership" },68];6970export const animationsConfig = {71 headers: animationsHeaders,72 rows: animationsData,73 tableProps: { columnReordering: true, enableColumnEditor: true, enableColumnEditorInitOpen: true },74};75
Props
Animations Configuration
| Property | Required | Description | Example |
|---|---|---|---|
Property | Required | Description | Example |
animations | Optional | FLIP-style cell motion on sort, column reorder, and visibility changes. Enabled by default; respects prefers-reduced-motion. |
AnimationsConfig
AnimationsConfig
| Property | Required | Description | Example |
|---|---|---|---|
Property | Required | Description | Example |
enabledboolean | Optional | Master toggle for animations. When false, no other field has effect and cells snap to their new positions instantly. Defaults to true. | |
durationnumber | Optional | Animation duration in milliseconds. Applies to every animated cell. Defaults to 240ms. | |
easingstring | Optional | CSS easing function applied to the transform transition. Accepts any valid CSS timing function (cubic-bezier, ease, linear, etc.). Defaults to cubic-bezier(0.2, 0.8, 0.2, 1). |