diff --git a/README.md b/README.md index 358c558c4..99118b6c2 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,25 @@ Simple Table provides first-class adapters for the most popular frameworks: ## Quick Start +Pick the install for your stack: + ```bash +# React +npm install @simple-table/react + +# Vue 3 / Nuxt +npm install @simple-table/vue + +# Angular 17+ +npm install @simple-table/angular + +# Svelte / SvelteKit +npm install @simple-table/svelte + +# Solid / Solid Start +npm install @simple-table/solid + +# Vanilla JS / TypeScript / web components npm install simple-table-core ``` diff --git a/apps/marketing/package.json b/apps/marketing/package.json index 4257606ab..5f4ce911c 100644 --- a/apps/marketing/package.json +++ b/apps/marketing/package.json @@ -13,7 +13,6 @@ "analyze": "ANALYZE=true next build --webpack", "start": "next start", "lint": "next lint", - "generate-sitemap": "node scripts/generate-sitemap.js", "generate-sales-data": "tsx scripts/generate-sales-data.ts", "generate-billing-data": "tsx scripts/generate-billing-data.ts", "generate-manufacturing-data": "tsx scripts/generate-manufacturing-data.ts", @@ -24,7 +23,7 @@ "generate-all-data": "pnpm run generate-sales-data && pnpm run generate-billing-data && pnpm run generate-manufacturing-data && pnpm run generate-infrastructure-data && pnpm run generate-hr-data && pnpm run generate-crm-data && pnpm run generate-music-data", "copy-to-txt": "node scripts/copy-to-txt.js", "generate-search-index": "node scripts/generate-search-index.cjs", - "publish": "pnpm install && pnpm run copy-to-txt && pnpm run generate-sitemap && git add . && git commit -m \"$npm_config_message\" && git push" + "publish": "pnpm install && pnpm run copy-to-txt && git add . && git commit -m \"$npm_config_message\" && git push" }, "dependencies": { "@ant-design/cssinjs": "^1.23.0", @@ -74,9 +73,7 @@ "eslint": "^9", "eslint-plugin-react-hooks": "^5.1.0", "eslint-plugin-react-refresh": "^0.4.19", - "glob": "^11.0.3", "node-fetch": "^3.3.2", - "sitemap": "^8.0.0", "ts-node": "^10.9.2", "tsx": "^4.19.4", "typescript-eslint": "^8.24.1" diff --git a/apps/marketing/public/llms.txt b/apps/marketing/public/llms.txt new file mode 100644 index 000000000..c297cbcdb --- /dev/null +++ b/apps/marketing/public/llms.txt @@ -0,0 +1,71 @@ +# Simple Table + +> A free, MIT-licensed data grid for React, Vue, Angular, Svelte, Solid, and vanilla TypeScript. One shared simple-table-core engine; six official npm adapters. Ships virtualization for 1M+ rows, column pinning, row grouping with aggregations, inline cell editing, custom renderers, and themeable CSS variables. + +Simple Table is positioned as a feature-complete free alternative to AG Grid (Enterprise), MUI X Data Grid (Pro), Handsontable, Tabulator, and TanStack Table. The core engine is framework-agnostic and runs the same logic across every adapter. + +## Frameworks and packages + +- React — `@simple-table/react` — peer: React 18+, works with Next.js (App Router and Pages), Remix, Vite. https://www.simple-table.com/frameworks/react +- Vue — `@simple-table/vue` — peer: Vue 3+, works with Nuxt 3/4 and Vite. https://www.simple-table.com/frameworks/vue +- Angular — `@simple-table/angular` — peer: Angular 17+ (standalone components), works with Angular CLI and Analog. https://www.simple-table.com/frameworks/angular +- Svelte — `@simple-table/svelte` — peer: Svelte 4 / Svelte 5 (runes), works with SvelteKit and Vite. https://www.simple-table.com/frameworks/svelte +- Solid — `@simple-table/solid` — peer: solid-js 1+, works with Solid Start and Vite. https://www.simple-table.com/frameworks/solid +- Vanilla TypeScript / Web Components — `simple-table-core` — no peer; bring-your-own DOM glue. https://www.simple-table.com/frameworks/vanilla + +## Install + +- npm install @simple-table/react +- npm install @simple-table/vue +- npm install @simple-table/angular +- npm install @simple-table/svelte +- npm install @simple-table/solid +- npm install simple-table-core + +## Pillar guides + +- React — Best free React data grid 2026: https://www.simple-table.com/blog/best-free-react-data-grid-2026 +- Vue / Nuxt — https://www.simple-table.com/blog/vue-nuxt-data-grid-simple-table +- Angular — https://www.simple-table.com/blog/angular-data-grid-simple-table +- SvelteKit — https://www.simple-table.com/blog/sveltekit-data-table-simple-table +- Solid.js — https://www.simple-table.com/blog/solidjs-data-grid-simple-table +- Vanilla TypeScript — https://www.simple-table.com/blog/vanilla-typescript-data-grid-simple-table-core + +## Comparisons (React-focused, vs. cross-stack incumbents) + +- vs AG Grid: https://www.simple-table.com/comparisons/simple-table-vs-ag-grid +- vs Handsontable: https://www.simple-table.com/comparisons/simple-table-vs-handsontable +- vs TanStack Table: https://www.simple-table.com/comparisons/simple-table-vs-tanstack +- vs Material React Table: https://www.simple-table.com/comparisons/simple-table-vs-material-react +- vs Ant Design Table: https://www.simple-table.com/comparisons/simple-table-vs-ant-design +- vs Tabulator: https://www.simple-table.com/comparisons/simple-table-vs-tabulator +- vs Syncfusion Grid: https://www.simple-table.com/comparisons/simple-table-vs-syncfusion + +## Stack-native alternatives Simple Table competes with + +- React: AG Grid React, TanStack Table, MUI X Data Grid, Material React Table, react-data-grid, Handsontable React, Kendo React Grid +- Vue: Vuetify v-data-table, PrimeVue DataTable, Vue Good Table, Element Plus el-table, Naive UI n-data-table, Quasar QTable, AG Grid Vue +- Angular: AG Grid Angular, ngx-datatable, PrimeNG Table, Angular Material MatTable, Kendo UI for Angular Grid, DevExtreme Angular Grid +- Svelte: svelte-headless-table, SVAR DataGrid, Flowbite-Svelte Table, Carbon Components Svelte DataTable +- Solid: TanStack Solid Table, Kobalte Table primitive +- Vanilla: Tabulator, Grid.js, jSpreadsheet, Handsontable Community, Webix DataTable, DataTables (jQuery) + +## License + +- Source-available, MIT for pre-revenue and bootstrapped projects. +- Pro / Enterprise tiers available for revenue-generating teams. +- License: https://www.simple-table.com/legal/license +- Pricing: https://www.simple-table.com/pricing + +## Documentation + +- Quick start: https://www.simple-table.com/docs/quick-start +- Installation: https://www.simple-table.com/docs/installation +- Full feature list: https://www.simple-table.com/docs/api-reference +- Examples (CRM, HR, billing, manufacturing, infrastructure, music, sales): https://www.simple-table.com/examples +- Theme builder: https://www.simple-table.com/theme-builder + +## Source + +- GitHub: https://github.com/petera2c/simple-table +- npm org: https://www.npmjs.com/org/simple-table diff --git a/apps/marketing/public/sitemap.xml b/apps/marketing/public/sitemap.xml deleted file mode 100644 index a28a10eae..000000000 --- a/apps/marketing/public/sitemap.xml +++ /dev/null @@ -1,578 +0,0 @@ - - - - https://www.simple-table.com/ - daily - 1.0 - - - https://www.simple-table.com/blog - weekly - 0.6 - - - https://www.simple-table.com/blog/ag-grid-alternatives-free-react-data-grids - monthly - 0.8 - - - https://www.simple-table.com/blog/ag-grid-pricing-license-breakdown-2026 - monthly - 0.8 - - - https://www.simple-table.com/blog/angular-data-grid-simple-table - monthly - 0.8 - - - https://www.simple-table.com/blog/ant-design-table-vs-simple-table - monthly - 0.8 - - - https://www.simple-table.com/blog/auto-expand-columns-react-tables - monthly - 0.8 - - - https://www.simple-table.com/blog/best-free-react-data-grid-2026 - monthly - 0.8 - - - https://www.simple-table.com/blog/best-react-table-libraries-2026 - monthly - 0.8 - - - https://www.simple-table.com/blog/custom-footer-renderers-react-tables - monthly - 0.8 - - - https://www.simple-table.com/blog/custom-icons-react-data-grids - monthly - 0.8 - - - https://www.simple-table.com/blog/customizing-data-grids-styling-easy - monthly - 0.8 - - - https://www.simple-table.com/blog/customizing-react-table-look-simple-table-themes - monthly - 0.8 - - - https://www.simple-table.com/blog/devextreme-grid-vs-simple-table - monthly - 0.8 - - - https://www.simple-table.com/blog/editable-react-data-grids-in-cell-vs-form-editing - monthly - 0.8 - - - https://www.simple-table.com/blog/free-alternative-to-ag-grid - monthly - 0.8 - - - https://www.simple-table.com/blog/handling-one-million-rows - monthly - 0.8 - - - https://www.simple-table.com/blog/handsontable-alternatives-free-react - monthly - 0.8 - - - https://www.simple-table.com/blog/handsontable-pricing-breakdown-2026 - monthly - 0.8 - - - https://www.simple-table.com/blog/ka-table-vs-simple-table - monthly - 0.8 - - - https://www.simple-table.com/blog/kendoreact-grid-vs-simple-table - monthly - 0.8 - - - https://www.simple-table.com/blog/mantine-datatable-vs-simple-table - monthly - 0.8 - - - https://www.simple-table.com/blog/material-react-table-vs-simple-table - monthly - 0.8 - - - https://www.simple-table.com/blog/mit-licensed-react-tables-accessibility-keyboard-navigation - monthly - 0.8 - - - https://www.simple-table.com/blog/mobile-compatibility-react-tables - monthly - 0.8 - - - https://www.simple-table.com/blog/mui-datatables-vs-simple-table - monthly - 0.8 - - - https://www.simple-table.com/blog/nested-headers-react-tables - monthly - 0.8 - - - https://www.simple-table.com/blog/nested-tables-react-hierarchical-data - monthly - 0.8 - - - https://www.simple-table.com/blog/react-data-grid-bundle-size-comparison - monthly - 0.8 - - - https://www.simple-table.com/blog/react-data-table-component-vs-simple-table - monthly - 0.8 - - - https://www.simple-table.com/blog/react-grid-column-pinning-tutorial - monthly - 0.8 - - - https://www.simple-table.com/blog/react-grid-filtering-implementation - monthly - 0.8 - - - https://www.simple-table.com/blog/react-table-column-resizing-guide - monthly - 0.8 - - - https://www.simple-table.com/blog/react-table-library-vs-simple-table - monthly - 0.8 - - - https://www.simple-table.com/blog/react-table-row-selection-guide - monthly - 0.8 - - - https://www.simple-table.com/blog/react-tree-data-hierarchical-tables - monthly - 0.8 - - - https://www.simple-table.com/blog/replicating-gojiberry-ui-simple-table - monthly - 0.8 - - - https://www.simple-table.com/blog/rsuite-table-vs-simple-table - monthly - 0.8 - - - https://www.simple-table.com/blog/smart-grid-vs-simple-table - monthly - 0.8 - - - https://www.simple-table.com/blog/solidjs-data-grid-simple-table - monthly - 0.8 - - - https://www.simple-table.com/blog/sveltekit-data-table-simple-table - monthly - 0.8 - - - https://www.simple-table.com/blog/tabulator-alternatives-react-2026 - monthly - 0.8 - - - https://www.simple-table.com/blog/tanstack-table-vs-ag-grid-comparison - monthly - 0.8 - - - https://www.simple-table.com/blog/tanstack-table-vs-simple-table-headless-batteries-included - monthly - 0.8 - - - https://www.simple-table.com/blog/vanilla-typescript-data-grid-simple-table-core - monthly - 0.8 - - - https://www.simple-table.com/blog/vue-nuxt-data-grid-simple-table - monthly - 0.8 - - - https://www.simple-table.com/case-studies/chartmetric - monthly - 0.9 - - - https://www.simple-table.com/changelog - weekly - 0.6 - - - https://www.simple-table.com/comparisons/simple-table-vs-ag-grid - weekly - 0.9 - - - https://www.simple-table.com/comparisons/simple-table-vs-ant-design - weekly - 0.9 - - - https://www.simple-table.com/comparisons/simple-table-vs-handsontable - weekly - 0.9 - - - https://www.simple-table.com/comparisons/simple-table-vs-material-react - weekly - 0.9 - - - https://www.simple-table.com/comparisons/simple-table-vs-syncfusion - weekly - 0.9 - - - https://www.simple-table.com/comparisons/simple-table-vs-tabulator - weekly - 0.9 - - - https://www.simple-table.com/comparisons/simple-table-vs-tanstack - weekly - 0.9 - - - https://www.simple-table.com/docs/aggregate-functions - weekly - 0.8 - - - https://www.simple-table.com/docs/cell-clicking - weekly - 0.8 - - - https://www.simple-table.com/docs/cell-editing - weekly - 0.8 - - - https://www.simple-table.com/docs/cell-highlighting - weekly - 0.8 - - - https://www.simple-table.com/docs/cell-renderer - weekly - 0.8 - - - https://www.simple-table.com/docs/chart-columns - weekly - 0.8 - - - https://www.simple-table.com/docs/collapsible-columns - weekly - 0.8 - - - https://www.simple-table.com/docs/column-alignment - weekly - 0.8 - - - https://www.simple-table.com/docs/column-editing - weekly - 0.8 - - - https://www.simple-table.com/docs/column-filtering - weekly - 0.8 - - - https://www.simple-table.com/docs/column-pinning - weekly - 0.8 - - - https://www.simple-table.com/docs/column-reordering - weekly - 0.8 - - - https://www.simple-table.com/docs/column-resizing - weekly - 0.8 - - - https://www.simple-table.com/docs/column-selection - weekly - 0.8 - - - https://www.simple-table.com/docs/column-sorting - weekly - 0.8 - - - https://www.simple-table.com/docs/column-visibility - weekly - 0.8 - - - https://www.simple-table.com/docs/column-width - weekly - 0.8 - - - https://www.simple-table.com/docs/csv-export - weekly - 0.8 - - - https://www.simple-table.com/docs/custom-icons - weekly - 0.8 - - - https://www.simple-table.com/docs/custom-theme - weekly - 0.8 - - - https://www.simple-table.com/docs/empty-state - weekly - 0.8 - - - https://www.simple-table.com/docs/footer-renderer - weekly - 0.8 - - - https://www.simple-table.com/docs/header-renderer - weekly - 0.8 - - - https://www.simple-table.com/docs/infinite-scroll - weekly - 0.8 - - - https://www.simple-table.com/docs/installation - weekly - 0.8 - - - https://www.simple-table.com/docs/live-updates - weekly - 0.8 - - - https://www.simple-table.com/docs/loading-state - weekly - 0.8 - - - https://www.simple-table.com/docs/nested-headers - weekly - 0.8 - - - https://www.simple-table.com/docs/nested-tables - weekly - 0.8 - - - https://www.simple-table.com/docs/pagination - weekly - 0.8 - - - https://www.simple-table.com/docs/programmatic-control - weekly - 0.8 - - - https://www.simple-table.com/docs/quick-filter - weekly - 0.8 - - - https://www.simple-table.com/docs/quick-start - weekly - 0.8 - - - https://www.simple-table.com/docs/row-grouping - weekly - 0.8 - - - https://www.simple-table.com/docs/row-height - weekly - 0.8 - - - https://www.simple-table.com/docs/row-selection - weekly - 0.8 - - - https://www.simple-table.com/docs/table-height - weekly - 0.8 - - - https://www.simple-table.com/docs/themes - weekly - 0.8 - - - https://www.simple-table.com/docs/tooltips - weekly - 0.8 - - - https://www.simple-table.com/docs/value-formatter - weekly - 0.8 - - - https://www.simple-table.com/examples/billing - weekly - 0.7 - - - https://www.simple-table.com/examples/crm - weekly - 0.7 - - - https://www.simple-table.com/examples/hr - weekly - 0.7 - - - https://www.simple-table.com/examples/infrastructure - weekly - 0.7 - - - https://www.simple-table.com/examples/manufacturing - weekly - 0.7 - - - https://www.simple-table.com/examples/music - weekly - 0.7 - - - https://www.simple-table.com/examples/sales - weekly - 0.7 - - - https://www.simple-table.com/frameworks - weekly - 0.8 - - - https://www.simple-table.com/frameworks/angular - weekly - 0.8 - - - https://www.simple-table.com/frameworks/react - weekly - 0.8 - - - https://www.simple-table.com/frameworks/solid - weekly - 0.8 - - - https://www.simple-table.com/frameworks/svelte - weekly - 0.8 - - - https://www.simple-table.com/frameworks/vanilla - weekly - 0.8 - - - https://www.simple-table.com/frameworks/vue - weekly - 0.8 - - - https://www.simple-table.com/legal/eula - monthly - 0.5 - - - https://www.simple-table.com/legal/license - monthly - 0.5 - - - https://www.simple-table.com/migrations/v2-4-1 - weekly - 0.6 - - - https://www.simple-table.com/migrations/v3 - weekly - 0.6 - - - https://www.simple-table.com/pricing - weekly - 0.6 - - - https://www.simple-table.com/theme-builder - weekly - 0.6 - - \ No newline at end of file diff --git a/apps/marketing/public/txt-demos/angular/animations.txt b/apps/marketing/public/txt-demos/angular/animations.txt new file mode 100644 index 000000000..6a2d4c285 --- /dev/null +++ b/apps/marketing/public/txt-demos/angular/animations.txt @@ -0,0 +1,78 @@ +// animations-demo.component.ts +import { Component, Input } from "@angular/core"; +import { SimpleTableComponent } from "@simple-table/angular"; +import type { AngularHeaderObject, Row, Theme } from "@simple-table/angular"; +import { animationsConfig } from "./animations.demo-data"; +import "@simple-table/angular/styles.css"; + +@Component({ + selector: "animations-demo", + standalone: true, + imports: [SimpleTableComponent], + template: ` + + `, +}) +export class AnimationsDemoComponent { + @Input() height: string | number = "400px"; + @Input() theme?: Theme; + + readonly rows: Row[] = animationsConfig.rows; + headers: AngularHeaderObject[] = [...animationsConfig.headers]; + + onColumnOrderChange(newHeaders: AngularHeaderObject[]): void { + this.headers = newHeaders; + } +} + + +// animations.demo-data.ts +// Self-contained demo table setup for this example. +import type { AngularHeaderObject } from "@simple-table/angular"; + + +export const animationsHeaders: AngularHeaderObject[] = [ + { accessor: "id", label: "ID", width: 60, isSortable: true, type: "number" }, + { accessor: "name", label: "Name", minWidth: 140, width: "1fr", isSortable: true, type: "string" }, + { accessor: "age", label: "Age", width: 80, align: "right", isSortable: true, type: "number" }, + { accessor: "role", label: "Role", minWidth: 140, width: "1fr", isSortable: true, type: "string" }, + { + accessor: "department", + disableReorder: true, + isSortable: true, + label: "Department", + minWidth: 140, + width: "1fr", + type: "string", + }, +]; + +export const animationsData = [ + { id: 1, name: "Captain Stella Vega", age: 38, role: "Mission Commander", department: "Flight Operations" }, + { id: 2, name: "Dr. Cosmos Rivera", age: 34, role: "Astrophysicist", department: "Science" }, + { id: 3, name: "Commander Nebula Johnson", age: 42, role: "Operations Director", department: "Mission Control" }, + { id: 4, name: "Cadet Orbit Williams", age: 26, role: "Flight Engineer", department: "Engineering" }, + { id: 5, name: "Dr. Galaxy Chen", age: 31, role: "Life Support Specialist", department: "Engineering" }, + { id: 6, name: "Lt. Meteor Lee", age: 29, role: "Navigation Officer", department: "Flight Operations" }, + { id: 7, name: "Dr. Comet Hassan", age: 33, role: "Mission Planner", department: "Planning" }, + { id: 8, name: "Major Pulsar White", age: 36, role: "Communications Director", department: "Communications" }, + { id: 9, name: "Specialist Quasar Black", age: 28, role: "Systems Analyst", department: "Technology" }, + { id: 10, name: "Engineer Supernova Blue", age: 35, role: "Propulsion Engineer", department: "Engineering" }, + { id: 11, name: "Dr. Aurora Kumar", age: 30, role: "Planetary Geologist", department: "Science" }, + { id: 12, name: "Admiral Cosmos Silver", age: 45, role: "Program Director", department: "Leadership" }, +]; + +export const animationsConfig = { + headers: animationsHeaders, + rows: animationsData, + tableProps: { columnReordering: true, editColumns: true, editColumnsInitOpen: true }, +} as const; diff --git a/apps/marketing/public/txt-demos/react/animations.txt b/apps/marketing/public/txt-demos/react/animations.txt new file mode 100644 index 000000000..4d64adb61 --- /dev/null +++ b/apps/marketing/public/txt-demos/react/animations.txt @@ -0,0 +1,34 @@ +import { useState } from "react"; +import { SimpleTable } from "@simple-table/react"; +import type { Theme, ReactHeaderObject } from "@simple-table/react"; +import { animationsConfig } from "./animations.demo-data"; +import "@simple-table/react/styles.css"; + +const AnimationsDemo = ({ + height = "400px", + theme, +}: { + height?: string | number; + theme?: Theme; +}) => { + const [headers, setHeaders] = useState(() => [...animationsConfig.headers]); + + const handleColumnOrderChange = (newHeaders: ReactHeaderObject[]) => { + setHeaders(newHeaders); + }; + + return ( + + ); +}; + +export default AnimationsDemo; diff --git a/apps/marketing/public/txt-demos/solid/animations.txt b/apps/marketing/public/txt-demos/solid/animations.txt new file mode 100644 index 000000000..df8ebe957 --- /dev/null +++ b/apps/marketing/public/txt-demos/solid/animations.txt @@ -0,0 +1,22 @@ +import { createSignal } from "solid-js"; +import { SimpleTable } from "@simple-table/solid"; +import type { Theme } from "@simple-table/solid"; +import { animationsConfig } from "./animations.demo-data"; +import "@simple-table/solid/styles.css"; + +export default function AnimationsDemo(props: { height?: string | number; theme?: Theme }) { + const [headers, setHeaders] = createSignal([...animationsConfig.headers]); + + return ( + + ); +} diff --git a/apps/marketing/public/txt-demos/svelte/animations.txt b/apps/marketing/public/txt-demos/svelte/animations.txt new file mode 100644 index 000000000..225e79c84 --- /dev/null +++ b/apps/marketing/public/txt-demos/svelte/animations.txt @@ -0,0 +1,24 @@ + + + diff --git a/apps/marketing/public/txt-demos/vanilla/animations.txt b/apps/marketing/public/txt-demos/vanilla/animations.txt new file mode 100644 index 000000000..4228a76a8 --- /dev/null +++ b/apps/marketing/public/txt-demos/vanilla/animations.txt @@ -0,0 +1,64 @@ +// AnimationsDemo.ts +import { SimpleTableVanilla } from "simple-table-core"; +import type { Theme } from "simple-table-core"; +import { animationsConfig } from "./animations.demo-data"; +import "simple-table-core/styles.css"; + +export function renderAnimationsDemo( + container: HTMLElement, + options?: { height?: string | number; theme?: Theme } +): SimpleTableVanilla { + const table = new SimpleTableVanilla(container, { + defaultHeaders: animationsConfig.headers, + rows: animationsConfig.rows, + height: options?.height ?? "400px", + theme: options?.theme, + columnReordering: true, + editColumns: true, + editColumnsInitOpen: true, + }); + return table; +} + + +// animations.demo-data.ts +// Self-contained demo table setup for this example. +import type { HeaderObject } from "simple-table-core"; + + +export const animationsHeaders: HeaderObject[] = [ + { accessor: "id", label: "ID", width: 60, isSortable: true, type: "number" }, + { accessor: "name", label: "Name", minWidth: 140, width: "1fr", isSortable: true, type: "string" }, + { accessor: "age", label: "Age", width: 80, align: "right", isSortable: true, type: "number" }, + { accessor: "role", label: "Role", minWidth: 140, width: "1fr", isSortable: true, type: "string" }, + { + accessor: "department", + disableReorder: true, + isSortable: true, + label: "Department", + minWidth: 140, + width: "1fr", + type: "string", + }, +]; + +export const animationsData = [ + { id: 1, name: "Captain Stella Vega", age: 38, role: "Mission Commander", department: "Flight Operations" }, + { id: 2, name: "Dr. Cosmos Rivera", age: 34, role: "Astrophysicist", department: "Science" }, + { id: 3, name: "Commander Nebula Johnson", age: 42, role: "Operations Director", department: "Mission Control" }, + { id: 4, name: "Cadet Orbit Williams", age: 26, role: "Flight Engineer", department: "Engineering" }, + { id: 5, name: "Dr. Galaxy Chen", age: 31, role: "Life Support Specialist", department: "Engineering" }, + { id: 6, name: "Lt. Meteor Lee", age: 29, role: "Navigation Officer", department: "Flight Operations" }, + { id: 7, name: "Dr. Comet Hassan", age: 33, role: "Mission Planner", department: "Planning" }, + { id: 8, name: "Major Pulsar White", age: 36, role: "Communications Director", department: "Communications" }, + { id: 9, name: "Specialist Quasar Black", age: 28, role: "Systems Analyst", department: "Technology" }, + { id: 10, name: "Engineer Supernova Blue", age: 35, role: "Propulsion Engineer", department: "Engineering" }, + { id: 11, name: "Dr. Aurora Kumar", age: 30, role: "Planetary Geologist", department: "Science" }, + { id: 12, name: "Admiral Cosmos Silver", age: 45, role: "Program Director", department: "Leadership" }, +]; + +export const animationsConfig = { + headers: animationsHeaders, + rows: animationsData, + tableProps: { columnReordering: true, editColumns: true, editColumnsInitOpen: true }, +} as const; diff --git a/apps/marketing/public/txt-demos/vue/animations.txt b/apps/marketing/public/txt-demos/vue/animations.txt new file mode 100644 index 000000000..ab7f18c07 --- /dev/null +++ b/apps/marketing/public/txt-demos/vue/animations.txt @@ -0,0 +1,30 @@ + + + diff --git a/apps/marketing/sandbox-links.json b/apps/marketing/sandbox-links.json index aac49ab5b..bbbbc6f06 100644 --- a/apps/marketing/sandbox-links.json +++ b/apps/marketing/sandbox-links.json @@ -1,5 +1,34 @@ [ { - "name": "quick-start" + "name": "quick-start", + "frameworks": ["react", "vue", "angular", "svelte", "solid", "vanilla"] + }, + { + "name": "billing", + "frameworks": ["react", "vue", "angular", "svelte", "solid", "vanilla"] + }, + { + "name": "crm", + "frameworks": ["react", "vue", "angular", "svelte", "solid", "vanilla"] + }, + { + "name": "hr", + "frameworks": ["react", "vue", "angular", "svelte", "solid", "vanilla"] + }, + { + "name": "infrastructure", + "frameworks": ["react", "vue", "angular", "svelte", "solid", "vanilla"] + }, + { + "name": "manufacturing", + "frameworks": ["react", "vue", "angular", "svelte", "solid", "vanilla"] + }, + { + "name": "music", + "frameworks": ["react", "vue", "angular", "svelte", "solid", "vanilla"] + }, + { + "name": "sales", + "frameworks": ["react", "vue", "angular", "svelte", "solid", "vanilla"] } -] \ No newline at end of file +] diff --git a/apps/marketing/scripts/generate-hr-data.ts b/apps/marketing/scripts/generate-hr-data.ts index 15d417fd5..bdd0d1675 100644 --- a/apps/marketing/scripts/generate-hr-data.ts +++ b/apps/marketing/scripts/generate-hr-data.ts @@ -144,11 +144,10 @@ const generateHRData = (): Row[] => { ]; const statuses = ["Active", "On Leave", "Probation", "Contract", "Terminated"]; - let rowId = 0; const rows: Row[] = []; - // Generate a flat list of 10,000 employees - const totalEmployees = 10000; + // Generate a flat list of 1,000 employees + const totalEmployees = 1000; for (let i = 0; i < totalEmployees; i++) { const firstName = firstNames[Math.floor(Math.random() * firstNames.length)]; @@ -163,12 +162,12 @@ const generateHRData = (): Row[] => { position.includes("Senior") || position.includes("Lead") ? 1.5 : position.includes("Manager") || position.includes("Director") - ? 2 - : position.includes("Head") || position.includes("Executive") - ? 2.5 - : position.includes("Intern") - ? 0.5 - : 1; + ? 2 + : position.includes("Head") || position.includes("Executive") + ? 2.5 + : position.includes("Intern") + ? 0.5 + : 1; const salary = Math.floor(salaryBase * salaryMultiplier) * 1000; const status = statuses[Math.floor(Math.random() * statuses.length)]; @@ -184,7 +183,7 @@ const generateHRData = (): Row[] => { // Calculate years of service based on hire date const yearsOfService = Math.round( - ((new Date().getTime() - new Date(hireDate).getTime()) / (1000 * 60 * 60 * 24 * 365)) * 10 + ((new Date().getTime() - new Date(hireDate).getTime()) / (1000 * 60 * 60 * 24 * 365)) * 10, ) / 10; // Generate random email @@ -207,16 +206,16 @@ const generateHRData = (): Row[] => { department.includes("Engineering") ? "Engineer" : department.includes("Marketing") - ? "Marketer" - : department.includes("Sales") - ? "Representative" - : department.includes("Finance") - ? "Analyst" - : department.includes("HR") - ? "Specialist" - : department.includes("Operations") - ? "Manager" - : "Agent" + ? "Marketer" + : department.includes("Sales") + ? "Representative" + : department.includes("Finance") + ? "Analyst" + : department.includes("HR") + ? "Specialist" + : department.includes("Operations") + ? "Manager" + : "Agent" }`, email, hireDate, diff --git a/apps/marketing/scripts/generate-infrastructure-data.ts b/apps/marketing/scripts/generate-infrastructure-data.ts index 7726f8998..74467b65d 100644 --- a/apps/marketing/scripts/generate-infrastructure-data.ts +++ b/apps/marketing/scripts/generate-infrastructure-data.ts @@ -33,13 +33,10 @@ const SERVER_TYPES = [ { name: "ML Compute", baseCpu: 80, baseMemory: 75 }, ]; -// Server status options -const STATUS_OPTIONS = ["online", "warning", "critical", "maintenance", "offline"]; - // Generate realistic infrastructure monitoring data const generateInfrastructureData = (): Row[] => { const rows: Row[] = []; - const totalRows = 10000; + const totalRows = 200; for (let i = 0; i < totalRows; i++) { // Random datacenter @@ -54,13 +51,13 @@ const generateInfrastructureData = (): Row[] => { // CPU usage - based on server type with variation const cpuUsage = Math.min( 100, - Math.max(0, Math.round((serverType.baseCpu + (Math.random() - 0.5) * 40) * 10) / 10) + Math.max(0, Math.round((serverType.baseCpu + (Math.random() - 0.5) * 40) * 10) / 10), ); // Memory usage - based on server type with variation const memoryUsage = Math.min( 100, - Math.max(0, Math.round((serverType.baseMemory + (Math.random() - 0.5) * 30) * 10) / 10) + Math.max(0, Math.round((serverType.baseMemory + (Math.random() - 0.5) * 30) * 10) / 10), ); // Disk usage - random but realistic @@ -86,8 +83,8 @@ const generateInfrastructureData = (): Row[] => { status === "critical" ? Math.floor(Math.random() * 5) + 1 : status === "warning" - ? Math.floor(Math.random() * 3) - : 0; + ? Math.floor(Math.random() * 3) + : 0; // Last ping timestamp - recent const lastPing = new Date(Date.now() - Math.random() * 300000); // Within last 5 minutes diff --git a/apps/marketing/scripts/generate-manufacturing-data.ts b/apps/marketing/scripts/generate-manufacturing-data.ts index 56b386e77..05459ceb5 100644 --- a/apps/marketing/scripts/generate-manufacturing-data.ts +++ b/apps/marketing/scripts/generate-manufacturing-data.ts @@ -44,7 +44,7 @@ const generateManufacturingData = (): Row[] => { const rows: Row[] = []; // Generate data for hierarchical structure - 1,000 base rows with ~10 children each - const totalRows = 1000; + const totalRows = 200; const rowsPerProductLine = Math.ceil(totalRows / productLines.length); productLines.forEach((productLine, lineIndex) => { @@ -81,12 +81,12 @@ const generateManufacturingData = (): Row[] => { statusRandom < 0.7 ? "Running" : statusRandom < 0.8 - ? "Scheduled Maintenance" - : statusRandom < 0.9 - ? "Unplanned Downtime" - : statusRandom < 0.95 - ? "Idle" - : "Setup"; + ? "Scheduled Maintenance" + : statusRandom < 0.9 + ? "Unplanned Downtime" + : statusRandom < 0.95 + ? "Idle" + : "Setup"; stations.push({ id: stationId, diff --git a/apps/marketing/scripts/generate-search-index.cjs b/apps/marketing/scripts/generate-search-index.cjs index dc3b3b33b..6f2b66f5c 100644 --- a/apps/marketing/scripts/generate-search-index.cjs +++ b/apps/marketing/scripts/generate-search-index.cjs @@ -127,6 +127,7 @@ function getSectionName(docPath) { "/docs/cell-highlighting": "Cell Features", "/docs/cell-renderer": "Cell Features", "/docs/cell-clicking": "Cell Features", + "/docs/animations": "Cell Features", "/docs/header-renderer": "Advanced Features", "/docs/footer-renderer": "Advanced Features", "/docs/pagination": "Advanced Features", @@ -314,6 +315,13 @@ function getSEOMetadata(docId) { keywords: "simple-table, react-table, react-grid, data-grid, datagrid, data table, cell clicking, cell events, interactive table, cell interactions, typescript table, onclick handlers", }, + animations: { + title: "Animations in Simple Table React Grid", + description: + "Smooth animations on sort, column reorder, and column visibility changes in your react-table with Simple Table. GPU-accelerated, virtualization-aware, and respects prefers-reduced-motion. Customize duration and easing or disable entirely.", + keywords: + "simple-table, react-table, react-grid, data-grid, datagrid, data table, animations, table animations, sort animations, column reorder animations, prefers-reduced-motion, typescript table", + }, "header-renderer": { title: "Custom Header Renderers with Simple Table", description: diff --git a/apps/marketing/scripts/generate-sitemap.js b/apps/marketing/scripts/generate-sitemap.js deleted file mode 100644 index 9aaa118b0..000000000 --- a/apps/marketing/scripts/generate-sitemap.js +++ /dev/null @@ -1,170 +0,0 @@ -import { SitemapStream, streamToPromise } from "sitemap"; -import { createWriteStream } from "fs"; -import { fileURLToPath } from "url"; -import { dirname, resolve } from "path"; -import { glob } from "glob"; - -const __filename = fileURLToPath(import.meta.url); -const __dirname = dirname(__filename); - -const baseUrl = "https://www.simple-table.com"; - -// Static routes under src/app (including blog/*/page.tsx) are discovered automatically. -// Dynamic segments like [framework] are excluded here and merged in via frameworkHubRoutes. -async function getNextJsRoutes() { - const appDir = resolve(__dirname, "../src/app"); - const routes = await glob("**/page.{tsx,jsx,js,ts}", { cwd: appDir }); - - const frameworkHubRoutes = ["react", "vue", "angular", "svelte", "solid", "vanilla"].map( - (id) => `frameworks/${id}` - ); - - const processedRoutes = routes - .map((route) => { - // Convert file path to URL path - return route - .replace(/\/page\.[jt]sx?$/, "") // Remove page.tsx - .replace(/\/\([^)]+\)/g, "") // Remove route groups - .replace(/index$/, "") // Remove index from path - .replace(/^page\.tsx$/, ""); // Handle root page.tsx - }) - .filter((route) => { - // Filter out special Next.js routes, dynamic routes, and unwanted pages - return ( - !route.startsWith("_") && - !route.includes("api") && - !route.includes("[") && // Filter out dynamic routes - !route.includes("not-found") && // Filter out error pages - !route.includes("mobile-unsupported") // Filter out mobile unsupported page - ); - }) - .sort(); // Sort routes alphabetically - - // Always include the root route - if (!processedRoutes.includes("")) { - processedRoutes.unshift(""); // Add root route at the beginning - } - - const merged = [...new Set([...processedRoutes, ...frameworkHubRoutes])]; - return merged; -} - -// Function to format XML with proper indentation -function formatXML(xml) { - // Remove any existing XML declaration - const xmlWithoutDeclaration = xml.replace(/<\?xml[^>]*\?>\s*/, ""); - - const formatted = xmlWithoutDeclaration - .replace(//g, "\n ") - .replace(/<\/url>/g, "\n ") - .replace(//g, "\n ") - .replace(/<\/loc>/g, "") - .replace(//g, "\n ") - .replace(/<\/changefreq>/g, "") - .replace(//g, "\n ") - .replace(/<\/priority>/g, "") - .replace(//g, "\n ") - .replace(/<\/lastmod>/g, "") - .replace(//g, "\n"); - - // Add XML declaration at the start - return '\n' + formatted; -} - -async function generateSitemap() { - try { - const sitemap = new SitemapStream({ - hostname: baseUrl, - xmlns: { - news: true, - xhtml: true, - image: true, - video: true, - }, - }); - - // Get all routes - const nextJsRoutes = await getNextJsRoutes(); - - // Extract route categories for reporting - const blogRoutes = nextJsRoutes.filter((route) => route.startsWith("blog/")).sort(); - const examplesRoutes = nextJsRoutes.filter((route) => route.startsWith("examples/")).sort(); - const docsRoutes = nextJsRoutes.filter((route) => route.startsWith("docs/")).sort(); - - // Create and sort all sitemap entries to ensure consistent order - const sitemapEntries = []; - - // Add Next.js routes with appropriate priorities - nextJsRoutes.forEach((route) => { - const routeConfig = { - url: route || "/", // Handle root route - changefreq: "weekly", - priority: 0.6, - }; - - if (route === "") { - routeConfig.priority = 1.0; - routeConfig.changefreq = "daily"; - } else if (route.startsWith("blog/")) { - routeConfig.priority = 0.8; - routeConfig.changefreq = "monthly"; - } else if (route.startsWith("comparisons/")) { - routeConfig.priority = 0.9; - routeConfig.changefreq = "weekly"; - } else if (route.startsWith("case-studies/")) { - routeConfig.priority = 0.9; - routeConfig.changefreq = "monthly"; - } else if (route.startsWith("docs/")) { - routeConfig.priority = 0.8; - routeConfig.changefreq = "weekly"; - } else if (route === "frameworks" || route.startsWith("frameworks/")) { - routeConfig.priority = 0.75; - routeConfig.changefreq = "weekly"; - } else if (route.startsWith("examples/")) { - routeConfig.priority = 0.7; - routeConfig.changefreq = "weekly"; - } else if (route.startsWith("legal/")) { - routeConfig.priority = 0.5; - routeConfig.changefreq = "monthly"; - } - - sitemapEntries.push(routeConfig); - }); - - // Sort all entries by URL for consistent ordering - sitemapEntries.sort((a, b) => { - // Always put homepage first - if (a.url === "/" || a.url === "") return -1; - if (b.url === "/" || b.url === "") return 1; - - return a.url.localeCompare(b.url); - }); - - // Write sorted entries to sitemap - sitemapEntries.forEach((entry) => { - sitemap.write(entry); - }); - - sitemap.end(); - - // Generate the sitemap XML - const xml = await streamToPromise(sitemap); - const formattedXML = formatXML(xml.toString()); - - // Write the sitemap to the public directory - const outputPath = resolve(__dirname, "../public/sitemap.xml"); - createWriteStream(outputPath).write(formattedXML); - - console.log("✅ Sitemap generated successfully!"); - console.log(`📊 Found ${nextJsRoutes.length} total routes`); - console.log( - `📊 Blog posts: ${blogRoutes.length}, Examples: ${examplesRoutes.length}, Docs: ${docsRoutes.length}` - ); - } catch (error) { - console.error("❌ Error generating sitemap:", error); - process.exit(1); - } -} - -generateSitemap(); diff --git a/apps/marketing/src/app/blog/BlogSegmentChrome.tsx b/apps/marketing/src/app/blog/BlogSegmentChrome.tsx index 7a4cceb06..a7a83ba84 100644 --- a/apps/marketing/src/app/blog/BlogSegmentChrome.tsx +++ b/apps/marketing/src/app/blog/BlogSegmentChrome.tsx @@ -2,19 +2,66 @@ import { usePathname } from "next/navigation"; import OtherFrameworksCallout from "@/components/OtherFrameworksCallout"; -import { shouldShowOtherFrameworksCallout } from "@/constants/blogPosts"; +import { + getBlogPostBySlug, + getPostFrameworkId, + shouldShowOtherFrameworksCallout, +} from "@/constants/blogPosts"; +import { FRAMEWORK_HUB_PILLAR_BLOG_SLUG } from "@/constants/frameworkPillarBlogs"; +import { + buildBreadcrumbListJsonLd, + buildTechArticleJsonLd, +} from "@/utils/structuredData"; + +const PILLAR_SLUGS_WITH_OWN_JSONLD = new Set( + Object.entries(FRAMEWORK_HUB_PILLAR_BLOG_SLUG) + .filter(([id]) => id !== "react") + .map(([, slug]) => slug) +); export default function BlogSegmentChrome({ children }: { children: React.ReactNode }) { const pathname = usePathname(); const segment = pathname.replace(/^\/?blog\/?/, "").split("/")[0] ?? ""; const showCallout = shouldShowOtherFrameworksCallout(segment); + const frameworkId = getPostFrameworkId(segment); + + const post = segment ? getBlogPostBySlug(segment) : undefined; + const shouldEmitJsonLd = !!post && !PILLAR_SLUGS_WITH_OWN_JSONLD.has(segment); + const article = shouldEmitJsonLd + ? buildTechArticleJsonLd({ + title: post.title, + description: post.description, + canonicalPath: `/blog/${post.slug}`, + datePublished: post.createdAt, + dateModified: post.updatedAt, + }) + : null; + const breadcrumbs = shouldEmitJsonLd + ? buildBreadcrumbListJsonLd([ + { name: "Home", url: "/" }, + { name: "Blog", url: "/blog" }, + { name: post.title, url: `/blog/${post.slug}` }, + ]) + : null; return ( <> + {article ? ( + + + diff --git a/packages/examples/svelte/src/demos/animations/animations.demo-data.ts b/packages/examples/svelte/src/demos/animations/animations.demo-data.ts new file mode 100644 index 000000000..2e5957913 --- /dev/null +++ b/packages/examples/svelte/src/demos/animations/animations.demo-data.ts @@ -0,0 +1,40 @@ +// Self-contained demo table setup for this example. +import type { SvelteHeaderObject } from "@simple-table/svelte"; + + +export const animationsHeaders: SvelteHeaderObject[] = [ + { accessor: "id", label: "ID", width: 60, isSortable: true, type: "number" }, + { accessor: "name", label: "Name", minWidth: 140, width: "1fr", isSortable: true, type: "string" }, + { accessor: "age", label: "Age", width: 80, align: "right", isSortable: true, type: "number" }, + { accessor: "role", label: "Role", minWidth: 140, width: "1fr", isSortable: true, type: "string" }, + { + accessor: "department", + disableReorder: true, + isSortable: true, + label: "Department", + minWidth: 140, + width: "1fr", + type: "string", + }, +]; + +export const animationsData = [ + { id: 1, name: "Captain Stella Vega", age: 38, role: "Mission Commander", department: "Flight Operations" }, + { id: 2, name: "Dr. Cosmos Rivera", age: 34, role: "Astrophysicist", department: "Science" }, + { id: 3, name: "Commander Nebula Johnson", age: 42, role: "Operations Director", department: "Mission Control" }, + { id: 4, name: "Cadet Orbit Williams", age: 26, role: "Flight Engineer", department: "Engineering" }, + { id: 5, name: "Dr. Galaxy Chen", age: 31, role: "Life Support Specialist", department: "Engineering" }, + { id: 6, name: "Lt. Meteor Lee", age: 29, role: "Navigation Officer", department: "Flight Operations" }, + { id: 7, name: "Dr. Comet Hassan", age: 33, role: "Mission Planner", department: "Planning" }, + { id: 8, name: "Major Pulsar White", age: 36, role: "Communications Director", department: "Communications" }, + { id: 9, name: "Specialist Quasar Black", age: 28, role: "Systems Analyst", department: "Technology" }, + { id: 10, name: "Engineer Supernova Blue", age: 35, role: "Propulsion Engineer", department: "Engineering" }, + { id: 11, name: "Dr. Aurora Kumar", age: 30, role: "Planetary Geologist", department: "Science" }, + { id: 12, name: "Admiral Cosmos Silver", age: 45, role: "Program Director", department: "Leadership" }, +]; + +export const animationsConfig = { + headers: animationsHeaders, + rows: animationsData, + tableProps: { columnReordering: true, editColumns: true, editColumnsInitOpen: true }, +} as const; diff --git a/packages/examples/vanilla/README.md b/packages/examples/vanilla/README.md new file mode 100644 index 000000000..e19b5f325 --- /dev/null +++ b/packages/examples/vanilla/README.md @@ -0,0 +1,32 @@ +# Simple Table — Vanilla TypeScript examples + +Runnable vanilla TypeScript / web-component demos for [`simple-table-core`](https://www.npmjs.com/package/simple-table-core), the framework-agnostic data grid engine that powers all `@simple-table/*` adapters. No React, no Vue, no Angular runtime needed. + +## Run locally + +```bash +pnpm install +pnpm --filter examples-vanilla dev +``` + +## What's inside + +Real-world demos that showcase `simple-table-core` against zero framework runtime: + +- **Quick start**, **Sales**, **CRM**, **HR**, **Music**, **Manufacturing**, **Infrastructure**, **Billing** +- Feature focuses: virtualization for 1M+ rows, column pinning, resizing, reordering, visibility, nested headers, row grouping, inline cell editing, custom renderers via DOM, themes, pagination, infinite scroll + +## Use this in your project + +```bash +npm install simple-table-core +``` + +See the [Quick Start guide](https://www.simple-table.com/docs/quick-start) and the [Vanilla framework hub](https://www.simple-table.com/frameworks/vanilla) for up-to-date usage instructions. + +## Links + +- Vanilla framework hub: https://www.simple-table.com/frameworks/vanilla +- Vanilla pillar guide: https://www.simple-table.com/blog/vanilla-typescript-data-grid-simple-table-core +- Docs: https://www.simple-table.com/docs +- Other adapters: React, Vue, Angular, Svelte, Solid — see https://www.simple-table.com/frameworks diff --git a/packages/examples/vanilla/src/demos/animations/AnimationsDemo.ts b/packages/examples/vanilla/src/demos/animations/AnimationsDemo.ts new file mode 100644 index 000000000..886acabee --- /dev/null +++ b/packages/examples/vanilla/src/demos/animations/AnimationsDemo.ts @@ -0,0 +1,20 @@ +import { SimpleTableVanilla } from "simple-table-core"; +import type { Theme } from "simple-table-core"; +import { animationsConfig } from "./animations.demo-data"; +import "simple-table-core/styles.css"; + +export function renderAnimationsDemo( + container: HTMLElement, + options?: { height?: string | number; theme?: Theme } +): SimpleTableVanilla { + const table = new SimpleTableVanilla(container, { + defaultHeaders: animationsConfig.headers, + rows: animationsConfig.rows, + height: options?.height ?? "400px", + theme: options?.theme, + columnReordering: true, + editColumns: true, + editColumnsInitOpen: true, + }); + return table; +} diff --git a/packages/examples/vanilla/src/demos/animations/animations.demo-data.ts b/packages/examples/vanilla/src/demos/animations/animations.demo-data.ts new file mode 100644 index 000000000..24266c254 --- /dev/null +++ b/packages/examples/vanilla/src/demos/animations/animations.demo-data.ts @@ -0,0 +1,40 @@ +// Self-contained demo table setup for this example. +import type { HeaderObject } from "simple-table-core"; + + +export const animationsHeaders: HeaderObject[] = [ + { accessor: "id", label: "ID", width: 60, isSortable: true, type: "number" }, + { accessor: "name", label: "Name", minWidth: 140, width: "1fr", isSortable: true, type: "string" }, + { accessor: "age", label: "Age", width: 80, align: "right", isSortable: true, type: "number" }, + { accessor: "role", label: "Role", minWidth: 140, width: "1fr", isSortable: true, type: "string" }, + { + accessor: "department", + disableReorder: true, + isSortable: true, + label: "Department", + minWidth: 140, + width: "1fr", + type: "string", + }, +]; + +export const animationsData = [ + { id: 1, name: "Captain Stella Vega", age: 38, role: "Mission Commander", department: "Flight Operations" }, + { id: 2, name: "Dr. Cosmos Rivera", age: 34, role: "Astrophysicist", department: "Science" }, + { id: 3, name: "Commander Nebula Johnson", age: 42, role: "Operations Director", department: "Mission Control" }, + { id: 4, name: "Cadet Orbit Williams", age: 26, role: "Flight Engineer", department: "Engineering" }, + { id: 5, name: "Dr. Galaxy Chen", age: 31, role: "Life Support Specialist", department: "Engineering" }, + { id: 6, name: "Lt. Meteor Lee", age: 29, role: "Navigation Officer", department: "Flight Operations" }, + { id: 7, name: "Dr. Comet Hassan", age: 33, role: "Mission Planner", department: "Planning" }, + { id: 8, name: "Major Pulsar White", age: 36, role: "Communications Director", department: "Communications" }, + { id: 9, name: "Specialist Quasar Black", age: 28, role: "Systems Analyst", department: "Technology" }, + { id: 10, name: "Engineer Supernova Blue", age: 35, role: "Propulsion Engineer", department: "Engineering" }, + { id: 11, name: "Dr. Aurora Kumar", age: 30, role: "Planetary Geologist", department: "Science" }, + { id: 12, name: "Admiral Cosmos Silver", age: 45, role: "Program Director", department: "Leadership" }, +]; + +export const animationsConfig = { + headers: animationsHeaders, + rows: animationsData, + tableProps: { columnReordering: true, editColumns: true, editColumnsInitOpen: true }, +} as const; diff --git a/packages/examples/vue/README.md b/packages/examples/vue/README.md new file mode 100644 index 000000000..0bb29ccf8 --- /dev/null +++ b/packages/examples/vue/README.md @@ -0,0 +1,32 @@ +# Simple Table — Vue examples + +Runnable Vue 3 (Vite) demos for the [`@simple-table/vue`](https://www.npmjs.com/package/@simple-table/vue) data grid. Compatible with Nuxt 3/4 and any Vite-powered Vue app. These same demos power the live sandboxes on [simple-table.com](https://www.simple-table.com) and the one-click StackBlitz links from the docs. + +## Run locally + +```bash +pnpm install +pnpm --filter examples-vue dev +``` + +## What's inside + +Real-world demos that showcase Simple Table on Vue 3 with Composition API + ` diff --git a/packages/examples/vue/src/demos/animations/animations.demo-data.ts b/packages/examples/vue/src/demos/animations/animations.demo-data.ts new file mode 100644 index 000000000..871d6fc16 --- /dev/null +++ b/packages/examples/vue/src/demos/animations/animations.demo-data.ts @@ -0,0 +1,40 @@ +// Self-contained demo table setup for this example. +import type { VueHeaderObject } from "@simple-table/vue"; + + +export const animationsHeaders: VueHeaderObject[] = [ + { accessor: "id", label: "ID", width: 60, isSortable: true, type: "number" }, + { accessor: "name", label: "Name", minWidth: 140, width: "1fr", isSortable: true, type: "string" }, + { accessor: "age", label: "Age", width: 80, align: "right", isSortable: true, type: "number" }, + { accessor: "role", label: "Role", minWidth: 140, width: "1fr", isSortable: true, type: "string" }, + { + accessor: "department", + disableReorder: true, + isSortable: true, + label: "Department", + minWidth: 140, + width: "1fr", + type: "string", + }, +]; + +export const animationsData = [ + { id: 1, name: "Captain Stella Vega", age: 38, role: "Mission Commander", department: "Flight Operations" }, + { id: 2, name: "Dr. Cosmos Rivera", age: 34, role: "Astrophysicist", department: "Science" }, + { id: 3, name: "Commander Nebula Johnson", age: 42, role: "Operations Director", department: "Mission Control" }, + { id: 4, name: "Cadet Orbit Williams", age: 26, role: "Flight Engineer", department: "Engineering" }, + { id: 5, name: "Dr. Galaxy Chen", age: 31, role: "Life Support Specialist", department: "Engineering" }, + { id: 6, name: "Lt. Meteor Lee", age: 29, role: "Navigation Officer", department: "Flight Operations" }, + { id: 7, name: "Dr. Comet Hassan", age: 33, role: "Mission Planner", department: "Planning" }, + { id: 8, name: "Major Pulsar White", age: 36, role: "Communications Director", department: "Communications" }, + { id: 9, name: "Specialist Quasar Black", age: 28, role: "Systems Analyst", department: "Technology" }, + { id: 10, name: "Engineer Supernova Blue", age: 35, role: "Propulsion Engineer", department: "Engineering" }, + { id: 11, name: "Dr. Aurora Kumar", age: 30, role: "Planetary Geologist", department: "Science" }, + { id: 12, name: "Admiral Cosmos Silver", age: 45, role: "Program Director", department: "Leadership" }, +]; + +export const animationsConfig = { + headers: animationsHeaders, + rows: animationsData, + tableProps: { columnReordering: true, editColumns: true, editColumnsInitOpen: true }, +} as const; diff --git a/packages/react/README.md b/packages/react/README.md index e11c04d00..87da07e14 100644 --- a/packages/react/README.md +++ b/packages/react/README.md @@ -30,13 +30,14 @@ Simple Table is available for the most popular frameworks: npm install @simple-table/react ``` -**Peer dependencies:** `react >=18.0.0`, `react-dom >=18.0.0` +**Peer dependencies:** `react >=18.0.0`, `react-dom >=18.0.0` (works with React 19, Next.js, Remix, and Vite) **[Follow our Quick Start Guide](https://www.simple-table.com/docs/quick-start)** for step-by-step instructions and live examples. ## Building with React - Use React components for cell renderers, header renderers, footer renderers, and more +- Works with React 18+, React 19, Next.js (Pages and App Router), Remix, and Vite - Access the full imperative `TableAPI` via a ref for sorting, filtering, pagination, export, and more - Types and APIs are exported from this package diff --git a/packages/react/package.json b/packages/react/package.json index 82fc253e2..47462462f 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,6 +1,6 @@ { "name": "@simple-table/react", - "version": "3.0.13", + "version": "3.2.0", "main": "dist/cjs/index.js", "module": "dist/index.es.js", "types": "dist/types/react/src/index.d.ts", @@ -66,10 +66,35 @@ "simple-table", "simple-table-react", "react", + "react 18", + "react 19", "datagrid", "data-grid", "data table", "react-table", - "react data grid" + "react table", + "react data grid", + "react datatable", + "react data table", + "react grid", + "react virtualized table", + "react tree table", + "react editable grid", + "react spreadsheet", + "next.js table", + "next.js data grid", + "remix table", + "react server components grid", + "ag-grid alternative", + "ag-grid react alternative", + "tanstack table alternative", + "material react table alternative", + "mui datagrid alternative", + "handsontable alternative", + "kendo react grid alternative", + "react-data-grid alternative", + "free react data grid", + "mit react data grid", + "typescript data grid" ] } diff --git a/packages/solid/README.md b/packages/solid/README.md index 7bc27ccc1..54478e790 100644 --- a/packages/solid/README.md +++ b/packages/solid/README.md @@ -30,15 +30,16 @@ Simple Table is available for the most popular frameworks: npm install @simple-table/solid ``` -**Peer dependencies:** `solid-js >=1.0.0` +**Peer dependencies:** `solid-js >=1.0.0` (works with Solid Start and any Vite-based Solid app) **[Follow our Quick Start Guide](https://www.simple-table.com/docs/quick-start)** for step-by-step instructions and live examples. ## Building with Solid +- Signals-friendly API; updates flow through Solid's fine-grained reactivity - Use Solid components for cell renderers, header renderers, footer renderers, and more - Access the imperative `TableAPI` via a ref callback for sorting, filtering, pagination, export, and more -- Types and APIs are exported from this package +- Types and APIs are exported from this package; works with Solid Start, Vite, and TypeScript strict mode ## Features diff --git a/packages/solid/package.json b/packages/solid/package.json index 9a838e93c..e4c14d0a9 100644 --- a/packages/solid/package.json +++ b/packages/solid/package.json @@ -1,6 +1,6 @@ { "name": "@simple-table/solid", - "version": "3.0.13", + "version": "3.2.0", "main": "dist/cjs/index.js", "module": "dist/index.es.js", "types": "dist/types/solid/src/index.d.ts", @@ -65,9 +65,32 @@ "simple-table-solid", "solid", "solidjs", + "solid-js", + "solid-start", + "solidstart", + "signals", + "fine-grained reactivity", "datagrid", "data-grid", "data table", - "solid data grid" + "solid table", + "solid data grid", + "solid datagrid", + "solid datatable", + "solid data table", + "solid grid", + "solid spreadsheet", + "solid virtualized table", + "solid tree table", + "solid editable grid", + "solidjs table", + "solidjs data grid", + "solidjs datatable", + "tanstack solid table alternative", + "kobalte alternative", + "ag-grid alternative", + "free solid data grid", + "mit solid data grid", + "typescript data grid" ] } diff --git a/packages/svelte/README.md b/packages/svelte/README.md index 2e6aac69e..11411d90f 100644 --- a/packages/svelte/README.md +++ b/packages/svelte/README.md @@ -30,12 +30,13 @@ Simple Table is available for the most popular frameworks: npm install @simple-table/svelte ``` -**Peer dependencies:** `svelte >=4.0.0` +**Peer dependencies:** `svelte >=4.0.0` (Svelte 5 with runes is fully supported, plus SvelteKit) **[Follow our Quick Start Guide](https://www.simple-table.com/docs/quick-start)** for step-by-step instructions and live examples. ## Building with Svelte +- Works with Svelte 4 and Svelte 5 (runes); SvelteKit is fully supported - Use Svelte components for cell renderers, header renderers, footer renderers, and more - Access the imperative `TableAPI` via `bind:this` for sorting, filtering, pagination, export, and more - Types and APIs are exported from this package diff --git a/packages/svelte/package.json b/packages/svelte/package.json index 30a30261b..41a6ef6d4 100644 --- a/packages/svelte/package.json +++ b/packages/svelte/package.json @@ -1,6 +1,6 @@ { "name": "@simple-table/svelte", - "version": "3.0.13", + "version": "3.2.0", "main": "dist/cjs/index.js", "module": "dist/index.es.js", "types": "dist/types/index.d.ts", @@ -63,10 +63,34 @@ "simple-table", "simple-table-svelte", "svelte", + "svelte4", "svelte5", + "svelte 5", + "sveltekit", + "runes", "datagrid", "data-grid", "data table", - "svelte data grid" + "svelte table", + "svelte data grid", + "svelte datagrid", + "svelte datatable", + "svelte data table", + "svelte grid", + "svelte spreadsheet", + "svelte virtualized table", + "svelte tree table", + "svelte editable grid", + "sveltekit table", + "sveltekit data grid", + "sveltekit data table", + "svelte-headless-table alternative", + "svar datagrid alternative", + "flowbite svelte table alternative", + "carbon svelte table alternative", + "ag-grid alternative", + "free svelte data grid", + "mit svelte data grid", + "typescript data grid" ] } diff --git a/packages/vue/README.md b/packages/vue/README.md index 6859dc755..9e3887f09 100644 --- a/packages/vue/README.md +++ b/packages/vue/README.md @@ -30,15 +30,16 @@ Simple Table is available for the most popular frameworks: npm install @simple-table/vue ``` -**Peer dependencies:** `vue >=3.0.0` +**Peer dependencies:** `vue >=3.0.0` (works with Nuxt 3+ and Vite-based Vue apps) **[Follow our Quick Start Guide](https://www.simple-table.com/docs/quick-start)** for step-by-step instructions and live examples. ## Building with Vue +- First-class `