{"_id":"@ascentsparksoftware/react-datatables-net","_rev":"2-2086615c6997ea2e2c3bcc6347e871c0","name":"@ascentsparksoftware/react-datatables-net","dist-tags":{"latest":"1.1.0"},"versions":{"1.0.0":{"name":"@ascentsparksoftware/react-datatables-net","version":"1.0.0","keywords":["react","react-datatables","datatables","datatables.net","datatables-react","table","react-table","grid","data-grid","react-data-grid","datagrid","react-grid","editable","inline-edit","edit-in-place","cell-editor","nextjs","react-19"],"author":{"name":"Ascentspark"},"license":"MIT","_id":"@ascentsparksoftware/react-datatables-net@1.0.0","maintainers":[{"name":"coderkane","email":"partha@ascentspark.com"}],"homepage":"https://github.com/ascentspark/react-datatables","bugs":{"url":"https://github.com/ascentspark/react-datatables/issues"},"dist":{"shasum":"56aa6704516844b789801e3dfd7456f68af2159d","tarball":"https://registry.npmjs.org/@ascentsparksoftware/react-datatables-net/-/react-datatables-net-1.0.0.tgz","fileCount":37,"integrity":"sha512-nkWObpcfT/BoyZCvyCuHwavbr3GrQcdUNUm4HTCKSmIPyYH3rzFkt1xE/8pD7XRVr2w4m22EEocTjcGW5TG4ww==","signatures":[{"sig":"MEUCIEO+/OEnPhs3PtZLFp0/osl+syHXYYx29IxtzuRZZWenAiEA/PnjcvMvVuwua6mfQUNQg+z8ui6RwE0R1DE53Lz2Uog=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":326787},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./dt":{"types":"./dist/dt/index.d.ts","import":"./dist/dt/index.js","require":"./dist/dt/index.cjs"},"./bs5":{"types":"./dist/bs5/index.d.ts","import":"./dist/bs5/index.js","require":"./dist/bs5/index.cjs"},"./material":{"types":"./dist/material/index.d.ts","import":"./dist/material/index.js","require":"./dist/material/index.cjs"},"./tailwind":{"types":"./dist/tailwind/index.d.ts","import":"./dist/tailwind/index.js","require":"./dist/tailwind/index.cjs"},"./package.json":"./package.json","./material/styles/react-datatables-net.material.css":"./dist/material/styles/react-datatables-net.material.css","./tailwind/styles/react-datatables-net.tailwind.css":"./dist/tailwind/styles/react-datatables-net.tailwind.css"},"gitHead":"5c7407629f4c29dccfad5cfee72d5a28647449cf","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup && npm run build:css","prepack":"cp ../README.md README.md && cp ../LICENSE LICENSE","build:css":"mkdir -p dist/tailwind/styles dist/material/styles && cp tailwind/styles/react-datatables-net.tailwind.css dist/tailwind/styles/ && cp material/styles/react-datatables-net.material.css dist/material/styles/","typecheck":"tsc --noEmit"},"_npmUser":{"name":"coderkane","email":"partha@ascentspark.com"},"repository":{"url":"git+https://github.com/ascentspark/react-datatables.git","type":"git"},"_npmVersion":"11.12.1","description":"Modern React wrapper for DataTables (datatables.net) using its non-jQuery API. Typed cells, free edit-in-place, styling adapters. Next.js and React Compiler friendly.","directories":{},"sideEffects":["./dist/dt/*","./dist/bs5/*","*.css"],"_nodeVersion":"24.15.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.0","jsdom":"^26.1.0","react":"^19.2.0","vitest":"^3.2.4","react-dom":"^19.2.0","typescript":"~5.9.2","@types/node":"^26.0.1","@types/react":"^19.1.0","@types/jquery":"^4.0.1","datatables.net":"^2.3.8","@types/react-dom":"^19.1.0","datatables.net-dt":"^2.3.8","datatables.net-bs5":"^2.3.8","@testing-library/dom":"^10.4.0","@testing-library/react":"^16.3.0"},"peerDependencies":{"react":"^19.0.0","react-dom":"^19.0.0","datatables.net":"^2.1.0","datatables.net-dt":"^2.1.0","datatables.net-bs5":"^2.1.0"},"peerDependenciesMeta":{"datatables.net-dt":{"optional":true},"datatables.net-bs5":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/react-datatables-net_1.0.0_1783594614320_0.8725904766482584","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@ascentsparksoftware/react-datatables-net","version":"1.1.0","description":"Modern React wrapper for DataTables (datatables.net) using its non-jQuery API. Typed cells, free edit-in-place, styling adapters. Next.js and React Compiler friendly.","author":{"name":"Ascentspark"},"license":"MIT","homepage":"https://github.com/ascentspark/react-datatables","bugs":{"url":"https://github.com/ascentspark/react-datatables/issues"},"repository":{"type":"git","url":"git+https://github.com/ascentspark/react-datatables.git"},"keywords":["react","react-datatables","datatables","datatables.net","datatables-react","table","react-table","grid","data-grid","react-data-grid","datagrid","react-grid","editable","inline-edit","edit-in-place","cell-editor","nextjs","react-19"],"type":"module","main":"./dist/index.cjs","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./dt":{"types":"./dist/dt/index.d.ts","import":"./dist/dt/index.js","require":"./dist/dt/index.cjs"},"./bs5":{"types":"./dist/bs5/index.d.ts","import":"./dist/bs5/index.js","require":"./dist/bs5/index.cjs"},"./tailwind":{"types":"./dist/tailwind/index.d.ts","import":"./dist/tailwind/index.js","require":"./dist/tailwind/index.cjs"},"./material":{"types":"./dist/material/index.d.ts","import":"./dist/material/index.js","require":"./dist/material/index.cjs"},"./tailwind/styles/react-datatables-net.tailwind.css":"./dist/tailwind/styles/react-datatables-net.tailwind.css","./material/styles/react-datatables-net.material.css":"./dist/material/styles/react-datatables-net.material.css","./package.json":"./package.json"},"sideEffects":["./dist/dt/*","./dist/bs5/*","*.css"],"scripts":{"prepack":"cp ../README.md README.md && cp ../LICENSE LICENSE","build":"tsup && npm run build:css","build:css":"mkdir -p dist/tailwind/styles dist/material/styles && cp tailwind/styles/react-datatables-net.tailwind.css dist/tailwind/styles/ && cp material/styles/react-datatables-net.material.css dist/material/styles/","dev":"tsup --watch","test":"vitest run","typecheck":"tsc --noEmit"},"peerDependencies":{"datatables.net":"^2.1.0","datatables.net-bs5":"^2.1.0","datatables.net-dt":"^2.1.0","react":"^19.0.0","react-dom":"^19.0.0"},"peerDependenciesMeta":{"datatables.net-dt":{"optional":true},"datatables.net-bs5":{"optional":true}},"devDependencies":{"@testing-library/dom":"^10.4.0","@testing-library/react":"^16.3.0","@types/jquery":"^4.0.1","@types/node":"^26.0.1","@types/react":"^19.1.0","@types/react-dom":"^19.1.0","datatables.net":"^2.3.8","datatables.net-bs5":"^2.3.8","datatables.net-dt":"^2.3.8","jsdom":"^26.1.0","react":"^19.2.0","react-dom":"^19.2.0","tsup":"^8.5.0","typescript":"~5.9.2","vitest":"^3.2.4"},"publishConfig":{"access":"public"},"gitHead":"7c0a3c9b1bec7aa60ef1277a889d655f37315671","_id":"@ascentsparksoftware/react-datatables-net@1.1.0","_nodeVersion":"24.15.0","_npmVersion":"11.12.1","dist":{"integrity":"sha512-Xa6dZa/KGQpmEWA4T5KdLdfWTi5TC1J+sRJy74WtXcl2r9vjlrM99Sy6JX3bPN+j7jNrzoRWN05hpHJJ4q/54g==","shasum":"4c8e5664ffb4bbf354681596a172115370ec3110","tarball":"https://registry.npmjs.org/@ascentsparksoftware/react-datatables-net/-/react-datatables-net-1.1.0.tgz","fileCount":37,"unpackedSize":343626,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDMMWzkrr+Gt+jfmkvyJs9hgAHySVH4F8t/As+R/3OwkgIgf97hpoRKriAC6+A3p1VY3k2eisxsDC/3SWb95qLi7rI="}]},"_npmUser":{"name":"coderkane","email":"partha@ascentspark.com"},"directories":{},"maintainers":[{"name":"coderkane","email":"partha@ascentspark.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/react-datatables-net_1.1.0_1783599895177_0.2717454334847005"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-09T10:56:54.055Z","modified":"2026-07-09T12:24:55.443Z","1.0.0":"2026-07-09T10:56:54.467Z","1.1.0":"2026-07-09T12:24:55.336Z"},"bugs":{"url":"https://github.com/ascentspark/react-datatables/issues"},"author":{"name":"Ascentspark"},"license":"MIT","homepage":"https://github.com/ascentspark/react-datatables","keywords":["react","react-datatables","datatables","datatables.net","datatables-react","table","react-table","grid","data-grid","react-data-grid","datagrid","react-grid","editable","inline-edit","edit-in-place","cell-editor","nextjs","react-19"],"repository":{"type":"git","url":"git+https://github.com/ascentspark/react-datatables.git"},"description":"Modern React wrapper for DataTables (datatables.net) using its non-jQuery API. Typed cells, free edit-in-place, styling adapters. Next.js and React Compiler friendly.","maintainers":[{"name":"coderkane","email":"partha@ascentspark.com"}],"readme":"<div align=\"center\">\n\n# @ascentsparksoftware/react-datatables-net\n\nA React wrapper for [DataTables.net](https://datatables.net), by\n<a href=\"https://ascentspark.com\" target=\"_blank\" rel=\"noopener\">Ascentspark</a>\n\n<a href=\"https://ascentspark.com\" target=\"_blank\" rel=\"noopener\"><img src=\"https://cdn.ascentspark.com/assets/images/asc-logo-full.svg\" alt=\"Ascentspark\" height=\"40\"></a>\n\n### Typed React components for DataTables.net — no jQuery in your code\n\n[![npm version](https://img.shields.io/npm/v/react-datatables-net.svg?color=61dafb)](https://www.npmjs.com/package/react-datatables-net)\n[![downloads](https://img.shields.io/npm/dm/react-datatables-net.svg)](https://www.npmjs.com/package/react-datatables-net)\n[![React 19](https://img.shields.io/badge/React-19-61dafb.svg)](https://react.dev)\n[![license MIT](https://img.shields.io/npm/l/react-datatables-net.svg?color=3b82f6)](LICENSE)\n\n**[🚀 Live demo](https://react-datatables-net.ascentspark.com)** &nbsp;·&nbsp;\n**[✏️ Edit in place](docs/EDIT-IN-PLACE.md)** &nbsp;·&nbsp;\n**[📦 npm](https://www.npmjs.com/package/react-datatables-net)** &nbsp;·&nbsp;\n**[📝 Changelog](CHANGELOG.md)**\n\n</div>\n\n---\n\n[DataTables](https://datatables.net) turns a plain HTML table into an interactive one: sorting,\nsearch, pagination, and a large set of extensions. **`@ascentsparksoftware/react-datatables-net`** lets you drive it from\nReact without writing any jQuery. Render a `<DataTable>` component, pass your options and data as\nprops, and read events back as typed callbacks. Client-only by design, StrictMode-safe, React\nCompiler-safe, Next.js friendly, and escaped by default. It is the React sibling of our Angular\nwrapper, [`ngx-datatables-net`](https://github.com/ascentspark/ngx-datatables-net), and shares its\ndesign contracts.\n\n> **⚛️ Built the modern React way.** Function components, portals for live React cell content, and\n> DataTables' **non-jQuery** constructor API. Your only peer dependencies are React and DataTables:\n> no `jquery` required of your app. The engine is loaded lazily inside an effect, so jQuery and\n> DataTables stay out of your initial bundle and out of the Next.js server graph. (DataTables uses\n> jQuery internally, so it still ships as a transitive dependency, but you never write or configure\n> it.)\n\n> ## 🆓 Built-in inline editing, an alternative to the paid version\n>\n> DataTables' own inline editing ships only in **[Editor](https://editor.datatables.net/), a\n> commercial paid extension**. This package gives you **double-click edit-in-place for free** (MIT):\n> text, textarea, number, date, checkbox, select, multiselect and **custom React component**\n> editors, with validation, keyboard navigation and optional pessimistic async saving, all through\n> the non-jQuery API and written the React way.\n>\n> **→ [Try the live demo](https://react-datatables-net.ascentspark.com/edit-in-place)** &nbsp;·&nbsp;\n> **[Read the guide](docs/EDIT-IN-PLACE.md)**\n\n## ✨ Why @ascentsparksoftware/react-datatables-net\n\n- **No jQuery in your code.** Built on the DataTables non-jQuery API; jQuery stays a transitive\n  dependency you never touch.\n- **Client-only with lazy engine loading.** The DataTables constructor is dynamically imported\n  inside an effect, so importing the module on the server (Next.js does, even for never-rendered\n  components) touches no DOM, and jQuery + the engine stay out of the initial bundle and the server\n  graph.\n- **Props in, callbacks out.** Pass a new `data` array and the table reconciles itself via the\n  cheap `clear → rows.add → draw` path — no manual redraw trigger to remember. Events come back as\n  typed callback props; the underlying `Api` is one `ref` away.\n- **Live React cell content.** A column's `cell` render prop renders real React — hooks, context\n  and event handlers all work — while sorting and search keep operating on the raw data.\n- **Free edit-in-place.** Inline editing without the commercial Editor licence (see the callout\n  above).\n- **StrictMode-safe and React Compiler-safe.** Init is idempotent, cleanup is complete, and nothing\n  mutated is read during render — the dev double-mount never leaks an instance or a listener.\n- **Safe by default.** `escapeByDefault` escapes every column without an explicit renderer;\n  `unsafeHtmlRenderer()` is the explicit, named escape hatch for trusted HTML.\n- **Every extension works.** Buttons, Select, Responsive, FixedHeader/Columns, Scroller, RowGroup,\n  SearchPanes, ColumnControl and more: pass the config straight through.\n- **Four styling adapters.** DataTables default, Bootstrap 5, plus Tailwind and Material themes\n  authored by us (DataTables ships neither).\n\n## 📦 Install\n\n```bash\nnpm install @ascentsparksoftware/react-datatables-net datatables.net datatables.net-dt\n```\n\nAdd the stylesheet for your chosen theme once, e.g. in `app/layout.tsx` (Next.js) or `main.tsx`\n(Vite):\n\n```ts\nimport 'datatables.net-dt/css/dataTables.dataTables.css';\n```\n\n## 🚀 Quick start\n\nConfigure the provider once, near the root of your app:\n\n```tsx\n// providers.tsx\nimport { DataTablesProvider } from '@ascentsparksoftware/react-datatables-net';\nimport { defaultStyling } from '@ascentsparksoftware/react-datatables-net/dt';\n\n<DataTablesProvider styling={defaultStyling} escapeByDefault options={{ pageLength: 10 }}>\n  <App />\n</DataTablesProvider>\n```\n\nThen render a table:\n\n```tsx\n'use client';\n\nimport { useState } from 'react';\nimport { DataTable, type Api, type ConfigColumns } from '@ascentsparksoftware/react-datatables-net';\n\ninterface Employee {\n  id: number;\n  name: string;\n  position: string;\n  office: string;\n}\n\nconst columns: ConfigColumns[] = [\n  { data: 'id', title: 'ID' },\n  { data: 'name', title: 'Name' },\n  { data: 'position', title: 'Position' },\n  { data: 'office', title: 'Office' },\n];\n\nexport default function EmployeesPage() {\n  const [data] = useState<Employee[]>([\n    { id: 1, name: 'Ada Lovelace', position: 'Engineer', office: 'London' },\n    { id: 2, name: 'Linus Torvalds', position: 'Maintainer', office: 'Portland' },\n  ]);\n\n  return (\n    <DataTable<Employee>\n      className=\"display\"\n      style={{ width: '100%' }}\n      data={data}\n      columns={columns}\n      onInit={(api: Api<Employee>) => {\n        // escape hatch: the full DataTables Api for imperative calls\n      }}\n      onRowClick={({ row }) => {\n        // row is the typed Employee that was clicked\n      }}\n    >\n      <thead>\n        <tr>\n          <th>ID</th>\n          <th>Name</th>\n          <th>Position</th>\n          <th>Office</th>\n        </tr>\n      </thead>\n    </DataTable>\n  );\n}\n```\n\nTo reload the table later, set a new array into state and pass it as `data`. That is the whole loop.\n\n## ✏️ Edit in place (free, no Editor licence)\n\nGive a column an `editor`. Double-click to edit; Enter commits, Escape cancels, Tab moves to the\nnext editable cell.\n\n```tsx\nimport { DataTable, type DtColumn } from '@ascentsparksoftware/react-datatables-net';\n\nconst columns: DtColumn<User>[] = [\n  { data: 'name',   title: 'Name',   editor: { type: 'text', validate: v => String(v).trim() ? null : 'Required' } },\n  { data: 'role',   title: 'Role',   editor: { type: 'select', options: ROLES } },\n  { data: 'skills', title: 'Skills', editor: { type: 'multiselect', options: SKILLS } },\n];\n\n<DataTable<User> data={users} columns={columns} save={saveHandler} />\n```\n\nEditors: `text`, `textarea`, `number`, `date`, `checkbox`, `select`, `multiselect`, `custom`\n(your own React component). Pass a `save` handler to persist before the cell is written (sync or\n`Promise`). The cell shows a busy state and, on failure, stays open with an inline error for retry.\nFull details in the **[Edit in place guide](docs/EDIT-IN-PLACE.md)**.\n\n## 🧩 `<DataTable>` props\n\nAll props are optional. `T` is the row type (`<DataTable<Employee> …>`).\n\n| Prop | Type | Description |\n| --- | --- | --- |\n| `options` | `Config` | DataTables options object. A *structural* change (new keys/values, not a new inline literal that serializes identically) recreates the table. Merged over the provider's default `options`. |\n| `data` | `readonly T[]` | Row data. A new array reference replaces the rows without re-initializing (`clear → rows.add → draw(false)`, keeping the paging position). |\n| `columns` | `DtColumn<T>[]` | Column definitions (convenience for `options.columns`). Columns may carry a `cell` render prop and/or an `editor` (see the table below). Structural change recreates the table. |\n| `escapeByDefault` | `boolean` | Override the provider's `escapeByDefault` for this table (see [Security](docs/SECURITY.md)). |\n| `styling` | `DtStyling` | Override the provider's styling adapter for this table. |\n| `className` | `string` | Class applied to the `<table>` element (e.g. `display` for the default theme). |\n| `style` | `CSSProperties` | Inline style for the `<table>` element. |\n| `id` | `string` | `id` for the `<table>` element. |\n| `children` | `ReactNode` | Table markup: `<thead>` (and optionally `<tfoot>` / a DOM-sourced `<tbody>`). |\n| `ref` | `Ref<DataTableRef<T>>` | Imperative access to the DataTables `Api` (`ref.current.api`, `null` until initialized). |\n| `onInit` | `(api: Api<T>) => void` | Called once with the `Api` immediately after the table is created. |\n| `onDraw` | `(event: DtEvent<T>) => void` | DataTables `draw` event. `event.page` carries an `api.page.info()` snapshot. |\n| `onPage` | `(event: DtEvent<T>) => void` | DataTables `page` event. `event.page` carries an `api.page.info()` snapshot. |\n| `onXhr` | `(event: DtEvent<T>) => void` | DataTables `xhr` event (Ajax/server-side data load). |\n| `onSelect` | `(event: DtSelectEvent<T>) => void` | Select extension `select` event. |\n| `onDeselect` | `(event: DtSelectEvent<T>) => void` | Select extension `deselect` event. |\n| `onSelectionChange` | `(selected: readonly T[]) => void` | Current selection (row data) after every select/deselect. Requires the Select extension. |\n| `onRowClick` | `(event: DtRowClickEvent<T>) => void` | Row click (delegated listener on `<tbody>`), with resolved row data, index, `<tr>` element and the mouse event. |\n| `save` | `DtCellSaveHandler<T>` | Optional pessimistic save handler for edit-in-place. Runs on commit **before** the cell is written; return a `Promise` to defer the write, reject/throw to keep the cell unchanged and leave the editor open for retry. |\n| `onCellEditStart` | `(ctx: DtEditContext<T>) => void` | Emitted when an edit begins (editor opened). |\n| `onCellEdit` | `(commit: DtCellEditCommit<T>) => void` | Emitted after a changed value is validated, saved and written to the cell. |\n| `onCellEditCancel` | `(evt: DtCellEditCancel<T>) => void` | Emitted when an edit is abandoned (Escape, blur with no change, programmatic close, …). |\n| `onCellEditError` | `(evt: DtCellEditError<T>) => void` | Emitted when a save handler fails; the cell is left unchanged. |\n\nInline callback props are safe: the component reads the latest callbacks from a ref, so a new inline\nfunction never forces a re-initialization. The same applies to a column's `cell` render prop and\n`editor` callbacks — swapping the function (same column structure) takes effect on the next draw\nwithout recreating the table. The `styling` prop is compared by a structural signature too, so an\ninline `withTailwind({...})` per render does not recreate the table.\n\n> **Server-side tip:** a `data: null` action column should either carry a `cell` render prop (the\n> component's display shim supplies the cell content) or set DataTables' `defaultContent` —\n> otherwise DataTables warns about the missing data source in `serverSide` mode.\n\n### `DtColumn<T>` extras\n\n`DtColumn<T>` is DataTables' own `ConfigColumns` plus two fields:\n\n| Field | Type | Description |\n| --- | --- | --- |\n| `cell` | `(ctx: DtCellContext<T>) => ReactNode` | React render prop for the cell's display content. Renders as live React (portals from the component's own tree, so hooks, context and event handlers work), re-rendered across draws. Sorting/filtering still use the raw `data`. Context: `{ cellData, row, rowIndex, colIndex }`. |\n| `editor` | `DtEditorConfig<T>` | Edit-in-place configuration; omit for a read-only column. |\n\n### Typed `Api` helpers\n\n| Helper | Signature | Description |\n| --- | --- | --- |\n| `ajaxParams` | `(api: Api<T>) => AjaxData \\| undefined` | Typed accessor for `api.ajax.params()` (upstream types it as a bare `object`): the last Ajax/server-side request parameters, or `undefined` when the table has no Ajax source. |\n| `pageInfo` | `(api: Api<T>) => ApiPageInfo` | Typed convenience for `api.page.info()`. |\n\n### Editor kinds\n\n| `editor.type` | Control | Committed value |\n| --- | --- | --- |\n| `text` | `<input type=\"text\">` | `string` |\n| `textarea` | `<textarea>` | `string` (commit with Ctrl/⌘+Enter, or blur) |\n| `number` | `<input type=\"number\">` | `number`, or `null` when blank |\n| `date` | `<input type=\"date\">` | ISO `yyyy-mm-dd` string, or `null` when blank |\n| `checkbox` | checkbox | `boolean` |\n| `select` | `<select>` | the chosen option's `value` |\n| `multiselect` | `<select multiple>` | an **array** of the chosen option values |\n| `custom` | your React component | whatever your component passes to `commit()` |\n\nAll editors share the optional `ariaLabel`, `disabled: (ctx) => boolean` and\n`validate: (value, row) => string \\| null \\| undefined` fields. See the\n**[Edit in place guide](docs/EDIT-IN-PLACE.md)** for everything.\n\n## 🎨 Styling adapters\n\nPick one adapter and pass it to `DataTablesProvider` (or per table via the `styling` prop). Each\nadapter lazily imports its DataTables constructor, so nothing touches the DOM at module import time.\n\n**DataTables default theme** — `@ascentsparksoftware/react-datatables-net/dt`\n\n```tsx\nimport { defaultStyling } from '@ascentsparksoftware/react-datatables-net/dt';\n// stylesheet (once, in your root layout / entry):\nimport 'datatables.net-dt/css/dataTables.dataTables.css';\n\n<DataTablesProvider styling={defaultStyling}>…</DataTablesProvider>\n```\n\n**Bootstrap 5** — `@ascentsparksoftware/react-datatables-net/bs5` (needs the `datatables.net-bs5` peer)\n\n```tsx\nimport { bootstrap5Styling } from '@ascentsparksoftware/react-datatables-net/bs5';\n// stylesheets:\nimport 'bootstrap/dist/css/bootstrap.css';\nimport 'datatables.net-bs5/css/dataTables.bootstrap5.css';\n\n// tables typically use className=\"table table-striped\" instead of \"display\"\n<DataTablesProvider styling={bootstrap5Styling}>…</DataTablesProvider>\n```\n\n**Tailwind** — `@ascentsparksoftware/react-datatables-net/tailwind`, authored by us (DataTables ships no official\nTailwind package). Self-contained, scoped stylesheet — Tailwind v4-compatible plain CSS, no\nTailwind build step required, themeable via CSS custom properties:\n\n```tsx\nimport { tailwindStyling } from '@ascentsparksoftware/react-datatables-net/tailwind';\n// stylesheet:\nimport '@ascentsparksoftware/react-datatables-net/tailwind/styles/react-datatables-net.tailwind.css';\n\n<DataTablesProvider styling={tailwindStyling}>…</DataTablesProvider>\n```\n\n**Material** — `@ascentsparksoftware/react-datatables-net/material`, authored by us (DataTables ships no official\nMaterial package). Follows Material Design conventions, themeable via CSS custom properties:\n\n```tsx\nimport { materialStyling } from '@ascentsparksoftware/react-datatables-net/material';\n// stylesheet:\nimport '@ascentsparksoftware/react-datatables-net/material/styles/react-datatables-net.material.css';\n\n<DataTablesProvider styling={materialStyling}>…</DataTablesProvider>\n```\n\nThe Tailwind and Material adapters scope their stylesheets under a class (`rdt-tailwind` /\n`rdt-material`) that the component adds to the DataTables container automatically.\n\n> **Overriding the scope class detaches the shipped stylesheet.** The CSS is hard-scoped to the\n> default class, so `withTailwind({ scopeClass: 'my-scope' })` renders the table unstyled unless\n> you also ship your own copy of the stylesheet rescoped under `.my-scope`. To theme the table,\n> keep the default scope and override the CSS custom properties (`--rdt-tw-*` for Tailwind)\n> instead.\n\n## 📚 Documentation\n\nLive demo and full docs for every feature, styling adapter and extension:\n**[react-datatables-net.ascentspark.com](https://react-datatables-net.ascentspark.com)**\n\nIn this repo:\n\n| Doc | What's inside |\n| --- | --- |\n| [Edit in place](docs/EDIT-IN-PLACE.md) | the editing engine in full |\n| [Security](docs/SECURITY.md) | cell rendering and the XSS boundary |\n| [Changelog](CHANGELOG.md) | dated release notes |\n\n## 🔢 Versions\n\n`@ascentsparksoftware/react-datatables-net` uses independent semantic versioning (unlike its Angular sibling, it does not\nneed one release line per framework major). Peer dependencies: `react` / `react-dom` `^19` and\n`datatables.net` `^2.1`; the `datatables.net-dt` and `datatables.net-bs5` peers are optional — install\nthe one your chosen styling adapter needs.\n\n## 🛠️ Working on this repo\n\nThis is an npm workspace: `package/` is the publishable library, `demo/` is the Next.js demo app.\n\n```bash\nnpm install\n\nnpm run build -w @ascentsparksoftware/react-datatables-net   # build the library\nnpm run dev -w demo                     # run the demo (http://localhost:4288)\nnpm test -w @ascentsparksoftware/react-datatables-net        # unit tests (Vitest)\nnpm run build:demo && npx playwright test   # end-to-end tests\n```\n\n## 🤝 Help keep it healthy\n\nWe genuinely try to keep this library current, bug-free and secure, and honestly the best way to get\nthere is together. If something breaks, please\n[open an issue](https://github.com/ascentspark/react-datatables/issues) so we can look into it. If\nyou can fix a bug or add something useful, pull requests are very welcome, big or small. An\nopen-source library stays dependable only when people use it, tell us what's broken, and pitch in\nnow and then, so thank you in advance for anything you send our way. 💛\n\n## 👋 About\n\nWe are [Ascentspark](https://ascentspark.com). We have used datatables.net across our projects and\nkept writing the same wrapper code to make it feel at home in modern React. This is that code,\ntidied up and shared, in case you are looking for a React wrapper too.\n\n## License\n\nMIT\n","readmeFilename":"README.md"}