Documentation
Custom Icons
Replace sort, filter, pagination, expand, and editor icons with the icons prop.
Override icons
Pass an icons object — only the keys you set replace the defaults. Values are framework nodes (JSX, VNodes, components, or DOM/SVG elements).
React TSX
Copy
const icons = {sortUp: <SortUpIcon />,sortDown: <SortDownIcon />,filter: <FilterIcon />,expand: <ExpandIcon />,headerExpand: <HeaderExpandIcon />,headerCollapse: <HeaderCollapseIcon />,prev: <PrevIcon />,next: <NextIcon />,drag: <DragIcon />,pinnedLeftIcon: <PinLeftIcon />,pinnedRightIcon: <PinRightIcon />,};<SimpleTableicons={icons}columns={columns}rows={rows}/>
Angular
Copy
icons: AngularIconsConfig = {sortUp: SortUpIconComponent,sortDown: SortDownIconComponent,filter: FilterIconComponent,expand: ExpandIconComponent,headerExpand: HeaderExpandIconComponent,headerCollapse: HeaderCollapseIconComponent,prev: PrevIconComponent,next: NextIconComponent,drag: DragIconComponent,pinnedLeftIcon: PinLeftIconComponent,pinnedRightIcon: PinRightIconComponent,};<simple-table[icons]="icons"[columns]="columns"[rows]="rows"></simple-table>
Vue SFC
Copy
import { h } from "vue";const icons = {sortUp: h(SortUpIcon),sortDown: h(SortDownIcon),filter: h(FilterIcon),expand: h(ExpandIcon),headerExpand: h(HeaderExpandIcon),headerCollapse: h(HeaderCollapseIcon),prev: h(PrevIcon),next: h(NextIcon),drag: h(DragIcon),pinnedLeftIcon: h(PinLeftIcon),pinnedRightIcon: h(PinRightIcon),};<SimpleTable:icons="icons":columns="columns":rows="rows"/>
Svelte
Copy
const icons = {sortUp: SortUpIcon,sortDown: SortDownIcon,filter: FilterIcon,expand: ExpandIcon,headerExpand: HeaderExpandIcon,headerCollapse: HeaderCollapseIcon,prev: PrevIcon,next: NextIcon,drag: DragIcon,pinnedLeftIcon: PinLeftIcon,pinnedRightIcon: PinRightIcon,};<SimpleTable {icons} {columns} {rows} />
Solid TSX
Copy
const icons = {sortUp: <SortUpIcon />,sortDown: <SortDownIcon />,filter: <FilterIcon />,expand: <ExpandIcon />,headerExpand: <HeaderExpandIcon />,headerCollapse: <HeaderCollapseIcon />,prev: <PrevIcon />,next: <NextIcon />,drag: <DragIcon />,pinnedLeftIcon: <PinLeftIcon />,pinnedRightIcon: <PinRightIcon />,};<SimpleTableicons={icons}columns={columns}rows={rows()}/>
TypeScript
Copy
const icons = {sortUp: createSvgIcon("M12 19V5M5 12l7-7 7 7"),sortDown: createSvgIcon("M12 5v14M19 12l-7 7-7-7"),filter: createSvgIcon("M3 4h18l-7 8.5V18l-4 2V12.5L3 4z"),expand: createSvgIcon("M9 5l7 7-7 7"),headerExpand: createSvgIcon("M9 5l7 7-7 7"),headerCollapse: createSvgIcon("M19 9l-7 7-7-7"),prev: createSvgIcon("M15 19l-7-7 7-7"),next: createSvgIcon("M9 5l7 7-7 7"),drag: createSvgIcon("M9 5h2M13 5h2M9 12h2M13 12h2M9 19h2M13 19h2"),pinnedLeftIcon: createSvgIcon("M12 17v5M9 10.76V7a3 3 0 116 0v3.76"),pinnedRightIcon: createSvgIcon("M12 17v5M9 10.76V7a3 3 0 116 0v3.76"),};new SimpleTableVanilla(container, {icons,columns,rows,});
Example
Sort and paginate to see the custom icons. Code or StackBlitz has the full example.
React TSX
Copy
1import {SimpleTable} from "@simple-table/react";import type { Theme, ReactIconsConfig } from "@simple-table/react";2import { customIconsConfig } from "./custom-icons.demo-data";3import "@simple-table/react/styles.css";45const customIcons: ReactIconsConfig = {6 sortUp: (7 <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#6366f1" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">8 <path d="M12 19V5M5 12l7-7 7 7" />9 </svg>10 ),11 sortDown: (12 <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#6366f1" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">13 <path d="M12 5v14M19 12l-7 7-7-7" />14 </svg>15 ),16 filter: (17 <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#8b5cf6" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">18 <path d="M3 4h18l-7 8.5V18l-4 2V12.5L3 4z" />19 </svg>20 ),21 expand: (22 <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#6366f1" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">23 <path d="M9 5l7 7-7 7" />24 </svg>25 ),26 next: (27 <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#2563eb" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">28 <path d="M9 5l7 7-7 7" />29 </svg>30 ),31 prev: (32 <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#2563eb" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">33 <path d="M15 19l-7-7 7-7" />34 </svg>35 )36};3738const CustomIconsDemo = ({39 height = "400px",40 theme41}: {42 height?: string | number;43 theme?: Theme;44}) => {45 return (46 <SimpleTable47 columns={customIconsConfig.headers}48 rows={customIconsConfig.rows}49 icons={customIcons}50 height={height}51 theme={theme}52 getRowId={({ row }) => row.id}53 />54 );55};5657export default CustomIconsDemo;
Angularcustom-icons-demo.component.ts
Copy
1import { Component, Input } from "@angular/core";2import { SimpleTableComponent } from "@simple-table/angular";3import type { AngularColumnDef, AngularIconsConfig, GetRowIdParams, Theme } from "@simple-table/angular";4import { customIconsConfig } from "./custom-icons.demo-data";5import {6 DemoExpandIconComponent,7 DemoFilterIconComponent,8 DemoNextIconComponent,9 DemoPrevIconComponent,10 DemoSortDownIconComponent,11 DemoSortUpIconComponent,12} from "./table-icons.components";13import "@simple-table/angular/styles.css";14import type { SoftwareRelease } from "./custom-icons.demo-data";1516@Component({17 selector: "custom-icons-demo",18 standalone: true,19 imports: [SimpleTableComponent],20 template: `21 <simple-table22 [getRowId]="getRowId"23 [rows]="rows"24 [columns]="headers"25 [height]="height"26 [theme]="theme"27 [icons]="icons"28 ></simple-table>29 `,30})31export class CustomIconsDemoComponent {32 @Input() height: string | number = "400px";33 @Input() theme?: Theme;3435 readonly rows: SoftwareRelease[] = customIconsConfig.rows;36 readonly headers: AngularColumnDef<SoftwareRelease>[] = customIconsConfig.headers;37 readonly icons: AngularIconsConfig = {38 sortUp: DemoSortUpIconComponent,39 sortDown: DemoSortDownIconComponent,40 filter: DemoFilterIconComponent,41 expand: DemoExpandIconComponent,42 next: DemoNextIconComponent,43 prev: DemoPrevIconComponent,44 };4546 getRowId = ({ row }: GetRowIdParams<SoftwareRelease>) => row.id;47}484950// custom-icons.demo-data.ts51// Self-contained demo table setup for this example.52import type { AngularColumnDef, ValueFormatterProps } from "@simple-table/angular";5354export interface SoftwareRelease {55 id: number;56 name: string;57 version: string;58 status: string;59 downloads: number;60 date: string;61}6263export const customIconsData: SoftwareRelease[] = [64 { id: 1, name: "Alpha Release", version: "1.0.0", status: "released", downloads: 15420, date: "2024-01-15" },65 { id: 2, name: "Beta Release", version: "1.1.0", status: "released", downloads: 28300, date: "2024-03-22" },66 { id: 3, name: "Hotfix", version: "1.1.1", status: "released", downloads: 31050, date: "2024-04-05" },67 { id: 4, name: "Feature Update", version: "1.2.0", status: "released", downloads: 42100, date: "2024-06-10" },68 { id: 5, name: "Security Patch", version: "1.2.1", status: "released", downloads: 45800, date: "2024-07-18" },69 { id: 6, name: "Major Release", version: "2.0.0", status: "released", downloads: 67200, date: "2024-09-01" },70 { id: 7, name: "Minor Update", version: "2.1.0", status: "beta", downloads: 8900, date: "2024-11-12" },71 { id: 8, name: "Next Release", version: "2.2.0", status: "planned", downloads: 0, date: "2025-01-20" },72];7374export const customIconsHeaders: AngularColumnDef<SoftwareRelease, any>[] = [75 { accessor: "id", label: "ID", width: 60, type: "number", sortable: true },76 { accessor: "name", label: "Release", width: 170, type: "string", sortable: true },77 { accessor: "version", label: "Version", width: 100, type: "string", sortable: true },78 { accessor: "status", label: "Status", width: 110, type: "string", sortable: true },79 {80 accessor: "downloads",81 label: "Downloads",82 width: 130,83 type: "number",84 sortable: true,85 valueFormatter: ({ value }: ValueFormatterProps<SoftwareRelease, number>) => value.toLocaleString(),86 },87 {88 accessor: "date",89 label: "Date",90 width: 130,91 type: "date",92 sortable: true,93 valueFormatter: ({ value }: ValueFormatterProps<SoftwareRelease, string>) => new Date(value).toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" }),94 },95];9697export const customIconsConfig = {98 headers: customIconsHeaders,99 rows: customIconsData,100};101102103// table-icons.components.ts104import { Component } from "@angular/core";105106@Component({107 standalone: true,108 selector: "demo-icon-sort-up",109 template: `110 <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#6366f1" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">111 <path d="M12 19V5M5 12l7-7 7 7" />112 </svg>113 `,114})115export class DemoSortUpIconComponent {}116117@Component({118 standalone: true,119 selector: "demo-icon-sort-down",120 template: `121 <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#6366f1" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">122 <path d="M12 5v14M19 12l-7 7-7-7" />123 </svg>124 `,125})126export class DemoSortDownIconComponent {}127128@Component({129 standalone: true,130 selector: "demo-icon-filter",131 template: `132 <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#8b5cf6" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">133 <path d="M3 4h18l-7 8.5V18l-4 2V12.5L3 4z" />134 </svg>135 `,136})137export class DemoFilterIconComponent {}138139@Component({140 standalone: true,141 selector: "demo-icon-expand",142 template: `143 <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#6366f1" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">144 <path d="M9 5l7 7-7 7" />145 </svg>146 `,147})148export class DemoExpandIconComponent {}149150@Component({151 standalone: true,152 selector: "demo-icon-next",153 template: `154 <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#2563eb" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">155 <path d="M9 5l7 7-7 7" />156 </svg>157 `,158})159export class DemoNextIconComponent {}160161@Component({162 standalone: true,163 selector: "demo-icon-prev",164 template: `165 <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#2563eb" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">166 <path d="M15 19l-7-7 7-7" />167 </svg>168 `,169})170export class DemoPrevIconComponent {}171
Vue SFC
Copy
1<script setup lang="ts">2import { h } from "vue";3import { SimpleTable } from "@simple-table/vue";4import type { Theme, VueIconsConfig, GetRowIdParams } from "@simple-table/vue";5import { customIconsConfig } from "./custom-icons.demo-data";6import type { SoftwareRelease } from "./custom-icons.demo-data";7import "@simple-table/vue/styles.css";89const props = withDefaults(defineProps<{ height?: string | number; theme?: Theme }>(), {10 height: "400px",11});1213function iconSvg(pathD: string, color: string, strokeWidth = "2.5") {14 return h(15 "svg",16 {17 width: 14,18 height: 14,19 viewBox: "0 0 24 24",20 fill: "none",21 stroke: color,22 strokeWidth,23 strokeLinecap: "round",24 strokeLinejoin: "round",25 },26 [h("path", { d: pathD })],27 );28}2930const getRowId = ({ row }: GetRowIdParams<SoftwareRelease>) => row.id;3132const icons: VueIconsConfig = {33 sortUp: iconSvg("M12 19V5M5 12l7-7 7 7", "#6366f1"),34 sortDown: iconSvg("M12 5v14M19 12l-7 7-7-7", "#6366f1"),35 filter: iconSvg("M3 4h18l-7 8.5V18l-4 2V12.5L3 4z", "#8b5cf6", "2"),36 expand: iconSvg("M9 5l7 7-7 7", "#6366f1"),37 next: iconSvg("M9 5l7 7-7 7", "#2563eb"),38 prev: iconSvg("M15 19l-7-7 7-7", "#2563eb"),39};40</script>4142<template>43 <SimpleTable44 :columns="customIconsConfig.headers"45 :rows="customIconsConfig.rows"46 :get-row-id="getRowId"47 :icons="icons"48 :height="props.height"49 :theme="props.theme"50 />51</template>
Svelte
Copy
1<script lang="ts">2 import { SimpleTable } from "@simple-table/svelte";3 import type { Theme, SvelteIconsConfig, GetRowIdParams } from "@simple-table/svelte";4 import { customIconsConfig } from "./custom-icons.demo-data";5 import type { SoftwareRelease } from "./custom-icons.demo-data";6 import IconSortUp from "./icons/IconSortUp.svelte";7 import IconSortDown from "./icons/IconSortDown.svelte";8 import IconFilter from "./icons/IconFilter.svelte";9 import IconExpand from "./icons/IconExpand.svelte";10 import IconNext from "./icons/IconNext.svelte";11 import IconPrev from "./icons/IconPrev.svelte";12 import "@simple-table/svelte/styles.css";1314 let { height = "400px", theme }: { height?: string | number; theme?: Theme } = $props();1516 const icons: SvelteIconsConfig = {17 sortUp: IconSortUp,18 sortDown: IconSortDown,19 filter: IconFilter,20 expand: IconExpand,21 next: IconNext,22 prev: IconPrev,23 };2425 const getRowId = ({ row }: GetRowIdParams<SoftwareRelease>) => row.id;26</script>2728<SimpleTable29 columns={customIconsConfig.headers}30 rows={customIconsConfig.rows}31 getRowId={getRowId}32 {icons}33 {height}34 {theme}35/>
Solid TSX
Copy
1import {SimpleTable} from "@simple-table/solid";import type { Theme, SolidIconsConfig } from "@simple-table/solid";2import { customIconsConfig } from "./custom-icons.demo-data";3import "@simple-table/solid/styles.css";45const customIcons: SolidIconsConfig = {6 sortUp: (7 <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#6366f1" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">8 <path d="M12 19V5M5 12l7-7 7 7" />9 </svg>10 ),11 sortDown: (12 <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#6366f1" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">13 <path d="M12 5v14M19 12l-7 7-7-7" />14 </svg>15 ),16 filter: (17 <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#8b5cf6" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">18 <path d="M3 4h18l-7 8.5V18l-4 2V12.5L3 4z" />19 </svg>20 ),21 expand: (22 <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#6366f1" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">23 <path d="M9 5l7 7-7 7" />24 </svg>25 ),26 next: (27 <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#2563eb" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">28 <path d="M9 5l7 7-7 7" />29 </svg>30 ),31 prev: (32 <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#2563eb" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">33 <path d="M15 19l-7-7 7-7" />34 </svg>35 ),36};3738export default function CustomIconsDemo(props: { height?: string | number; theme?: Theme }) {39 return (40 <SimpleTable41 columns={customIconsConfig.headers}42 getRowId={({ row }) => row.id}43 rows={customIconsConfig.rows}44 height={props.height ?? "400px"}45 theme={props.theme}46 icons={customIcons}47 />48 );49}
TypeScriptCustomIconsDemo.ts
Copy
1import { SimpleTableVanilla } from "simple-table-core";2import type { Theme, IconsConfig, GetRowIdParams } from "simple-table-core";3import { customIconsConfig } from "./custom-icons.demo-data";4import type { SoftwareRelease } from "./custom-icons.demo-data";5import "simple-table-core/styles.css";67function iconSvg(pathD: string, color: string, strokeWidth = "2.5"): SVGSVGElement {8 const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");9 svg.setAttribute("width", "14");10 svg.setAttribute("height", "14");11 svg.setAttribute("viewBox", "0 0 24 24");12 svg.setAttribute("fill", "none");13 svg.setAttribute("stroke", color);14 svg.setAttribute("stroke-width", strokeWidth);15 svg.setAttribute("stroke-linecap", "round");16 svg.setAttribute("stroke-linejoin", "round");17 const path = document.createElementNS("http://www.w3.org/2000/svg", "path");18 path.setAttribute("d", pathD);19 svg.appendChild(path);20 return svg;21}2223const getRowId = ({ row }: GetRowIdParams<SoftwareRelease>) => row.id;2425const icons: IconsConfig = {26 sortUp: iconSvg("M12 19V5M5 12l7-7 7 7", "#6366f1"),27 sortDown: iconSvg("M12 5v14M19 12l-7 7-7-7", "#6366f1"),28 filter: iconSvg("M3 4h18l-7 8.5V18l-4 2V12.5L3 4z", "#8b5cf6", "2"),29 expand: iconSvg("M9 5l7 7-7 7", "#6366f1"),30 next: iconSvg("M9 5l7 7-7 7", "#2563eb"),31 prev: iconSvg("M15 19l-7-7 7-7", "#2563eb"),32};3334export function renderCustomIconsDemo(35 container: HTMLElement,36 options?: { height?: string | number; theme?: Theme },37): SimpleTableVanilla<SoftwareRelease> {38 return new SimpleTableVanilla(container, {39 getRowId,40 columns: customIconsConfig.headers,41 rows: customIconsConfig.rows,42 height: options?.height ?? "400px",43 theme: options?.theme,44 icons,45 });46}474849// custom-icons.demo-data.ts50// Self-contained demo table setup for this example.51import type { ColumnDef } from "simple-table-core";5253export interface SoftwareRelease {54 id: number;55 name: string;56 version: string;57 status: string;58 downloads: number;59 date: string;60}6162export const customIconsData: SoftwareRelease[] = [63 { id: 1, name: "Alpha Release", version: "1.0.0", status: "released", downloads: 15420, date: "2024-01-15" },64 { id: 2, name: "Beta Release", version: "1.1.0", status: "released", downloads: 28300, date: "2024-03-22" },65 { id: 3, name: "Hotfix", version: "1.1.1", status: "released", downloads: 31050, date: "2024-04-05" },66 { id: 4, name: "Feature Update", version: "1.2.0", status: "released", downloads: 42100, date: "2024-06-10" },67 { id: 5, name: "Security Patch", version: "1.2.1", status: "released", downloads: 45800, date: "2024-07-18" },68 { id: 6, name: "Major Release", version: "2.0.0", status: "released", downloads: 67200, date: "2024-09-01" },69 { id: 7, name: "Minor Update", version: "2.1.0", status: "beta", downloads: 8900, date: "2024-11-12" },70 { id: 8, name: "Next Release", version: "2.2.0", status: "planned", downloads: 0, date: "2025-01-20" },71];7273export const customIconsHeaders: ColumnDef<SoftwareRelease>[] = [74 { accessor: "id", label: "ID", width: 60, type: "number", sortable: true },75 { accessor: "name", label: "Release", width: 170, type: "string", sortable: true },76 { accessor: "version", label: "Version", width: 100, type: "string", sortable: true },77 { accessor: "status", label: "Status", width: 110, type: "string", sortable: true },78 {79 accessor: "downloads",80 label: "Downloads",81 width: 130,82 type: "number",83 sortable: true,84 valueFormatter: ({ value }) => Number(value).toLocaleString(),85 },86 {87 accessor: "date",88 label: "Date",89 width: 130,90 type: "date",91 sortable: true,92 valueFormatter: ({ value }) => new Date(String(value)).toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" }),93 },94];9596export const customIconsConfig = {97 headers: customIconsHeaders,98 rows: customIconsData,99};100
Props
Icons Configuration
| Property | Required | Description | Example |
|---|---|---|---|
Property | Required | Description | Example |
iconsIconsConfig | Optional | Partial icon map. Unset keys keep the built-in icons. | |
icons.sortUpIconElement | Optional | Ascending sort indicator in column headers. | |
icons.sortDownIconElement | Optional | Descending sort indicator in column headers. | |
icons.filterIconElement | Optional | Column filter button. | |
icons.expandIconElement | Optional | Collapsed row-group expand control. | |
icons.headerExpandIconElement | Optional | Collapsed nested column header. | |
icons.headerCollapseIconElement | Optional | Expanded nested column header. | |
icons.prevIconElement | Optional | Pagination previous button. | |
icons.nextIconElement | Optional | Pagination next button. | |
icons.dragIconElement | Optional | Column editor drag handle. | |
icons.pinnedLeftIconIconElement | Optional | Column editor pin-left control. | |
icons.pinnedRightIconIconElement | Optional | Column editor pin-right control. |