Liveweave: Generative AI Web Editor & HTML/CSS/JS Playground
Initializing
Liveweave
Web
expand_more
home
Home
Palette
Color Explorer
arrow_outward
Polyline
Graphics Editor
arrow_outward
frame_source
Python Playground
arrow_outward
build
Tools
expand_more
restart_alt
Load "Hello Weaver!"
post_add
Generate Lorem ipsum...
code
Format HTML
code_blocks
Format CSS
data_object
Format JavaScript
library_add
Library
expand_more
A
Algolia JS
Animate CSS
Apex Charts JS
B
Bulma CSS
Bootstrap
C
Chart JS
Chartist
Create JS
D
D3
Dojo
F
Foundation
Fullpage JS
G
Granim JS
Google Charts
H
Halfmoon
J
jQuery
M
Materialize
Moment JS
Masonry JS
Milligram CSS
P
Pure CSS
Primer CSS
Popper JS
Pattern CSS
Picnic CSS
R
React JS
Raphael JS
Raisin CSS
S
Semantic UI
Skeleton CSS
Spectre CSS
Tachyons CSS
T
Tailwind
Three JS
U
UI Kit
Vis JS
W
Water CSS
download
Download
expand_more
developer_mode
Download as HTML
folder_zip
Download as .ZIP
cloud_upload
Fork
account_circle
Login
settings
Settings
expand_more
Editor font
14
px
A
A
Line number
Mini map
Word wrap
sync_alt
Reset Settings
smart_display
Run
left_panel_close
AI Assistant
dashboard
All
HTML
CSS
JS
visibility
Preview
bolt
Live Preview
terminal
JS Console
<link href="https://unpkg.com/tabulator-tables@6.5.0/dist/css/tabulator.min.css" rel="stylesheet" /> <div class="app"> <div class="table-card"> <div class="table-header"> <div> <span class="eyebrow">CUSTOMERS</span> <h1>Customer Directory</h1> <p> Manage customers, subscriptions and account activity. </p> </div> <button id="addCustomer" class="primary-button"> + Add customer </button> </div> <div class="toolbar"> <div class="search-box"> <span class="search-icon">⌕</span> <input id="searchInput" type="text" placeholder="Search customers..." /> </div> <div class="toolbar-actions"> <select id="statusFilter"> <option value=""> All statuses </option> <option value="Active"> Active </option> <option value="Trial"> Trial </option> <option value="Inactive"> Inactive </option> </select> <button id="exportButton" class="secondary-button"> Export CSV </button> </div> </div> <div class="selection-bar" id="selectionBar"> <span> <strong id="selectedCount">0</strong> customers selected </span> <button id="clearSelection"> Clear </button> </div> <div id="customerTable"></div> <div class="table-footer"> <div class="records"> <span class="live-dot"></span> <span id="recordCount">0 customers</span> </div> <span> Updated just now </span> </div> </div> </div> <script src="https://unpkg.com/tabulator-tables@6.5.0/dist/js/tabulator.min.js" ></script>
* { box-sizing: border-box; } :root { --background: #f6f7f9; --card: #ffffff; --text: #17181b; --muted: #737780; --border: #e8e9ed; --primary: #161719; --primary-hover: #2c2e32; } html, body { margin: 0; min-height: 100%; font-family: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; background: linear-gradient( 145deg, #f8f9fb, #f1f2f5 ); color: var(--text); } /* PAGE */ .app { min-height: 100vh; padding: 55px 30px; } /* CARD */ .table-card { width: min(1180px, 100%); margin: auto; overflow: hidden; background: var(--card); border: 1px solid var(--border); border-radius: 18px; box-shadow: 0 18px 60px rgba(22, 28, 45, .07); } /* HEADER */ .table-header { display: flex; align-items: flex-start; justify-content: space-between; gap: 30px; padding: 27px 28px 23px; } .eyebrow { display: block; margin-bottom: 7px; color: #9a9da5; font-size: 10px; font-weight: 700; letter-spacing: 1.8px; } .table-header h1 { margin: 0; font-size: 24px; letter-spacing: -.7px; } .table-header p { margin: 7px 0 0; color: var(--muted); font-size: 12px; } /* BUTTONS */ .primary-button, .secondary-button { height: 38px; padding: 0 14px; border-radius: 8px; font-size: 12px; font-weight: 550; cursor: pointer; transition: background .15s, transform .15s, border-color .15s; } .primary-button { border: 1px solid var(--primary); background: var(--primary); color: white; } .primary-button:hover { background: var(--primary-hover); transform: translateY(-1px); } .secondary-button { border: 1px solid #dfe1e6; background: white; color: #36383d; } .secondary-button:hover { background: #f5f6f7; border-color: #cacdd3; } /* TOOLBAR */ .toolbar { display: flex; align-items: center; justify-content: space-between; gap: 15px; padding: 14px 28px; border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); background: #fbfbfc; } /* SEARCH */ .search-box { width: min(330px, 100%); height: 38px; display: flex; align-items: center; gap: 9px; padding: 0 11px; background: white; border: 1px solid #dfe1e5; border-radius: 8px; } .search-box:focus-within { border-color: #a9abb0; box-shadow: 0 0 0 3px rgba(0,0,0,.04); } .search-icon { color: #9da0a7; font-size: 17px; } .search-box input { flex: 1; min-width: 0; border: 0; outline: 0; background: transparent; font-size: 12px; color: #1d1e21; } .search-box input::placeholder { color: #a8aab0; } /* TOOLBAR ACTIONS */ .toolbar-actions { display: flex; gap: 8px; } .toolbar select { height: 38px; padding: 0 32px 0 11px; border: 1px solid #dfe1e5; border-radius: 8px; background: white; color: #3e4045; outline: none; font-size: 12px; cursor: pointer; } /* SELECTION */ .selection-bar { display: none; align-items: center; justify-content: space-between; padding: 10px 28px; background: #f4f2ff; border-bottom: 1px solid #e7e2ff; color: #6255b8; font-size: 11px; } .selection-bar.visible { display: flex; } .selection-bar button { border: 0; background: transparent; color: #6255b8; font-size: 11px; font-weight: 600; cursor: pointer; } /* TABULATOR */ #customerTable { border: 0; } /* TABLE BODY */ .tabulator { border: 0; background: white; font-family: inherit; font-size: 12px; } /* COLUMN HEADERS */ .tabulator .tabulator-header { border-bottom: 1px solid var(--border); background: #fafafb; color: #777a82; } .tabulator .tabulator-header .tabulator-col { min-height: 42px; border-right: 0; background: transparent; } .tabulator .tabulator-header .tabulator-col:hover { background: #f3f4f6; } .tabulator-col-title { font-size: 10px; font-weight: 650; letter-spacing: .45px; text-transform: uppercase; } /* ROW */ .tabulator-row { min-height: 62px; border-bottom: 1px solid #f0f1f3; background: white; transition: background .15s; } .tabulator-row:hover { background: #fafafb; } .tabulator-row.tabulator-selected { background: #f7f5ff; } .tabulator-row .tabulator-cell { display: flex; align-items: center; border-right: 0; padding: 10px 12px; } /* CHECKBOX */ .tabulator input[type="checkbox"] { width: 15px; height: 15px; accent-color: #17181b; cursor: pointer; } /* USER */ .user-cell { display: flex; align-items: center; gap: 11px; } .avatar { width: 35px; height: 35px; display: flex; align-items: center; justify-content: center; flex-shrink: 0; border-radius: 50%; background: linear-gradient( 145deg, #e7e9ee, #d7dae1 ); color: #52555c; font-size: 10px; font-weight: 700; } .user-info strong { display: block; color: #202125; font-size: 12px; font-weight: 600; } .user-info span { display: block; margin-top: 3px; color: #989ba2; font-size: 10px; } /* STATUS */ .status { display: inline-flex; align-items: center; gap: 5px; padding: 5px 8px; border-radius: 20px; font-size: 10px; font-weight: 550; } .status::before { content: ""; width: 5px; height: 5px; border-radius: 50%; background: currentColor; } .status-active { color: #168453; background: #edf9f3; } .status-trial { color: #8c6616; background: #fff8e7; } .status-inactive { color: #777b83; background: #f1f2f4; } /* PLAN */ .plan-badge { padding: 5px 8px; border: 1px solid #e2e3e7; border-radius: 6px; background: #fafafb; color: #55585f; font-size: 10px; } /* USAGE */ .usage { width: 100%; } .usage-top { display: flex; align-items: center; justify-content: space-between; margin-bottom: 5px; font-size: 9px; color: #81848b; } .usage-bar { width: 100%; height: 4px; overflow: hidden; border-radius: 10px; background: #eceef1; } .usage-fill { height: 100%; border-radius: inherit; background: linear-gradient( 90deg, #6558e8, #8c82ff ); } /* REVENUE */ .revenue { font-weight: 600; color: #313338; } /* ACTION */ .more-button { width: 30px; height: 30px; border: 1px solid transparent; border-radius: 7px; background: transparent; color: #777a81; font-size: 18px; cursor: pointer; } .more-button:hover { border-color: #e1e3e7; background: #f5f6f7; color: #202124; } /* PAGINATION */ .tabulator .tabulator-footer { padding: 13px 16px; border-top: 1px solid var(--border); background: #fafafb; } .tabulator .tabulator-footer .tabulator-page { min-width: 29px; height: 29px; margin: 0 2px; border: 1px solid #e0e2e5; border-radius: 6px; background: white; color: #62656c; } .tabulator .tabulator-footer .tabulator-page:hover { background: #f1f2f4; color: #202124; } .tabulator .tabulator-footer .tabulator-page.active { border-color: #1c1d20; background: #1c1d20; color: white; } /* FOOTER */ .table-footer { display: flex; align-items: center; justify-content: space-between; padding: 13px 28px; color: #999ca3; font-size: 10px; background: white; } .records { display: flex; align-items: center; gap: 7px; } .live-dot { width: 6px; height: 6px; border-radius: 50%; background: #35b978; box-shadow: 0 0 0 3px rgba(53,185,120,.12); } /* RESPONSIVE */ @media ( max-width: 700px ) { .app { padding: 20px 12px; } .table-header { padding: 20px; flex-direction: column; } .primary-button { width: 100%; } .toolbar { padding: 12px 20px; flex-direction: column; align-items: stretch; } .search-box { width: 100%; } .toolbar-actions { width: 100%; } .toolbar-actions select, .toolbar-actions button { flex: 1; } .table-footer { padding: 13px 20px; } }
const data = [ { id: 1, name: "Maya Patel", email: "maya@northstar.io", status: "Active", plan: "Business", usage: 82, revenue: 2490, joined: "Aug 18, 2026" }, { id: 2, name: "Daniel Kim", email: "daniel@frame.ai", status: "Active", plan: "Pro", usage: 64, revenue: 1290, joined: "Aug 12, 2026" }, { id: 3, name: "Sarah Chen", email: "sarah@vertexlabs.com", status: "Trial", plan: "Pro", usage: 38, revenue: 0, joined: "Sep 2, 2026" }, { id: 4, name: "Marcus Reed", email: "marcus@atlas.dev", status: "Inactive", plan: "Starter", usage: 12, revenue: 390, joined: "Jul 24, 2026" }, { id: 5, name: "Ava Thompson", email: "ava@luminous.co", status: "Active", plan: "Business", usage: 94, revenue: 3240, joined: "Jul 17, 2026" }, { id: 6, name: "Noah Williams", email: "noah@pixelworks.dev", status: "Active", plan: "Pro", usage: 72, revenue: 1440, joined: "Jun 29, 2026" }, { id: 7, name: "Sophia Martinez", email: "sophia@orbital.io", status: "Trial", plan: "Business", usage: 45, revenue: 0, joined: "Sep 6, 2026" }, { id: 8, name: "Ethan Brooks", email: "ethan@craftlab.com", status: "Active", plan: "Starter", usage: 58, revenue: 620, joined: "Jun 14, 2026" }, { id: 9, name: "Olivia Lee", email: "olivia@mono.studio", status: "Inactive", plan: "Pro", usage: 18, revenue: 870, joined: "May 27, 2026" }, { id: 10, name: "Liam Anderson", email: "liam@aperture.ai", status: "Active", plan: "Business", usage: 88, revenue: 2980, joined: "May 10, 2026" }, { id: 11, name: "Emma Wilson", email: "emma@north.co", status: "Active", plan: "Pro", usage: 69, revenue: 1680, joined: "Apr 22, 2026" }, { id: 12, name: "Lucas Garcia", email: "lucas@shift.dev", status: "Trial", plan: "Starter", usage: 31, revenue: 0, joined: "Sep 7, 2026" } ]; /* INITIALS */ function getInitials(name) { return name .split(" ") .map(function(word) { return word[0]; }) .join("") .slice(0, 2); } /* USER FORMATTER */ function userFormatter(cell) { const row = cell.getRow().getData(); return ` <div class="user-cell"> <div class="avatar"> ${getInitials(row.name)} </div> <div class="user-info"> <strong>${row.name}</strong> <span>${row.email}</span> </div> </div> `; } /* STATUS FORMATTER */ function statusFormatter(cell) { const value = cell.getValue(); const className = value .toLowerCase(); return ` <span class="status status-${className}" > ${value} </span> `; } /* PLAN */ function planFormatter(cell) { return ` <span class="plan-badge"> ${cell.getValue()} </span> `; } /* USAGE */ function usageFormatter(cell) { const value = cell.getValue(); return ` <div class="usage"> <div class="usage-top"> <span>Usage</span> <span>${value}%</span> </div> <div class="usage-bar"> <div class="usage-fill" style="width:${value}%" ></div> </div> </div> `; } /* REVENUE */ function revenueFormatter(cell) { const value = cell.getValue(); return ` <span class="revenue"> $${value.toLocaleString()} </span> `; } /* TABLE */ const table = new Tabulator( "#customerTable", { data: data, layout: "fitColumns", responsiveLayout: "collapse", selectableRows: true, pagination: true, paginationSize: 7, paginationSizeSelector: [7, 10, 20], movableColumns: true, columns: [ { formatter: "rowSelection", titleFormatter: "rowSelection", hozAlign: "center", headerSort: false, width: 45, responsive: 0 }, { title: "Customer", field: "name", formatter: userFormatter, minWidth: 220 }, { title: "Status", field: "status", formatter: statusFormatter, width: 110 }, { title: "Plan", field: "plan", formatter: planFormatter, width: 110 }, { title: "Usage", field: "usage", formatter: usageFormatter, sorter: "number", minWidth: 145 }, { title: "Revenue", field: "revenue", formatter: revenueFormatter, sorter: "number", width: 115 }, { title: "Joined", field: "joined", width: 125, responsive: 2 }, { title: "", formatter: function() { return ` <button class="more-button" > ⋯ </button> `; }, headerSort: false, width: 50, hozAlign: "center" } ] } ); /* RECORD COUNT */ document .getElementById( "recordCount" ) .textContent = data.length + " customers"; /* SEARCH */ const search = document.getElementById( "searchInput" ); search.addEventListener( "input", function() { const value = search.value.trim(); if (!value) { table.clearFilter(); applyStatusFilter(); return; } const status = document .getElementById( "statusFilter" ) .value; const filters = [ [ { field: "name", type: "like", value: value }, { field: "email", type: "like", value: value }, { field: "plan", type: "like", value: value } ] ]; if (status) { filters.push( { field: "status", type: "=", value: status } ); } table.setFilter( filters ); } ); /* STATUS FILTER */ const statusFilter = document.getElementById( "statusFilter" ); statusFilter.addEventListener( "change", applyStatusFilter ); function applyStatusFilter() { const status = statusFilter.value; const searchValue = search.value.trim(); table.clearFilter(); const filters = []; if (searchValue) { filters.push( [ { field: "name", type: "like", value: searchValue }, { field: "email", type: "like", value: searchValue } ] ); } if (status) { filters.push( { field: "status", type: "=", value: status } ); } if (filters.length) { table.setFilter( filters ); } } /* ROW SELECTION */ const selectionBar = document.getElementById( "selectionBar" ); const selectedCount = document.getElementById( "selectedCount" ); table.on( "rowSelectionChanged", function(data) { const count = data.length; selectedCount.textContent = count; selectionBar .classList .toggle( "visible", count > 0 ); } ); /* CLEAR SELECTION */ document .getElementById( "clearSelection" ) .addEventListener( "click", function() { table.deselectRow(); } ); /* EXPORT CSV */ document .getElementById( "exportButton" ) .addEventListener( "click", function() { table.download( "csv", "customers.csv" ); } ); /* ADD DEMO CUSTOMER */ document .getElementById( "addCustomer" ) .addEventListener( "click", function() { const id = Date.now(); table.addRow( { id: id, name: "New Customer", email: "customer@example.com", status: "Trial", plan: "Starter", usage: 10, revenue: 0, joined: "Sep 9, 2026" }, true ); const count = table.getDataCount(); document .getElementById( "recordCount" ) .textContent = count + " customers"; } );
terminal
JavaScript Console
Preview
Clear
close
›
Run