A versatile table/datagrid component with built-in keyboard navigation for displaying and interacting with structured data. Use it for anything from simple read-only tables to fully interactive, spreadsheet experiences.
<nve-page>
<nve-grid>
<nve-grid-header>
<nve-grid-column>Column 1</nve-grid-column>
<nve-grid-column>Column 2</nve-grid-column>
<nve-grid-column>Column 3</nve-grid-column>
<nve-grid-column width="max-content" aria-label="details"></nve-grid-column>
</nve-grid-header>
<nve-grid-row>
<nve-grid-cell>Cell 1-1</nve-grid-cell>
<nve-grid-cell>Cell 1-2</nve-grid-cell>
<nve-grid-cell>Cell 1-3</nve-grid-cell>
<nve-grid-cell>
<nve-icon-button container="flat" icon-name="additional-actions" aria-label="view item 1"></nve-icon-button>
</nve-grid-cell>
</nve-grid-row>
</nve-grid>
<nve-page-panel slot="right" size="sm" expanded closable>
...
</nve-page-panel>
</nve-page>
Use a nve-page-panel when displaying advanced filtering or display settings for the grid. Item detail panels should be open using a action button placed at the end of the grid row.
<nve-page id="grid-panel-demo">
<nve-page-header slot="header">
<nve-logo slot="prefix" size="sm" color="brand-green">NV</nve-logo>
<h2 nve-text="heading" slot="prefix">Infrastructure</h2>
</nve-page-header>
<section nve-layout="column gap:md pad:md full">
<nve-grid>
<nve-grid-header>
<nve-grid-column>column 0</nve-grid-column> <nve-grid-column>column 1</nve-grid-column>
<nve-grid-column>column 2</nve-grid-column>
<nve-grid-column width="max-content" aria-label="details"></nve-grid-column>
</nve-grid-header>
<nve-grid-row>
<nve-grid-cell>cell 0-0</nve-grid-cell> <nve-grid-cell>cell 0-1</nve-grid-cell>
<nve-grid-cell>cell 0-2</nve-grid-cell>
<nve-grid-cell>
<nve-icon-button container="flat" icon-name="expand-details" value="0" aria-label="view 0"></nve-icon-button>
</nve-grid-cell>
</nve-grid-row>
<nve-grid-row selected>
<nve-grid-cell>cell 1-0</nve-grid-cell> <nve-grid-cell>cell 1-1</nve-grid-cell>
<nve-grid-cell>cell 1-2</nve-grid-cell>
<nve-grid-cell>
<nve-icon-button container="flat" icon-name="expand-details" value="1" aria-label="view 1"></nve-icon-button>
</nve-grid-cell>
</nve-grid-row>
<nve-grid-row>
<nve-grid-cell>cell 2-0</nve-grid-cell> <nve-grid-cell>cell 2-1</nve-grid-cell>
<nve-grid-cell>cell 2-2</nve-grid-cell>
<nve-grid-cell>
<nve-icon-button container="flat" icon-name="expand-details" value="2" aria-label="view 2"></nve-icon-button>
</nve-grid-cell>
</nve-grid-row>
<nve-grid-row>
<nve-grid-cell>cell 3-0</nve-grid-cell> <nve-grid-cell>cell 3-1</nve-grid-cell>
<nve-grid-cell>cell 3-2</nve-grid-cell>
<nve-grid-cell>
<nve-icon-button container="flat" icon-name="expand-details" value="3" aria-label="view 3"></nve-icon-button>
</nve-grid-cell>
</nve-grid-row>
<nve-grid-row>
<nve-grid-cell>cell 4-0</nve-grid-cell> <nve-grid-cell>cell 4-1</nve-grid-cell>
<nve-grid-cell>cell 4-2</nve-grid-cell>
<nve-grid-cell>
<nve-icon-button container="flat" icon-name="expand-details" value="4" aria-label="view 4"></nve-icon-button>
</nve-grid-cell>
</nve-grid-row>
<nve-grid-row>
<nve-grid-cell>cell 5-0</nve-grid-cell> <nve-grid-cell>cell 5-1</nve-grid-cell>
<nve-grid-cell>cell 5-2</nve-grid-cell>
<nve-grid-cell>
<nve-icon-button container="flat" icon-name="expand-details" value="5" aria-label="view 5"></nve-icon-button>
</nve-grid-cell>
</nve-grid-row>
<nve-grid-row>
<nve-grid-cell>cell 6-0</nve-grid-cell> <nve-grid-cell>cell 6-1</nve-grid-cell>
<nve-grid-cell>cell 6-2</nve-grid-cell>
<nve-grid-cell>
<nve-icon-button container="flat" icon-name="expand-details" value="6" aria-label="view 6"></nve-icon-button>
</nve-grid-cell>
</nve-grid-row>
<nve-grid-row>
<nve-grid-cell>cell 7-0</nve-grid-cell> <nve-grid-cell>cell 7-1</nve-grid-cell>
<nve-grid-cell>cell 7-2</nve-grid-cell>
<nve-grid-cell>
<nve-icon-button container="flat" icon-name="expand-details" value="7" aria-label="view 7"></nve-icon-button>
</nve-grid-cell>
</nve-grid-row>
<nve-grid-row>
<nve-grid-cell>cell 8-0</nve-grid-cell> <nve-grid-cell>cell 8-1</nve-grid-cell>
<nve-grid-cell>cell 8-2</nve-grid-cell>
<nve-grid-cell>
<nve-icon-button container="flat" icon-name="expand-details" value="8" aria-label="view 8"></nve-icon-button>
</nve-grid-cell>
</nve-grid-row>
<nve-grid-row>
<nve-grid-cell>cell 9-0</nve-grid-cell> <nve-grid-cell>cell 9-1</nve-grid-cell>
<nve-grid-cell>cell 9-2</nve-grid-cell>
<nve-grid-cell>
<nve-icon-button container="flat" icon-name="expand-details" value="9" aria-label="view 9"></nve-icon-button>
</nve-grid-cell>
</nve-grid-row>
</nve-grid>
</section>
<nve-page-panel slot="right" size="sm" expanded closable>
<nve-page-panel-header>
<h3 nve-text="heading medium sm">Row 2 Details</h3>
</nve-page-panel-header>
<nve-page-panel-content>
<div nve-layout="column gap:md">
<div nve-layout="column gap:xs">
<label nve-text="body sm muted">Task</label>
<p nve-text="label sm">Workflow</p>
</div>
<div nve-layout="column gap:xs">
<label nve-text="body sm muted">Status</label>
<nve-badge status="success">Complete</nve-badge>
</div>
<div nve-layout="column gap:xs">
<label nve-text="body sm muted">Priority</label>
<nve-badge status="pending">P1</nve-badge>
</div>
</div>
</nve-page-panel-content>
</nve-page-panel>
</nve-page>
<script type="module">
const page = document.getElementById("grid-panel-demo");
const grid = page.querySelector("nve-grid");
const panel = page.querySelector("nve-page-panel");
const rows = grid.querySelectorAll("nve-grid-row");
const heading = page.querySelector("nve-page-panel-header h3");
panel.addEventListener("close", () => {
rows.forEach((row) => (row.selected = false));
panel.hidden = true;
});
grid.addEventListener("click", (e) => {
if (e.target.localName === "nve-icon-button") {
const row = e.target.closest("nve-grid-row");
rows.forEach((row) => (row.selected = false));
panel.hidden = false;
heading.textContent = "Row " + e.target.value + " Details";
row.selected = !panel.hidden;
}
});
</script>
NV
Infrastructure
column 0 column 1
column 2
cell 0-0 cell 0-1
cell 0-2
cell 1-0 cell 1-1
cell 1-2
cell 2-0 cell 2-1
cell 2-2
cell 3-0 cell 3-1
cell 3-2
cell 4-0 cell 4-1
cell 4-2
cell 5-0 cell 5-1
cell 5-2
cell 6-0 cell 6-1
cell 6-2
cell 7-0 cell 7-1
cell 7-2
cell 8-0 cell 8-1
cell 8-2
cell 9-0 cell 9-1
cell 9-2
Row 2 Details
Status
Complete
Priority
P1