{
    "id": "bhaskar/sortable-data-table-2",
    "kind": "component",
    "title": "Sortable Data Table",
    "summary": "Data table with selectable rows, sortable columns, status badges and a sticky header. Click a header to sort.",
    "author": "Admin",
    "stars": 0,
    "url": "https://ownlyplans.com/bhaskar/sortable-data-table-2/",
    "stack": [],
    "tools": [
        "claude-code"
    ],
    "difficulty": "beginner",
    "license": "cc-by-4.0",
    "version": "1.0",
    "overview": "",
    "steps": [],
    "files": [],
    "install": "",
    "how_to_use": "Use the component code (html, css, js, or react) directly, or run the install command.",
    "component": {
        "category": "Other",
        "html": "<div class=\"tb\"><small class=\"cn\"></small><div class=\"sh\"><table><thead></thead><tbody></tbody></table></div></div>",
        "css": ".tb{width:100%;height:100%;min-height:380px;box-sizing:border-box;padding:20px;display:flex;flex-direction:column;align-items:center;justify-content:center;font-family:system-ui,-apple-system,sans-serif;color:#eee;}.cn{width:100%;max-width:520px;font-size:11px;color:#777;margin-bottom:6px}.sh{width:100%;max-width:520px;max-height:290px;overflow:auto;border:1px solid #2a2a2a;border-radius:14px;background:#161616}table{border-collapse:collapse;width:100%;min-width:480px;font-size:12px}th{position:sticky;top:0;background:#1d1d1d;text-align:left;font-weight:600;color:#999;padding:10px 12px;cursor:pointer;user-select:none;white-space:nowrap;z-index:1}th:hover{color:#fff}td{padding:11px 12px;border-top:1px solid #222;white-space:nowrap}tr.sl td{background:rgba(10,132,255,.1)}.ck{width:15px;height:15px;border-radius:4px;border:1.5px solid #444;display:inline-grid;place-items:center;font-size:10px;color:#fff;cursor:pointer;vertical-align:middle}.ck.on{background:#0a84ff;border-color:#0a84ff}.bd{padding:3px 8px;border-radius:99px;font-size:10px;font-weight:600}.Active{background:rgba(34,197,94,.15);color:#34d399}.Invited{background:rgba(245,158,11,.15);color:#fbbf24}.Suspended{background:rgba(239,68,68,.15);color:#f87171}.ar{margin-left:4px;font-size:9px}",
        "js": "(function(){var R=document.querySelector(\".tb\"),th=R.querySelector(\"thead\"),tb=R.querySelector(\"tbody\"),cn=R.querySelector(\".cn\"),F=[\"Leo\",\"Jude\",\"Ren\",\"Eli\",\"Mia\",\"Noa\",\"Sam\",\"Zoe\",\"Ari\",\"Kai\"],L=[\"Marsh\",\"Reyes\",\"Quinn\",\"Sato\",\"Ortiz\",\"Khan\",\"Berg\",\"Lopez\",\"Ford\",\"Cole\"],RO=[\"Admin\",\"Editor\",\"Viewer\",\"Owner\"],ST=[\"Suspended\",\"Active\",\"Invited\"],D=[];for(var i=0;i<30;i++){var f=F[i%10],l=L[(i*3)%10];D.push({id:i,name:f+\" \"+l,email:(f+\".\"+l+(100+i*7)).toLowerCase()+\"@example.dev\",role:RO[i%4],status:ST[(i*2)%3],mrr:[49,99,199,499][(i*5)%4]})}var key=null,dir=1,sel={};var C=[[\"name\",\"Name\"],[\"email\",\"Email\"],[\"role\",\"Role\"],[\"status\",\"Status\"],[\"mrr\",\"MRR\"]];function draw(){var rows=D.slice();if(key)rows.sort(function(a,b){var x=a[key],y=b[key];return(x>y?1:x<y?-1:0)*dir});var n=Object.keys(sel).length;cn.textContent=n?n+\" selected\":D.length+\" rows\";th.innerHTML=\"\";var tr=document.createElement(\"tr\"),h=document.createElement(\"th\");h.innerHTML=\"<span class=\\\"ck\"+(n===D.length?\" on\":\"\")+\"\\\">\"+(n===D.length?\"✓\":n?\"–\":\"\")+\"</span>\";h.onclick=function(){if(n===D.length)sel={};else D.forEach(function(d){sel[d.id]=1});draw()};tr.appendChild(h);C.forEach(function(c){var t=document.createElement(\"th\");t.innerHTML=c[1]+\"<span class=\\\"ar\\\">\"+(key===c[0]?(dir>0?\"▲\":\"▼\"):\"\")+\"</span>\";t.onclick=function(){if(key===c[0])dir=-dir;else{key=c[0];dir=1}draw()};tr.appendChild(t)});th.appendChild(tr);tb.innerHTML=\"\";rows.forEach(function(d){var r=document.createElement(\"tr\");if(sel[d.id])r.className=\"sl\";r.innerHTML=\"<td><span class=\\\"ck\"+(sel[d.id]?\" on\":\"\")+\"\\\">\"+(sel[d.id]?\"✓\":\"\")+\"</span></td><td><b>\"+d.name+\"</b></td><td>\"+d.email+\"</td><td>\"+d.role+\"</td><td><span class=\\\"bd \"+d.status+\"\\\">\"+d.status+\"</span></td><td>$\"+d.mrr+\"</td>\";r.firstChild.onclick=function(){if(sel[d.id])delete sel[d.id];else sel[d.id]=1;draw()};tb.appendChild(r)})}draw()})();",
        "react": "",
        "dependencies": [],
        "install": "",
        "licence_notice": ""
    }
}