react-flexi-datatable 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,153 @@
1
+ # react-flexi-datatable 🚀
2
+
3
+ A feature-rich, interactive, highly configurable, and responsive React data table component built with Tailwind CSS and Lucide icons.
4
+
5
+ ---
6
+
7
+ ## 📦 Installation
8
+
9
+ Install `react-flexi-datatable` in your React application:
10
+
11
+ ```bash
12
+ # Using npm
13
+ npm install react-flexi-datatable
14
+
15
+ # OR using yarn
16
+ yarn add react-flexi-datatable
17
+
18
+ # OR using pnpm
19
+ pnpm add react-flexi-datatable
20
+ ```
21
+
22
+ ---
23
+
24
+ ## 💻 Quick Start & Usage
25
+
26
+ Import `DataTable` and the bundled CSS file in your React application:
27
+
28
+ ```jsx
29
+ import React, { useState } from "react";
30
+ import DataTable from "react-flexi-datatable";
31
+ import "react-flexi-datatable/dist/style.css"; // Import styles
32
+
33
+ const tableConfig = {
34
+ title: "User Directory",
35
+ searchable: true, // Enable global search bar
36
+ filterable: true, // Enable dropdown filter menu
37
+ sortable: true, // Enable column header sorting
38
+ pagination: true, // Enable pagination footer
39
+ columnVisibility: true, // Enable column visibility toggle menu
40
+ selectable: true, // Enable row checkboxes
41
+ keyboardNavigation: true,// Enable arrow key grid navigation
42
+ exportable: true, // Enable CSV export button
43
+ bulkEditable: true, // Enable bulk edit mode
44
+ dropcolumn: true, // Enable drag column header to hide dropzone
45
+ columnordering: true, // Enable drag & drop column reordering
46
+ pageSize: 5,
47
+ pageSizeOptions: [5, 10, 20],
48
+ filters: [
49
+ {
50
+ key: "status",
51
+ label: "Status",
52
+ type: "select",
53
+ options: [
54
+ { label: "All", value: "all" },
55
+ { label: "Active", value: "Active" },
56
+ { label: "Inactive", value: "Inactive" }
57
+ ]
58
+ }
59
+ ],
60
+ columns: [
61
+ { key: "name", label: "Name", visible: true, sortable: true, searchable: true, editable: true, width: 260 },
62
+ { key: "email", label: "Email", visible: true, sortable: true, searchable: true, editable: true },
63
+ { key: "role", label: "Role", visible: true, sortable: true, searchable: true, editable: true, type: "select", options: ["Admin", "Editor", "User"] },
64
+ { key: "status", label: "Status", visible: true, sortable: true, searchable: true, editable: true, type: "select", options: ["Active", "Inactive"] }
65
+ ],
66
+ actions: { view: true, edit: true, delete: true }
67
+ };
68
+
69
+ export default function App() {
70
+ const [data, setData] = useState([
71
+ { id: 1, name: "Aarav Sharma", email: "aarav@example.com", role: "Admin", status: "Active" },
72
+ { id: 2, name: "Priya Singh", email: "priya@example.com", role: "Editor", status: "Active" },
73
+ { id: 3, name: "Rahul Verma", email: "rahul@example.com", role: "User", status: "Inactive" }
74
+ ]);
75
+
76
+ return (
77
+ <main className="p-6 max-w-7xl mx-auto">
78
+ <DataTable
79
+ config={tableConfig}
80
+ data={data}
81
+ onView={(row) => alert(`Viewing: ${row.name}`)}
82
+ onEdit={(updatedRow) => {
83
+ setData((prev) => prev.map((item) => (item.id === updatedRow.id ? updatedRow : item)));
84
+ }}
85
+ onBulkEdit={(ids, changes) => console.log("Bulk updated IDs:", ids, changes)}
86
+ onDelete={(deletedRow) => {
87
+ setData((prev) => prev.filter((item) => item.id !== deletedRow.id));
88
+ }}
89
+ />
90
+ </main>
91
+ );
92
+ }
93
+ ```
94
+
95
+ ---
96
+
97
+ ## ✨ Complete Feature Breakdown
98
+
99
+ ### 🪟 1. Drag & Drop Column Reordering (`columnordering: true`)
100
+ - **Header Dragging**: Click and drag column headers left or right to reorder columns.
101
+ - **Menu Reordering**: Drag columns inside the **Columns** dropdown menu to reorder.
102
+
103
+ ### 📐 2. Column Resizing (`width: number`)
104
+ - **Resizer Handle**: Hover over column borders and drag to resize column width.
105
+ - **Double-Click Reset**: Double-click resizer border to reset back to custom default width.
106
+
107
+ ### 🗑️ 3. Drop Column to Hide (`dropcolumn: true`)
108
+ - **Dropzone**: Dragging a column header reveals a dropzone above the table. Drop to hide the column instantly.
109
+
110
+ ### ✂️ 4. Character Truncation & Hover Tooltip
111
+ - **25-Character Truncation**: Text longer than 25 characters automatically truncates with `...`.
112
+ - **Hover Full Text**: Hovering over truncated text displays full text in a tooltip.
113
+
114
+ ### ✏️ 5. Bulk Editing Mode (`bulkEditable: true`)
115
+ - **Multi-Row Selection**: Select rows via checkboxes and choose specific columns to bulk update simultaneously.
116
+
117
+ ### 📝 6. Inline Row Editing
118
+ - **In-Place Editing**: Edit row data directly inside the table with input or select controls (`Enter` to save, `Escape` to cancel).
119
+
120
+ ### 👁️ 7. Column Visibility & LocalStorage Persistence
121
+ - Toggle column visibility on/off. Layout order, widths, and visibility automatically persist in `localStorage`.
122
+
123
+ ### 🔍 8. Global Search, Filtering & Sorting
124
+ - Real-time multi-column search, dynamic select dropdown filters, and multi-state column header sorting.
125
+
126
+ ### ⌨️ 9. Keyboard Grid Navigation (`keyboardNavigation: true`)
127
+ - Navigate cells with `↑` `↓` `←` `→` arrow keys and activate controls with `Enter` / `Space`.
128
+
129
+ ### 📥 10. CSV Export (`exportable: true`)
130
+ - Export active filtered and sorted table data to CSV with a single click.
131
+
132
+ ---
133
+
134
+ ## 🛠️ Publishing to NPM
135
+
136
+ To publish this package to NPM under `react-flexi-datatable`:
137
+
138
+ ```bash
139
+ # 1. Login to your NPM account
140
+ npm login
141
+
142
+ # 2. Build library bundle
143
+ npm run build
144
+
145
+ # 3. Publish to global NPM registry
146
+ npm publish --access public
147
+ ```
148
+
149
+ ---
150
+
151
+ ## 📄 License
152
+
153
+ MIT License © 2026
package/dist/index.cjs ADDED
@@ -0,0 +1,8 @@
1
+ (function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports,require("react"),require("lucide-react")):typeof define==`function`&&define.amd?define([`exports`,`react`,`lucide-react`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.FlexiTable={},e.React,e.LucideReact))})(this,function(e,t,n){Object.defineProperties(e,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});var r=Object.create,i=Object.defineProperty,a=Object.getOwnPropertyDescriptor,o=Object.getOwnPropertyNames,s=Object.getPrototypeOf,c=Object.prototype.hasOwnProperty,l=(e,t)=>()=>(t||(e((t={exports:{}}).exports,t),e=null),t.exports),u=(e,t,n,r)=>{if(t&&typeof t==`object`||typeof t==`function`)for(var s=o(t),l=0,u=s.length,d;l<u;l++)d=s[l],!c.call(e,d)&&d!==n&&i(e,d,{get:(e=>t[e]).bind(null,d),enumerable:!(r=a(t,d))||r.enumerable});return e};t=((e,t,n)=>(n=e==null?{}:r(s(e)),u(t||!e||!e.__esModule||!c.call(e,`default`)?i(n,`default`,{value:e,enumerable:!0}):n,e)))(t,1);var d=l((e=>{var t=Symbol.for(`react.transitional.element`),n=Symbol.for(`react.fragment`);function r(e,n,r){var i=null;if(r!==void 0&&(i=``+r),n.key!==void 0&&(i=``+n.key),`key`in n)for(var a in r={},n)a!==`key`&&(r[a]=n[a]);else r=n;return n=r.ref,{$$typeof:t,type:e,key:i,ref:n===void 0?null:n,props:r}}e.Fragment=n,e.jsx=r,e.jsxs=r})),f=l((e=>{process.env.NODE_ENV!==`production`&&(function(){function t(e){if(e==null)return null;if(typeof e==`function`)return e.$$typeof===T?null:e.displayName||e.name||null;if(typeof e==`string`)return e;switch(e){case _:return`Fragment`;case y:return`Profiler`;case v:return`StrictMode`;case te:return`Suspense`;case S:return`SuspenseList`;case ne:return`Activity`}if(typeof e==`object`)switch(typeof e.tag==`number`&&console.error(`Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue.`),e.$$typeof){case g:return`Portal`;case b:return e.displayName||`Context`;case ee:return(e._context.displayName||`Context`)+`.Consumer`;case x:var n=e.render;return e=e.displayName,e||=(e=n.displayName||n.name||``,e===``?`ForwardRef`:`ForwardRef(`+e+`)`),e;case C:return n=e.displayName||null,n===null?t(e.type)||`Memo`:n;case w:n=e._payload,e=e._init;try{return t(e(n))}catch{}}return null}function n(e){return``+e}function r(e){try{n(e);var t=!1}catch{t=!0}if(t){t=console;var r=t.error,i=typeof Symbol==`function`&&Symbol.toStringTag&&e[Symbol.toStringTag]||e.constructor.name||`Object`;return r.call(t,`The provided key is an unsupported type %s. This value must be coerced to a string before using it here.`,i),n(e)}}function i(e){if(e===_)return`<>`;if(typeof e==`object`&&e&&e.$$typeof===w)return`<...>`;try{var n=t(e);return n?`<`+n+`>`:`<...>`}catch{return`<...>`}}function a(){var e=E.A;return e===null?null:e.getOwner()}function o(){return Error(`react-stack-top-frame`)}function s(e){if(re.call(e,`key`)){var t=Object.getOwnPropertyDescriptor(e,`key`).get;if(t&&t.isReactWarning)return!1}return e.key!==void 0}function c(e,t){function n(){O||(O=!0,console.error("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",t))}n.isReactWarning=!0,Object.defineProperty(e,"key",{get:n,configurable:!0})}function l(){var e=t(this.type);return k[e]||(k[e]=!0,console.error(`Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release.`)),e=this.props.ref,e===void 0?null:e}function u(e,t,n,r,i,a){var o=n.ref;return e={$$typeof:h,type:e,key:t,props:n,_owner:r},(o===void 0?null:o)===null?Object.defineProperty(e,"ref",{enumerable:!1,value:null}):Object.defineProperty(e,"ref",{enumerable:!1,get:l}),e._store={},Object.defineProperty(e._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:0}),Object.defineProperty(e,"_debugInfo",{configurable:!1,enumerable:!1,writable:!0,value:null}),Object.defineProperty(e,"_debugStack",{configurable:!1,enumerable:!1,writable:!0,value:i}),Object.defineProperty(e,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:a}),Object.freeze&&(Object.freeze(e.props),Object.freeze(e)),e}function d(e,n,i,o,l,d){var p=n.children;if(p!==void 0){if(o){if(ie(p)){for(o=0;o<p.length;o++)f(p[o]);Object.freeze&&Object.freeze(p)}else console.error(`React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.`)}else f(p)}if(re.call(n,`key`)){p=t(e);var m=Object.keys(n).filter(function(e){return e!==`key`});o=0<m.length?`{key: someKey, `+m.join(`: ..., `)+`: ...}`:`{key: someKey}`,M[p+o]||(m=0<m.length?`{`+m.join(`: ..., `)+`: ...}`:`{}`,console.error(`A props object containing a "key" prop is being spread into JSX:
2
+ let props = %s;
3
+ <%s {...props} />
4
+ React keys must be passed directly to JSX without using spread:
5
+ let props = %s;
6
+ <%s key={someKey} {...props} />`,o,p,m,p),M[p+o]=!0)}if(p=null,i!==void 0&&(r(i),p=``+i),s(n)&&(r(n.key),p=``+n.key),`key`in n)for(var h in i={},n)h!==`key`&&(i[h]=n[h]);else i=n;return p&&c(i,typeof e==`function`?e.displayName||e.name||`Unknown`:e),u(e,p,i,a(),l,d)}function f(e){p(e)?e._store&&(e._store.validated=1):typeof e==`object`&&e&&e.$$typeof===w&&(e._payload.status===`fulfilled`?p(e._payload.value)&&e._payload.value._store&&(e._payload.value._store.validated=1):e._store&&(e._store.validated=1))}function p(e){return typeof e==`object`&&!!e&&e.$$typeof===h}var m=require("react"),h=Symbol.for(`react.transitional.element`),g=Symbol.for(`react.portal`),_=Symbol.for(`react.fragment`),v=Symbol.for(`react.strict_mode`),y=Symbol.for(`react.profiler`),ee=Symbol.for(`react.consumer`),b=Symbol.for(`react.context`),x=Symbol.for(`react.forward_ref`),te=Symbol.for(`react.suspense`),S=Symbol.for(`react.suspense_list`),C=Symbol.for(`react.memo`),w=Symbol.for(`react.lazy`),ne=Symbol.for(`react.activity`),T=Symbol.for(`react.client.reference`),E=m.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,re=Object.prototype.hasOwnProperty,ie=Array.isArray,D=console.createTask?console.createTask:function(){return null};m={react_stack_bottom_frame:function(e){return e()}};var O,k={},A=m.react_stack_bottom_frame.bind(m,o)(),j=D(i(o)),M={};e.Fragment=_,e.jsx=function(e,t,n){var r=1e4>E.recentlyCreatedOwnerStacks++;return d(e,t,n,!1,r?Error(`react-stack-top-frame`):A,r?D(i(e)):j)},e.jsxs=function(e,t,n){var r=1e4>E.recentlyCreatedOwnerStacks++;return d(e,t,n,!0,r?Error(`react-stack-top-frame`):A,r?D(i(e)):j)}})()})),p=l(((e,t)=>{t.exports=process.env.NODE_ENV===`production`?d():f()}))(),m=`border border-slate-200 rounded-lg bg-white`,h={Active:`bg-emerald-50 text-emerald-700`,Inactive:`bg-slate-100 text-slate-600`,Pending:`bg-amber-50 text-amber-700`};function g({config:e,data:r=[],onView:i,onEdit:a,onDelete:o,onBulkEdit:s}){let c=`table_cols_${e.id||e.title||`default`}`,[l,u]=(0,t.useState)(r),[d,f]=(0,t.useState)(``),[g,_]=(0,t.useState)({}),[v,y]=(0,t.useState)({key:null,dir:null}),[ee,b]=(0,t.useState)(1),[x,te]=(0,t.useState)(e.pageSize||10),[S,C]=(0,t.useState)(()=>{try{let e=localStorage.getItem(`${c}_visible`);if(e)return JSON.parse(e)}catch{}return Object.fromEntries(e.columns.map(e=>[e.key,e.visible!==!1]))}),[w,ne]=(0,t.useState)(()=>{try{let e=localStorage.getItem(`${c}_order`);if(e)return JSON.parse(e)}catch{}return e.columns.map(e=>e.key)}),[T,E]=(0,t.useState)(()=>{try{let e=localStorage.getItem(`${c}_widths`);if(e)return JSON.parse(e)}catch{}return Object.fromEntries(e.columns.map(e=>[e.key,e.width||160]))}),[re,ie]=(0,t.useState)(null),[D,O]=(0,t.useState)(null),[k,A]=(0,t.useState)(null),[j,M]=(0,t.useState)([]),[N,P]=(0,t.useState)(null),[ae,oe]=(0,t.useState)(!1),[se,ce]=(0,t.useState)(!1),[F,I]=(0,t.useState)({row:0,col:0}),[le,ue]=(0,t.useState)(null),[L,R]=(0,t.useState)({}),[z,de]=(0,t.useState)(!1),[fe,B]=(0,t.useState)([]),[V,H]=(0,t.useState)({}),[U,W]=(0,t.useState)(1),G=(0,t.useRef)(null),pe=(0,t.useRef)(null),me=(0,t.useRef)(null),K=(0,t.useRef)(null);(0,t.useEffect)(()=>{e.searchable&&K.current&&K.current.focus()},[e.searchable]),(0,t.useEffect)(()=>{let e=e=>{pe.current&&!pe.current.contains(e.target)&&ce(!1),me.current&&!me.current.contains(e.target)&&oe(!1)};return document.addEventListener(`mousedown`,e),()=>document.removeEventListener(`mousedown`,e)},[]),(0,t.useEffect)(()=>u(r),[r]),(0,t.useEffect)(()=>b(1),[d,g,x]),(0,t.useEffect)(()=>{try{localStorage.setItem(`${c}_order`,JSON.stringify(w))}catch{}},[w,c]),(0,t.useEffect)(()=>{try{localStorage.setItem(`${c}_visible`,JSON.stringify(S))}catch{}},[S,c]),(0,t.useEffect)(()=>{try{localStorage.setItem(`${c}_widths`,JSON.stringify(T))}catch{}},[T,c]);let he=()=>{let t=e.columns.map(e=>e.key),n=Object.fromEntries(e.columns.map(e=>[e.key,e.visible!==!1])),r=Object.fromEntries(e.columns.map(e=>[e.key,e.width||160]));ne(t),C(n),E(r);try{localStorage.removeItem(`${c}_order`),localStorage.removeItem(`${c}_visible`),localStorage.removeItem(`${c}_widths`)}catch{}},ge=(e,t)=>{e.preventDefault(),e.stopPropagation();let n=e.clientX,r=T[t]||160,i=e=>{let i=e.clientX-n,a=Math.max(70,r+i);E(e=>({...e,[t]:a}))},a=()=>{document.removeEventListener(`mousemove`,i),document.removeEventListener(`mouseup`,a),ie(null)};ie(t),document.addEventListener(`mousemove`,i),document.addEventListener(`mouseup`,a)},q=(0,t.useMemo)(()=>{let t=Object.fromEntries(e.columns.map(e=>[e.key,e]));return w.map(e=>t[e]).filter(e=>e&&S[e.key])},[e.columns,w,S]),J=(0,t.useMemo)(()=>e.columns.filter(e=>e.editable!==!1),[e.columns]),_e=t=>{if(t.options)return t.options;let n=e.filters?.find(e=>e.key===t.key);return n?.options?n.options.filter(e=>e.value!==`all`).map(e=>e.value):null},Y=e.columnordering!==!1&&e.columnOrdering!==!1,ve=Y&&e.dropcolumn!==!1&&e.dropColumn!==!1,ye=(e,t)=>{Y&&(O(t),e.dataTransfer.setData(`text/plain`,t),e.dataTransfer.effectAllowed=`move`)},be=(e,t)=>{e.preventDefault(),ve&&(e.dataTransfer.dropEffect=`move`,k!==t&&A(t))},xe=(e,t)=>{e.preventDefault(),e.stopPropagation();let n=e.dataTransfer.getData(`text/plain`)||D;n&&n!==t&&ne(e=>{let r=[...e],i=r.indexOf(n),a=r.indexOf(t);return i!==-1&&a!==-1&&(r.splice(i,1),r.splice(a,0,n)),r}),O(null),A(null)},Se=e=>{e&&(C(t=>Object.values(t).filter(Boolean).length<=1?t:{...t,[e]:!1}),O(null),A(null))},X=(0,t.useMemo)(()=>{let t=[...l];if(d.trim()){let n=d.toLowerCase(),r=e.columns.filter(e=>e.searchable!==!1).map(e=>e.key);t=t.filter(e=>r.some(t=>String(e[t]??``).toLowerCase().includes(n)))}return Object.entries(g).forEach(([e,n])=>{n&&n!==`all`&&(t=t.filter(t=>String(t[e])===String(n)))}),v.key&&t.sort((e,t)=>{let n=String(e[v.key]??``).toLowerCase(),r=String(t[v.key]??``).toLowerCase(),i=n.localeCompare(r,void 0,{numeric:!0});return v.dir===`asc`?i:-i}),t},[l,d,g,v,e.columns]),Z=Math.max(1,Math.ceil(X.length/x)),Q=Math.min(ee,Z),$=X.slice((Q-1)*x,Q*x),Ce=(0,t.useMemo)(()=>j.length>0?j:$.map(e=>e.id),[j,$]),we=e=>{if(v.key!==e)return y({key:e,dir:`asc`});if(v.dir===`asc`)return y({key:e,dir:`desc`});y({key:null,dir:null})},Te=e=>M(e?$.map(e=>e.id):[]),Ee=e=>M(t=>t.includes(e)?t.filter(t=>t!==e):[...t,e]),De=e=>{ue(e.id),R({...e})},Oe=()=>{ue(null),R({})},ke=()=>{u(e=>e.map(e=>e.id===le?L:e)),a?.(L),ue(null),R({})},Ae=()=>{let e={},t=j.length>0?j:$.map(e=>e.id);l.forEach(n=>{t.includes(n.id)&&(e[n.id]={...n})}),H(e),B(J.map(e=>e.key)),de(!0)},je=()=>{de(!1),H({}),B([])},Me=()=>{let e=j.length>0?j:$.map(e=>e.id);u(t=>t.map(t=>e.includes(t.id)&&V[t.id]||t)),s?.(e,V),de(!1),H({}),B([])};return(0,t.useEffect)(()=>{let t=t=>{if(!e.keyboardNavigation||!$.length)return;let n=document.activeElement;if(n&&([`TEXTAREA`].includes(n.tagName)||n.tagName===`INPUT`&&n.type!==`checkbox`||n.tagName===`SELECT`))return;let r=!!(e.actions?.view||e.actions?.edit||e.actions?.delete),a=q.length+ +!!e.selectable,o=q.length+ +!!e.selectable+ +!!r,s=n?.closest(`[data-cell]`),c=F.row,l=F.col;if(s){let e=s.getAttribute(`data-cell`);if(e){let t=e.split(`-`).map(Number);t.length===2&&!isNaN(t[0])&&!isNaN(t[1])&&(c=t[0],l=t[1])}}if(t.key===`ArrowDown`){t.preventDefault();let e=Math.min($.length-1,c+1);I({row:e,col:l})}else if(t.key===`ArrowUp`){t.preventDefault();let e=Math.max(-1,c-1);I({row:e,col:l})}else if(t.key===`ArrowRight`){if(t.preventDefault(),r&&l===a){let e=G.current?.querySelector(`[data-cell="${c}-${l}"]`),t=e?Array.from(e.querySelectorAll(`button`)):[];if(U<t.length-1){W(e=>e+1);return}}let e=Math.min(o-1,l+1);I({row:c,col:e})}else if(t.key===`ArrowLeft`){if(t.preventDefault(),r&&l===a&&U>0){W(e=>e-1);return}let e=Math.max(0,l-1);I({row:c,col:e})}else if(t.key===`Enter`||t.key===` `){if(c===-1){if(e.selectable&&l===0)t.preventDefault(),Te($.length>0&&!$.every(e=>j.includes(e.id)));else{let n=e.selectable?l-1:l,r=q[n];r&&r.sortable&&(t.preventDefault(),we(r.key))}}else{let o=$[c];n&&(n.type===`checkbox`||n.tagName===`BUTTON`)?(t.key===`Enter`||t.key===` `)&&(t.preventDefault(),n.click()):o&&(e.selectable&&l===0?(t.preventDefault(),Ee(o.id)):r&&l===a?(t.preventDefault(),De(o)):t.key===`Enter`&&(t.preventDefault(),i?.(o)))}}};return window.addEventListener(`keydown`,t),()=>window.removeEventListener(`keydown`,t)},[e.keyboardNavigation,$,q,F,U,Ee,Te,we,i,e.selectable,j]),(0,t.useEffect)(()=>{if(!e.keyboardNavigation||!G.current||document.activeElement===K.current)return;let t=G.current.querySelector(`[data-cell="${F.row}-${F.col}"]`);if(t){let e=Array.from(t.querySelectorAll(`input, button, select`));e.length>0?(e[Math.min(U,e.length-1)]||e[0]).focus():t.focus()}},[F,U,e.keyboardNavigation,$]),(0,p.jsxs)(`div`,{className:`space-y-3`,children:[(0,p.jsx)(`div`,{className:`${m} p-4`,children:(0,p.jsxs)(`div`,{className:`flex flex-col gap-3 lg:flex-row lg:items-center lg:justify-between`,children:[(0,p.jsxs)(`div`,{children:[(0,p.jsx)(`h2`,{className:`text-lg font-semibold`,children:e.title}),(0,p.jsxs)(`p`,{className:`text-sm text-slate-500`,children:[X.length,` records`]})]}),(0,p.jsxs)(`div`,{className:`flex flex-wrap gap-2`,children:[e.searchable&&(0,p.jsxs)(`div`,{className:`relative`,children:[(0,p.jsx)(n.Search,{size:16,className:`absolute left-3 top-1/2 -translate-y-1/2 text-slate-400`}),(0,p.jsx)(`input`,{ref:K,autoFocus:!0,value:d,onChange:e=>f(e.target.value),placeholder:`Search...`,className:`w-56 rounded-lg border border-slate-200 py-2 pl-9 pr-8 text-sm outline-none focus:border-indigo-500 focus:ring-2 focus:ring-indigo-500/20`}),d&&(0,p.jsx)(`button`,{onClick:()=>{f(``),K.current?.focus()},className:`absolute right-2 top-1/2 -translate-y-1/2 text-slate-400 hover:text-slate-600`,children:(0,p.jsx)(n.X,{size:15})})]}),e.filterable&&(0,p.jsxs)(`div`,{ref:pe,className:`relative`,children:[(0,p.jsxs)(`button`,{onClick:()=>ce(e=>!e),className:`flex items-center gap-2 rounded-lg border border-slate-200 px-3 py-2 text-sm`,children:[(0,p.jsx)(n.SlidersHorizontal,{size:16}),`Filter`]}),se&&(0,p.jsxs)(`div`,{className:`absolute right-0 z-30 mt-2 w-64 rounded-xl border bg-white p-4 shadow-xl`,children:[e.filters?.map(e=>(0,p.jsxs)(`label`,{className:`mb-3 block text-sm`,children:[(0,p.jsx)(`span`,{className:`mb-1 block font-medium`,children:e.label}),(0,p.jsx)(`select`,{value:g[e.key]||`all`,onChange:t=>_(n=>({...n,[e.key]:t.target.value})),className:`w-full rounded-lg border p-2`,children:e.options.map(e=>(0,p.jsx)(`option`,{value:e.value,children:e.label},e.value))})]},e.key)),(0,p.jsx)(`button`,{onClick:()=>_({}),className:`text-sm font-medium text-slate-600`,children:`Clear filters`})]})]}),e.columnVisibility&&(0,p.jsxs)(`div`,{ref:me,className:`relative`,children:[(0,p.jsxs)(`button`,{onClick:()=>oe(e=>!e),className:`flex items-center gap-2 rounded-lg border border-slate-200 px-3 py-2 text-sm`,children:[(0,p.jsx)(n.Columns3,{size:16}),`Columns`]}),ae&&(0,p.jsxs)(`div`,{className:`absolute right-0 z-30 mt-2 w-64 rounded-xl border bg-white p-3.5 shadow-xl`,children:[(0,p.jsxs)(`div`,{className:`flex items-center justify-between pb-2 mb-2 border-b`,children:[(0,p.jsx)(`span`,{className:`text-xs font-semibold uppercase tracking-wider text-slate-500`,children:`Columns & Layout`}),(0,p.jsxs)(`button`,{onClick:he,className:`flex items-center gap-1 text-xs text-indigo-600 hover:text-indigo-800 font-medium`,title:`Reset default layout`,children:[(0,p.jsx)(n.RotateCcw,{size:12}),`Reset`]})]}),(0,p.jsx)(`div`,{className:`space-y-1 max-h-64 overflow-y-auto`,children:w.map(t=>{let r=e.columns.find(e=>e.key===t);if(!r)return null;let i=S[t]!==!1;return(0,p.jsxs)(`div`,{draggable:!0,onDragStart:e=>ye(e,r.key),onDragOver:e=>be(e,r.key),onDrop:e=>xe(e,r.key),className:`flex items-center justify-between p-2 text-sm rounded-lg hover:bg-slate-50 cursor-grab active:cursor-grabbing transition-colors ${D===r.key?`opacity-30 bg-slate-100`:``} ${k===r.key&&D!==r.key?`border-l-4 border-l-indigo-600 bg-indigo-50/60`:``}`,children:[(0,p.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,p.jsx)(`span`,{title:`Drag to reorder`,className:`text-slate-300 hover:text-slate-500 cursor-grab`,children:(0,p.jsx)(n.GripVertical,{size:14})}),(0,p.jsxs)(`label`,{className:`flex items-center gap-2 cursor-pointer select-none`,children:[(0,p.jsx)(`input`,{type:`checkbox`,checked:i,onChange:()=>C(e=>{let t=Object.values(e).filter(Boolean).length;return e[r.key]&&t===1?e:{...e,[r.key]:!e[r.key]}}),className:`rounded text-indigo-600 focus:ring-indigo-500`}),(0,p.jsx)(`span`,{className:i?`font-medium text-slate-800`:`text-slate-400 line-through`,children:r.label})]})]}),(0,p.jsxs)(`span`,{className:`text-xs text-slate-400 font-mono`,children:[T[r.key]||160,`px`]})]},r.key)})}),(0,p.jsx)(`p`,{className:`mt-2.5 pt-2 border-t text-[11px] text-slate-400 text-center`,children:`Drag handles to reorder | Drag column edge to resize`})]})]}),e.bulkEditable!==!1&&J.length>0&&(0,p.jsxs)(`button`,{onClick:Ae,className:`flex items-center gap-2 rounded-lg border px-3 py-2 text-sm font-medium transition-colors ${z?`border-indigo-500 bg-indigo-600 text-white`:j.length>0?`border-indigo-300 bg-indigo-50 text-indigo-700 hover:bg-indigo-100`:`border-slate-200 bg-white text-slate-700 hover:bg-slate-50`}`,children:[(0,p.jsx)(n.Edit3,{size:16}),`Bulk Edit`,j.length>0?` (${j.length})`:``]}),e.exportable&&(0,p.jsxs)(`button`,{onClick:()=>{let e=q.map(e=>e.label).join(`,`),t=X.map(e=>q.map(t=>`"${String(e[t.key]??``).replaceAll(`"`,`""`)}"`).join(`,`)).join(`
7
+ `),n=new Blob([e+`
8
+ `+t],{type:`text/csv`}),r=document.createElement(`a`);r.href=URL.createObjectURL(n),r.download=`table-export.csv`,r.click(),URL.revokeObjectURL(r.href)},className:`flex items-center gap-2 rounded-lg border border-slate-200 px-3 py-2 text-sm`,children:[(0,p.jsx)(n.Download,{size:16}),`Export`]})]})]})}),ve&&(0,p.jsx)(`div`,{onDragOver:e=>{e.preventDefault(),e.dataTransfer.dropEffect=`move`},onDrop:e=>{e.preventDefault();let t=e.dataTransfer.getData(`text/plain`)||D;t&&Se(t)},className:`transition-all duration-200 overflow-hidden ${D?`max-h-24 opacity-100 my-2`:`max-h-0 opacity-0 my-0 pointer-events-none`}`,children:(0,p.jsxs)(`div`,{className:`flex items-center justify-center gap-2 rounded-xl border-2 border-dashed border-rose-400 bg-rose-50 p-3 text-sm font-semibold text-rose-700 shadow-sm`,children:[(0,p.jsx)(n.Trash2,{size:20,className:`text-rose-600 animate-bounce`}),(0,p.jsxs)(`span`,{children:[`Drop column header here to hide column `,(0,p.jsx)(`b`,{children:e.columns.find(e=>e.key===D)?.label})]})]})}),z&&(0,p.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-3 rounded-xl border border-indigo-200 bg-indigo-50/80 p-3.5 shadow-sm`,children:[(0,p.jsxs)(`div`,{className:`flex flex-wrap items-center gap-3`,children:[(0,p.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,p.jsx)(n.Edit3,{size:18,className:`text-indigo-600`}),(0,p.jsxs)(`span`,{className:`font-semibold text-slate-900 text-sm`,children:[`Bulk Edit Mode (`,Ce.length,` records):`]})]}),(0,p.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,p.jsx)(`span`,{className:`text-xs font-medium text-slate-600`,children:`Select columns to edit:`}),J.map(e=>{let t=fe.includes(e.key);return(0,p.jsxs)(`button`,{type:`button`,onClick:()=>{B(t?t=>t.filter(t=>t!==e.key):t=>[...t,e.key])},className:`flex items-center gap-1.5 rounded-lg px-2.5 py-1 text-xs font-medium border transition-all ${t?`border-indigo-500 bg-indigo-600 text-white shadow-xs`:`border-slate-200 bg-white text-slate-700 hover:border-slate-300 hover:bg-slate-50`}`,children:[(0,p.jsx)(`span`,{className:`flex h-3.5 w-3.5 items-center justify-center rounded border ${t?`border-white bg-white text-indigo-600`:`border-slate-300 bg-white`}`,children:t&&(0,p.jsx)(n.Check,{size:10,strokeWidth:3})}),(0,p.jsx)(`span`,{children:e.label})]},e.key)})]})]}),(0,p.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,p.jsxs)(`button`,{onClick:je,className:`flex items-center gap-1.5 rounded-lg border border-slate-200 bg-white px-3 py-1.5 text-xs font-medium text-slate-700 hover:bg-slate-50 transition-colors`,children:[(0,p.jsx)(n.X,{size:14,className:`text-rose-500`}),`Cancel`]}),(0,p.jsxs)(`button`,{onClick:Me,className:`flex items-center gap-1.5 rounded-lg bg-emerald-600 px-3.5 py-1.5 text-xs font-medium text-white hover:bg-emerald-700 shadow-sm transition-colors`,children:[(0,p.jsx)(n.Check,{size:14}),`Save`]})]})]}),(0,p.jsxs)(`div`,{className:`${m} overflow-hidden`,children:[(0,p.jsx)(`div`,{className:`overflow-x-auto`,children:(0,p.jsxs)(`table`,{ref:G,className:`min-w-full text-sm table-fixed`,children:[(0,p.jsx)(`thead`,{className:`border-b bg-slate-50`,children:(0,p.jsxs)(`tr`,{children:[e.selectable&&(0,p.jsx)(`th`,{"data-cell":`-1-0`,className:`w-12 px-4 py-3`,children:(0,p.jsx)(`input`,{type:`checkbox`,checked:$.length>0&&$.every(e=>j.includes(e.id)),onChange:e=>Te(e.target.checked),onFocus:()=>I({row:-1,col:0})})}),q.map((t,r)=>{let i=e.selectable?r+1:r,a=D===t.key,o=k===t.key&&D!==t.key,s=T[t.key]||t.width||160;return(0,p.jsxs)(`th`,{"data-cell":`-1-${i}`,style:{width:`${s}px`,minWidth:`${s}px`},draggable:Y,onDragStart:e=>ye(e,t.key),onDragOver:e=>be(e,t.key),onDragLeave:()=>A(null),onDrop:e=>xe(e,t.key),onDragEnd:()=>{O(null),A(null)},"aria-sort":v.key===t.key?v.dir:`none`,className:`group relative whitespace-nowrap px-4 py-3 text-left font-semibold text-slate-600 ${Y?`cursor-grab active:cursor-grabbing`:``} transition-colors select-none ${a?`opacity-30 bg-slate-100`:``} ${o?`border-l-4 border-l-indigo-600 bg-indigo-50/60`:``}`,children:[(0,p.jsxs)(`div`,{className:`flex items-center justify-between gap-1.5 pr-2`,children:[(0,p.jsxs)(`div`,{className:`flex items-center gap-1.5 overflow-hidden`,children:[Y&&(0,p.jsx)(`span`,{title:`Drag header to reorder`,className:`text-slate-300 group-hover:text-slate-500 cursor-grab shrink-0`,children:(0,p.jsx)(n.GripVertical,{size:14})}),(0,p.jsxs)(`button`,{disabled:!t.sortable,onClick:()=>t.sortable&&we(t.key),className:`flex items-center gap-1 truncate ${t.sortable?`hover:text-slate-900`:``}`,children:[(0,p.jsx)(`span`,{className:`truncate`,children:t.label}),t.sortable&&(v.key===t.key?v.dir===`asc`?(0,p.jsx)(n.ChevronUp,{size:15,className:`shrink-0`}):(0,p.jsx)(n.ChevronDown,{size:15,className:`shrink-0`}):(0,p.jsx)(n.ChevronsUpDown,{size:15,className:`text-slate-400 shrink-0`}))]})]}),(0,p.jsx)(`button`,{type:`button`,title:`Hide column`,onClick:e=>{e.stopPropagation(),Se(t.key)},className:`opacity-0 group-hover:opacity-100 transition-opacity p-0.5 text-slate-400 hover:text-rose-600 rounded shrink-0`,children:(0,p.jsx)(n.EyeOff,{size:13})})]}),(0,p.jsx)(`div`,{draggable:!1,onMouseDown:e=>ge(e,t.key),onDoubleClick:e=>{e.stopPropagation(),E(e=>({...e,[t.key]:t.width||160}))},title:`Drag to resize column width`,className:`absolute right-0 top-0 bottom-0 w-2.5 cursor-col-resize group-hover:bg-indigo-300/50 hover:!bg-indigo-500 transition-colors z-10 ${re===t.key?`bg-indigo-600 w-1`:``}`})]},t.key)}),(e.actions?.view||e.actions?.edit||e.actions?.delete)&&(0,p.jsx)(`th`,{className:`sticky right-0 bg-slate-50 px-4 py-3 text-right font-semibold text-slate-600 w-32`,children:`Actions`})]})}),(0,p.jsxs)(`tbody`,{children:[$.map((t,r)=>{let a=le===t.id,o=z&&Ce.includes(t.id);return(0,p.jsxs)(`tr`,{className:`border-b last:border-0 ${a||o?`bg-indigo-50/20`:`hover:bg-slate-50`}`,children:[e.selectable&&(0,p.jsx)(`td`,{"data-cell":`${r}-0`,className:`px-4 py-3`,children:(0,p.jsx)(`input`,{type:`checkbox`,checked:j.includes(t.id),onChange:()=>Ee(t.id),onFocus:()=>I({row:r,col:0})})}),q.map((n,i)=>{let s=e.selectable?i+1:i,c=o&&fe.includes(n.key)&&n.editable!==!1,l=_e(n),u=T[n.key]||n.width||160,d=t[n.key],f=d==null?``:String(d),m=f.length>25;return(0,p.jsx)(`td`,{"data-cell":`${r}-${s}`,style:{width:`${u}px`,minWidth:`${u}px`},className:`px-4 py-3 truncate`,tabIndex:-1,title:m?f:void 0,children:a&&n.editable!==!1?l?(0,p.jsx)(`select`,{value:L[n.key]??``,onChange:e=>R({...L,[n.key]:e.target.value}),onKeyDown:e=>{e.key===`Enter`&&ke(),e.key===`Escape`&&Oe()},className:`w-full rounded-md border border-indigo-300 bg-white px-2 py-1 text-sm outline-none focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500`,children:l.map(e=>{let t=typeof e==`object`?e.value:e,n=typeof e==`object`?e.label:e;return(0,p.jsx)(`option`,{value:t,children:n},t)})}):(0,p.jsx)(`input`,{type:`text`,value:L[n.key]??``,onChange:e=>R({...L,[n.key]:e.target.value}),onKeyDown:e=>{e.key===`Enter`&&ke(),e.key===`Escape`&&Oe()},className:`w-full rounded-md border border-indigo-300 bg-white px-2 py-1 text-sm outline-none focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500`}):c?l?(0,p.jsx)(`select`,{value:V[t.id]?.[n.key]??t[n.key]??``,onChange:e=>H(r=>({...r,[t.id]:{...r[t.id]||t,[n.key]:e.target.value}})),onKeyDown:e=>{e.key===`Enter`&&Me(),e.key===`Escape`&&je()},className:`w-full rounded-md border border-indigo-400 bg-white px-2 py-1 text-sm outline-none focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500`,children:l.map(e=>{let t=typeof e==`object`?e.value:e,n=typeof e==`object`?e.label:e;return(0,p.jsx)(`option`,{value:t,children:n},t)})}):(0,p.jsx)(`input`,{type:`text`,value:V[t.id]?.[n.key]??t[n.key]??``,onChange:e=>H(r=>({...r,[t.id]:{...r[t.id]||t,[n.key]:e.target.value}})),onKeyDown:e=>{e.key===`Enter`&&Me(),e.key===`Escape`&&je()},className:`w-full rounded-md border border-indigo-400 bg-white px-2 py-1 text-sm outline-none focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500`}):n.render?n.render(d,t,r):n.key===`status`?(0,p.jsx)(`span`,{className:`rounded-full px-2.5 py-1 text-xs font-medium ${h[d]||`bg-slate-100 text-slate-600`}`,children:d}):m?(0,p.jsxs)(`span`,{title:f,children:[f.slice(0,25),`...`]}):f},n.key)}),(e.actions?.view||e.actions?.edit||e.actions?.delete)&&(0,p.jsx)(`td`,{"data-cell":`${r}-${q.length+ +!!e.selectable}`,className:`sticky right-0 bg-white px-4 py-3 w-32`,children:a?(0,p.jsxs)(`div`,{className:`flex justify-end gap-1`,children:[(0,p.jsx)(`button`,{title:`Save`,onClick:ke,className:`rounded-md bg-emerald-100 p-2 text-emerald-700 hover:bg-emerald-200`,children:(0,p.jsx)(n.Check,{size:16})}),(0,p.jsx)(`button`,{title:`Cancel`,onClick:Oe,className:`rounded-md bg-rose-100 p-2 text-rose-700 hover:bg-rose-200`,children:(0,p.jsx)(n.X,{size:16})})]}):(0,p.jsxs)(`div`,{className:`flex justify-end gap-1`,children:[e.actions.view&&(0,p.jsx)(`button`,{title:`View`,onClick:()=>i?.(t),onFocus:()=>{I({row:r,col:q.length+ +!!e.selectable}),W(0)},className:`rounded-md p-2 hover:bg-slate-100 focus:outline-none focus:ring-2 focus:ring-slate-400`,children:(0,p.jsx)(n.Eye,{size:16})}),e.actions.edit&&(0,p.jsx)(`button`,{title:`Edit`,onClick:()=>De(t),onFocus:()=>{I({row:r,col:q.length+ +!!e.selectable}),W(1)},className:`rounded-md p-2 hover:bg-slate-100 focus:outline-none focus:ring-2 focus:ring-slate-400`,children:(0,p.jsx)(n.Pencil,{size:16})}),e.actions.delete&&(0,p.jsx)(`button`,{title:`Delete`,onClick:()=>P(t),onFocus:()=>{I({row:r,col:q.length+ +!!e.selectable}),W(2)},className:`rounded-md p-2 text-red-600 hover:bg-red-50 focus:outline-none focus:ring-2 focus:ring-red-400`,children:(0,p.jsx)(n.Trash2,{size:16})})]})})]},t.id)}),!$.length&&(0,p.jsx)(`tr`,{children:(0,p.jsxs)(`td`,{colSpan:q.length+ +!!e.selectable+1,className:`px-6 py-16 text-center`,children:[(0,p.jsx)(`div`,{className:`font-medium`,children:`No records found`}),(0,p.jsx)(`div`,{className:`mt-1 text-sm text-slate-500`,children:`Try changing your search or filters.`})]})})]})]})}),(0,p.jsxs)(`div`,{className:`flex flex-col gap-3 border-t bg-white px-4 py-3 sm:flex-row sm:items-center sm:justify-between`,children:[(0,p.jsxs)(`div`,{className:`text-sm text-slate-500`,children:[`Showing `,X.length?(Q-1)*x+1:0,`–`,Math.min(Q*x,X.length),` of `,X.length]}),(0,p.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,p.jsx)(`select`,{value:x,onChange:e=>te(Number(e.target.value)),className:`rounded-lg border border-slate-200 px-2 py-1.5 text-sm`,children:e.pageSizeOptions.map(e=>(0,p.jsxs)(`option`,{value:e,children:[e,`/page`]},e))}),(0,p.jsx)(`button`,{disabled:Q===1,onClick:()=>b(1),className:`rounded-md border p-1.5 disabled:opacity-40`,children:(0,p.jsx)(n.ChevronsLeft,{size:16})}),(0,p.jsx)(`button`,{disabled:Q===1,onClick:()=>b(e=>e-1),className:`rounded-md border p-1.5 disabled:opacity-40`,children:(0,p.jsx)(n.ChevronLeft,{size:16})}),(0,p.jsxs)(`span`,{className:`px-2 text-sm`,children:[`Page `,Q,` of `,Z]}),(0,p.jsx)(`button`,{disabled:Q===Z,onClick:()=>b(e=>e+1),className:`rounded-md border p-1.5 disabled:opacity-40`,children:(0,p.jsx)(n.ChevronRight,{size:16})}),(0,p.jsx)(`button`,{disabled:Q===Z,onClick:()=>b(Z),className:`rounded-md border p-1.5 disabled:opacity-40`,children:(0,p.jsx)(n.ChevronsRight,{size:16})})]})]})]}),j.length>0&&!z&&(0,p.jsxs)(`div`,{className:`fixed bottom-5 left-1/2 z-40 flex -translate-x-1/2 items-center gap-3 rounded-xl bg-slate-900 px-4 py-2.5 text-sm text-white shadow-xl`,children:[(0,p.jsxs)(`span`,{className:`font-medium pl-1`,children:[j.length,` selected`]}),e.bulkEditable!==!1&&J.length>0&&(0,p.jsxs)(`button`,{onClick:Ae,className:`flex items-center gap-1.5 rounded-lg bg-indigo-600 px-3 py-1.5 text-xs font-semibold text-white hover:bg-indigo-500 transition-colors shadow-sm`,children:[(0,p.jsx)(n.Edit3,{size:14}),`Bulk Edit`]}),(0,p.jsx)(`button`,{onClick:()=>M([]),className:`text-xs text-slate-400 hover:text-white underline pr-1`,children:`Clear`})]}),N&&(0,p.jsx)(`div`,{onClick:e=>{e.target===e.currentTarget&&P(null)},className:`fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4`,children:(0,p.jsxs)(`div`,{className:`w-full max-w-sm rounded-2xl bg-white p-6 shadow-2xl`,children:[(0,p.jsx)(`h3`,{className:`text-lg font-semibold`,children:`Delete record?`}),(0,p.jsxs)(`p`,{className:`mt-2 text-sm text-slate-500`,children:[`Are you sure you want to delete `,(0,p.jsx)(`b`,{children:N.name}),`? This action cannot be undone.`]}),(0,p.jsxs)(`div`,{className:`mt-6 flex justify-end gap-2`,children:[(0,p.jsx)(`button`,{onClick:()=>P(null),className:`rounded-lg border px-4 py-2 text-sm`,children:`Cancel`}),(0,p.jsx)(`button`,{onClick:()=>{u(e=>e.filter(e=>e.id!==N.id)),M(e=>e.filter(e=>e!==N.id)),P(null),o?.(N)},className:`rounded-lg bg-red-600 px-4 py-2 text-sm font-medium text-white`,children:`Delete`})]})]})})]})}var _=g;e.DataTable=g,e.default=_});