Skip to main content

Editable Table Ready

Editable Table is a functional component for enhancing tabular data with editable possibilities. It is based upon duet-table but is intended to take a Javascript Map of Records and map them into grouped sections

It’s important to understand that this component only give you the tools to represent a map in a visual way, and connect various "actions" to each line item. What the line item is and which actions you choose to run are your decisions, any action given results an event that contains information about what action was clicked/pressed and which line item it originated from. The rest of any logic will have to be provided by you.

Examples #

Open in new window
<style>
.duet-table-action-row.content-editable td:not(:last-child) {
border: 1px solid red;
}

.example-menu {
text-align: right;
}

.example-menu ul {
padding: 0 1rem;
}

.example-menu li {
display: inline-block;
list-style: none;
border-left: 1px solid #ccc;
padding: 0 1rem;
}
</style>
<duet-layout center>
<div slot="main">
<duet-card>
<duet-heading level="h1" visual-level="h3">Duet-editable-table simple version</duet-heading>

<duet-editable-table id="duet-editable-table_simple_table" margin="auto" sticky sticky-distance="none" variation="striped">
<div class="example-menu" slot="thead-first">
<div>
<ul role="menubar">
<li role="menuitem">
<duet-button
accessible-label="Download the table as a CSV file"
fixed
icon="action-download"
icon-size="medium"
margin="none"
padding="none"
variation="plain"
>

Download as CSV
</duet-button>
</li>
<li role="menuitem">
<duet-button
accessible-label="Copy the data to you Clipboard as csv"
fixed
icon="form-file"
icon-size="medium"
margin="none"
padding="none"
variation="plain"
>

copy
</duet-button>
</li>
</ul>
</div>
</div>
</duet-editable-table>
</duet-card>
</div>
</duet-layout>

<script>
(function (){
// Save a reference to the elements
const eTable = document.querySelector("#duet-editable-table_simple_table");


// defined actions - if this is not defined, the table will not have any actions
eTable.actions = [
{
"icon": "action-edit-2",
"color": "primary",
"name": "edit",
"size": "x-small",
"background": "gray-lightest",
"label": {
"fi": "Muokkaa luokkaa",
"en": "Edit category",
"sv": "Redigera kategori",
},
},
{
"icon": "action-delete",
"color": "danger",
"name": "delete",
"size": "x-small",
"background": "gray-lightest",
"label": {
"fi": "Poista",
"en": "Delete",
"sv": "Radera",
},
},
];

//defined columns, if this is set, rows must also be defined for this to have an affect
eTable.columns = [
{
sort_order: 1, direction: 1, index: 0, key: "name",
label: {
"fi": "Name",
"en": "Name",
"sv": "Name",
},
},
{
sort_order: 2, direction: -1, index: 1, key: "last_name",
label: {
"fi": "Last name",
"en": "Last name",
"sv": "Last name",
},
},
{
direction: 1, index: 2, key: "age",
label: {
"fi": "Age",
"en": "Age",
"sv": "Age",
},
},
{
direction: 1, index: 3, key: "hidden_age",
label: {
"fi": "hidden age",
"en": "hidden age",
"sv": "hidden age",
},
},
];

//defined rows, if this is set, columns must also be defined for this to have an affect
eTable.rows = [{
"name": "Jenn",
"last_name": "Woodburne",
"age": 65,
"hidden_age": 25,
"meta": {
"id": "1",
},
}, {
"name": "Symon",
"last_name": "Effemy",
"age": 91,
"hidden_age": 25,
"meta": {
"id": "2",
},
}, {
"name": "Shari",
"last_name": "Pattlel",
"age": 81,
"hidden_age": 25,
"meta": {
"id": "3",
},
}, {
"name": "Trudy",
"last_name": "MacRitchie",
"age": 56,
"hidden_age": 25,
"meta": {
"id": "4",
},
}, {
"name": "Dick",
"last_name": "Gorgen",
"age": 69,
"hidden_age": 25,
"meta": {
"id": "5",
},
}, {
"name": "Pia",
"last_name": "Siemens",
"age": 93,
"hidden_age": 25,
"meta": {
"id": "6",
},
}, {
"name": "Fred",
"last_name": "Baslter",
"age": 78,
"hidden_age": 25,
"meta": {
"id": "7",
},
}, {
"name": "Fred",
"last_name": "Alster",
"age": 54,
"hidden_age": 25,
"meta": {
"id": "8",
},
}, {
"name": "Mair",
"last_name": "Camier",
"age": 76,
"hidden_age": 25,
"meta": {
"id": "9",
},
}, {
"name": "Meade",
"last_name": "Hansana",
"age": 68,
"hidden_age": 25,
"meta": {
"id": "10",
},
}];


eTable.addEventListener("duetActionEvent", function(e) {

//quick demonstration of how to delete items from the rows array
console.log("Event received from duet-table: ", e.detail);
if (e.detail.action === "delete") {
eTable.rows = eTable.rows.map(item => item.meta.id !== e.detail.meta.id ? item : null).filter(item => item);
}
//quick demonstration of how to create the beginnings of a table with edit capabilities
if (e.detail.action === "edit") {
const currentRow = eTable.querySelectorAll("tbody tr")[e.detail.meta.index];
console.log(currentRow);
currentRow.contentEditable = true;
currentRow.classList.toggle("content-editable");
}
});
}())



</script>
Open in new window
<style>
.duet-table-action-row.content-editable td:not(:last-child) {
border: 1px solid red;
}

.example-menu {
text-align: right;
}

.example-menu ul {
padding: 0 1rem;
}

.example-menu li {
display: inline-block;
list-style: none;
border-left: 1px solid #ccc;
padding: 0 1rem;
}
</style>
<duet-layout center>
<div slot="main">
<duet-card>
<duet-heading level="h1" visual-level="h3">Duet-editable-table simple version</duet-heading>

<duet-editable-table id="duet-editable-table_simple_table_with_pagination" margin="auto" sticky sticky-distance="none" variation="striped">
<div class="example-menu" slot="thead-first">
<div>
<ul role="menubar">
<li role="menuitem">
<duet-button
accessible-label="Download the table as a CSV file"
fixed
icon="action-download"
icon-size="medium"
margin="none"
padding="none"
variation="plain"
>

Download as CSV
</duet-button>
</li>
<li role="menuitem">
<duet-button
accessible-label="Copy the data to you Clipboard as csv"
fixed
icon="form-file"
icon-size="medium"
margin="none"
padding="none"
variation="plain"
>

copy
</duet-button>
</li>
</ul>
</div>
</div>
<div class="pagination-advanced" slot="tfoot">
<style>
.pagination-advanced {
text-align: center;
margin: 0 auto;
text-align: center;
margin: 0 auto;
display: flex;
justify-content: space-evenly;
align-items: baseline;
}

@media only screen and (max-width: 48em) {
.pagination-advanced .pagination-menu {
display: block;
}

duet-range-stepper {
display: none;
}
}
</style>
<duet-pagination class="pagination-menu" total="500" visible-items="4"></duet-pagination>
<duet-range-stepper></duet-range-stepper>
</div>
</duet-editable-table>
</duet-card>
</div>
</duet-layout>

<script>
(function(){
// Save a reference to the elements
const eTable = document.querySelector("#duet-editable-table_simple_table_with_pagination");


// defined actions - if this is not defined, the table will not have any actions
eTable.actions = [
{
"icon": "action-edit-2",
"color": "primary",
"name": "edit",
"size": "x-small",
"background": "gray-lightest",
"label": {
"fi": "Muokkaa luokkaa",
"en": "Edit category",
"sv": "Redigera kategori",
},
},
{
"icon": "action-delete",
"color": "danger",
"name": "delete",
"size": "x-small",
"background": "gray-lightest",
"label": {
"fi": "Poista",
"en": "Delete",
"sv": "Radera",
},
},
];

//defined columns, if this is set, rows must also be defined for this to have an affect
eTable.columns = [
{
sort_order: 1, direction: 1, index: 0, key: "name",
label: {
"fi": "Name",
"en": "Name",
"sv": "Name",
},
},
{
sort_order: 2, direction: -1, index: 1, key: "last_name",
label: {
"fi": "Last name",
"en": "Last name",
"sv": "Last name",
},
},
{
direction: 1, index: 2, key: "age",
label: {
"fi": "Age",
"en": "Age",
"sv": "Age",
},
},
{
direction: 1, index: 3, key: "hidden_age",
label: {
"fi": "hidden age",
"en": "hidden age",
"sv": "hidden age",
},
},
];

//defined rows, if this is set, columns must also be defined for this to have an affect
eTable.rows = [{
"name": "Jenn",
"last_name": "Woodburne",
"age": 65,
"hidden_age": 25,
"meta": {
"id": "1",
},
}, {
"name": "Symon",
"last_name": "Effemy",
"age": 91,
"hidden_age": 25,
"meta": {
"id": "2",
},
}, {
"name": "Shari",
"last_name": "Pattlel",
"age": 81,
"hidden_age": 25,
"meta": {
"id": "3",
},
}, {
"name": "Trudy",
"last_name": "MacRitchie",
"age": 56,
"hidden_age": 25,
"meta": {
"id": "4",
},
}, {
"name": "Dick",
"last_name": "Gorgen",
"age": 69,
"hidden_age": 25,
"meta": {
"id": "5",
},
}, {
"name": "Pia",
"last_name": "Siemens",
"age": 93,
"hidden_age": 25,
"meta": {
"id": "6",
},
}, {
"name": "Fred",
"last_name": "Baslter",
"age": 78,
"hidden_age": 25,
"meta": {
"id": "7",
},
}, {
"name": "Fred",
"last_name": "Alster",
"age": 54,
"hidden_age": 25,
"meta": {
"id": "8",
},
}, {
"name": "Mair",
"last_name": "Camier",
"age": 76,
"hidden_age": 25,
"meta": {
"id": "9",
},
}, {
"name": "Meade",
"last_name": "Hansana",
"age": 68,
"hidden_age": 25,
"meta": {
"id": "10",
},
}];


eTable.addEventListener("duetActionEvent", function(e) {

//quick demonstration of how to delete items from the rows array
console.log("Event received from duet-table: ", e.detail);
if (e.detail.action === "delete") {
eTable.rows = eTable.rows.map(item => item.meta.id !== e.detail.meta.id ? item : null).filter(item => item);
}
});
}())
</script>
Open in new window
<style>
.duet-table-action-row.content-editable td:not(:last-child) {
border: 1px solid red;
}

.example-menu {
text-align: right;
}

.example-menu ul {
padding: 0 1rem;
}

.example-menu li {
display: inline-block;
list-style: none;
border-left: 1px solid #ccc;
padding: 0 1rem;
}
</style>
<duet-layout center>
<div slot="main">
<duet-card>
<form action="#" novalidate>
<duet-fieldset label="Editable-table header slot">
<duet-choice-group
direction="horizontal"
label="Check to enable a column"
name="group"
responsive
value="one"
>

<duet-checkbox checked data-key="name" label="Name"></duet-checkbox>
<duet-checkbox checked data-key="last_name" label="Last name"></duet-checkbox>
<duet-checkbox checked data-key="age" label="Age"></duet-checkbox>
<duet-checkbox data-key="hidden_age" label="Hidden age"></duet-checkbox>
</duet-choice-group>
</duet-fieldset>
</form>
<form action="#" novalidate>
<duet-fieldset label="Editable-table footer slot">
<duet-button id="flipit" variation="secondary"> Flip Column Order</duet-button>
</duet-fieldset>
</form>
</duet-card>
<duet-card>
<duet-heading level="h1" visual-level="h3">Duet-editable-table with inline actions</duet-heading>

<duet-editable-table id="duet-editable-table_table_with_actions_and_sorting" margin="auto" sortable sticky sticky-distance="none" variation="striped">
<div class="example-menu" slot="thead-first">
<div>
<ul role="menubar">
<li role="menuitem">
<duet-button
accessible-label="Download the table as a CSV file"
fixed
icon="action-download"
icon-size="medium"
margin="none"
padding="none"
variation="plain"
>

Download as CSV
</duet-button>
</li>
<li role="menuitem">
<duet-button
accessible-label="Copy the data to you Clipboard as csv"
fixed
icon="form-file"
icon-size="medium"
margin="none"
padding="none"
variation="plain"
>

copy
</duet-button>
</li>
</ul>
</div>
</div>
</duet-editable-table>
</duet-card>
</div>
</duet-layout>

<script>
(function(){
// Save a reference to the elements
const flipit = document.querySelector("#flipit");
const eTable = document.querySelector("#duet-editable-table_table_with_actions_and_sorting");
const form = document.querySelectorAll("duet-checkbox");
const columnSelector = document.querySelectorAll("duet-checkbox");

// Listen for change events in the select
flipit.addEventListener("click", function(e) {

eTable.columns = eTable.columns.reverse().map((item, index) => {
item.index = index;
return item;
});


});

// defined actions - if this is not defined, the table will not have any actions
eTable.actions = [
{
"icon": "action-edit-2",
"color": "primary",
"name": "edit",
"size": "x-small",
"background": "gray-lightest",
"label": {
"fi": "Muokkaa luokkaa",
"en": "Edit category",
"sv": "Redigera kategori",
},
},
{
"icon": "action-delete",
"color": "danger",
"name": "delete",
"size": "x-small",
"background": "gray-lightest",
"label": {
"fi": "Poista",
"en": "Delete",
"sv": "Radera",
},
},
];

//defined columns, if this is set, rows must also be defined for this to have an affect
eTable.columns = [
{
sort_order: 1, direction: 1, index: 0, key: "name",
label: {
"fi": "Name",
"en": "Name",
"sv": "Name",
},
},
{
sort_order: 2, direction: -1, index: 1, key: "last_name",
label: {
"fi": "Last name",
"en": "Last name",
"sv": "Last name",
},
},
{
direction: 1, index: 2, key: "age",
label: {
"fi": "Age",
"en": "Age",
"sv": "Age",
},
},
{
direction: 1, index: 3, key: "hidden_age", display: false,
label: {
"fi": "hidden age",
"en": "hidden age",
"sv": "hidden age",
},
},
];

//defined rows, if this is set, columns must also be defined for this to have an affect
eTable.rows = [{
"name": "Jenn",
"last_name": "Woodburne",
"age": 65,
"hidden_age": 25,
"meta": {
"id": "1",
},
}, {
"name": "Symon",
"last_name": "Effemy",
"age": 91,
"hidden_age": 25,
"meta": {
"id": "2",
},
}, {
"name": "Shari",
"last_name": "Pattlel",
"age": 81,
"hidden_age": 25,
"meta": {
"id": "3",
},
}, {
"name": "Trudy",
"last_name": "MacRitchie",
"age": 56,
"hidden_age": 25,
"meta": {
"id": "4",
},
}, {
"name": "Dick",
"last_name": "Gorgen",
"age": 69,
"hidden_age": 25,
"meta": {
"id": "5",
},
}, {
"name": "Pia",
"last_name": "Siemens",
"age": 93,
"hidden_age": 25,
"meta": {
"id": "6",
},
}, {
"name": "Fred",
"last_name": "Baslter",
"age": 78,
"hidden_age": 25,
"meta": {
"id": "7",
},
}, {
"name": "Fred",
"last_name": "Alster",
"age": 54,
"hidden_age": 25,
"meta": {
"id": "8",
},
}, {
"name": "Mair",
"last_name": "Camier",
"age": 76,
"hidden_age": 25,
"meta": {
"id": "9",
},
}, {
"name": "Meade",
"last_name": "Hansana",
"age": 68,
"hidden_age": 25,
"meta": {
"id": "10",
},
}];

// function that sorts an array (in this case table.rows) by columns in descending order

function fieldSorter(fields) {
return function(a, b) {
return fields
.map(function(o) {
let dir = 1;
if (o[0] === "-") {
dir = -1;
o = o.substring(1);
}
if (a[o] > b[o]) return dir;
if (a[o] < b[o]) return -(dir);
return 0;
})
.reduce(function firstNonZeroValue(p, n) {
return p ? p : n;
}, 0);
};
}

//change the sort order of a specific column
function setSortOrder({ order, direction, index, column }) {
const newArray = eTable.columns.map((item) => {
if (item.key === column) {
// set sort_order to 0, which is ignored in the component as undefined
item.sort_order = 0;
// flip direction asc->desc and desc->asc
item.direction = item.direction === -1 ? 1 : -1;
}
return item;
})
// sort the array by sort_order thereby getting a 0,1,3,4,x sequence
.sort(fieldSorter(["sort_order"]))
// reset that sequence to a 1,2,3,4 situation and ignore anything where sort order was not defined
.map((item, i) => {
if (item.sort_order || item.sort_order === 0) {
item.sort_order = i + 1;
}
return item;
});

eTable.columns = newArray;

}


// Listen for toggle events
eTable.addEventListener("duetTableToggle", function(e) {
console.log("Event received from duet-table: ", e.detail);
setSortOrder({
order: e.detail.sort_order,
direction: e.detail.direction,
index: e.detail.index,
column: e.detail.key,
});
});


eTable.addEventListener("duetActionEvent", function(e) {

//quick demonstration of how to delete items from the rows array
console.log("Event received from duet-table: ", e.detail);
if (e.detail.action === "delete") {
eTable.rows = eTable.rows.map(item => item.meta.id !== e.detail.meta.id ? item : null).filter(item => item);
}
});

form.forEach(item => {
item.addEventListener("duetChange", function(e) {
const target = e.target.getAttribute("data-key");
const state = e.detail.checked;

eTable.columns = eTable.columns.map((item) => {
if (item.key === target) {
item.display = state;
}
return item;
});
});
});
}())
</script>
Open in new window
<style>
.duet-table-action-row.content-editable td:not(:last-child) {
border: 1px solid red;
}
.menu-items {
position: absolute;
z-index: 999;
right: 0px;
top: 0px;
background-color: #fff;
box-shadow: 0 3px 10px rgb(0 0 0 / 0.2);
padding: 0;
margin: 0;
}
.menu-items li {
list-style: none;
border-bottom: 1px solid #ccc;
padding: 0.5rem 1.5rem 0;
}
.menu-items.menu-items-hidden {
display: none;
}

#popout-menu-button {
position: absolute;
right: 0;
top: -60px;
z-index: 999;
}
</style>

<duet-layout center>
<div slot="main">
<duet-card>
<duet-heading level="h1" visual-level="h3">Duet-editable-table simple version</duet-heading>

<duet-editable-table id="duet-editable-table_table_with_dot_menu" margin="auto" sticky sticky-distance="none" variation="striped">
<div class="example-popover" slot="thead-last">
<div class="duet-table-dot-menu">
<duet-button
variation="plain"
id="popout-menu-button"
accessible-expanded="false"
accesible-popup="true"
accessible-label="Popout menu with actions"
accessible-controls="popout-menu"
center-text
onclick="(e)=>doAction(e)"
>
...
</duet-button>
<ul
id="popout-menu"
role="menu"
aria-labelledby="popout-menu-button"
class="menu-items menu-items-hidden"
>

<li role="menuitem">
<duet-button variation="plain" icon="navigation-arrow-left"> Action 1 </duet-button>
</li>
<li role="menuitem">
<duet-button variation="plain" icon="navigation-arrow-left"> Action 2 </duet-button>
</li>
<li role="menuitem">
<duet-button variation="plain" icon="navigation-arrow-left"> Action 3 </duet-button>
</li>
<li role="menuitem">
<duet-button variation="plain" icon="navigation-arrow-left"> Action 4 </duet-button>
</li>
</ul>
</div>
</div>
</duet-editable-table>
</duet-card>
</div>
</duet-layout>

<script>
(function(){
// Save a reference to the elements
const eTable = document.querySelector("#duet-editable-table_table_with_dot_menu");


// defined actions - if this is not defined, the table will not have any actions
eTable.actions = [
{
"icon": "action-edit-2",
"color": "primary",
"name": "edit",
"size": "x-small",
"background": "gray-lightest",
"label": {
"fi": "Muokkaa luokkaa",
"en": "Edit category",
"sv": "Redigera kategori",
},
},
{
"icon": "action-delete",
"color": "danger",
"name": "delete",
"size": "x-small",
"background": "gray-lightest",
"label": {
"fi": "Poista",
"en": "Delete",
"sv": "Radera",
},
},
];

//defined columns, if this is set, rows must also be defined for this to have an affect
eTable.columns = [
{
sort_order: 1, direction: 1, index: 0, key: "name",
label: {
"fi": "Name",
"en": "Name",
"sv": "Name",
},
},
{
sort_order: 2, direction: -1, index: 1, key: "last_name",
label: {
"fi": "Last name",
"en": "Last name",
"sv": "Last name",
},
},
{
direction: 1, index: 2, key: "age",
label: {
"fi": "Age",
"en": "Age",
"sv": "Age",
},
},
{
direction: 1, index: 3, key: "hidden_age",
label: {
"fi": "hidden age",
"en": "hidden age",
"sv": "hidden age",
},
},
];

//defined rows, if this is set, columns must also be defined for this to have an affect
eTable.rows = [{
"name": "Jenn",
"last_name": "Woodburne",
"age": 65,
"hidden_age": 25,
"meta": {
"id": "1",
},
}, {
"name": "Symon",
"last_name": "Effemy",
"age": 91,
"hidden_age": 25,
"meta": {
"id": "2",
},
}, {
"name": "Shari",
"last_name": "Pattlel",
"age": 81,
"hidden_age": 25,
"meta": {
"id": "3",
},
}, {
"name": "Trudy",
"last_name": "MacRitchie",
"age": 56,
"hidden_age": 25,
"meta": {
"id": "4",
},
}, {
"name": "Dick",
"last_name": "Gorgen",
"age": 69,
"hidden_age": 25,
"meta": {
"id": "5",
},
}, {
"name": "Pia",
"last_name": "Siemens",
"age": 93,
"hidden_age": 25,
"meta": {
"id": "6",
},
}, {
"name": "Fred",
"last_name": "Baslter",
"age": 78,
"hidden_age": 25,
"meta": {
"id": "7",
},
}, {
"name": "Fred",
"last_name": "Alster",
"age": 54,
"hidden_age": 25,
"meta": {
"id": "8",
},
}, {
"name": "Mair",
"last_name": "Camier",
"age": 76,
"hidden_age": 25,
"meta": {
"id": "9",
},
}, {
"name": "Meade",
"last_name": "Hansana",
"age": 68,
"hidden_age": 25,
"meta": {
"id": "10",
},
}];


eTable.addEventListener("duetActionEvent", function(e) {

//quick demonstration of how to delete items from the rows array
console.log("Event received from duet-table: ", e.detail);
if (e.detail.action === "delete") {
eTable.rows = eTable.rows.map(item => item.meta.id !== e.detail.meta.id ? item : null).filter(item => item);
}
//quick demonstration of how to create the beginnings of a table with edit capabilities
if (e.detail.action === "edit") {
const currentRow = eTable.querySelectorAll("tbody tr")[e.detail.meta.index];
console.log(currentRow);
currentRow.contentEditable = true;
currentRow.classList.toggle("content-editable");
}
});

// menu items demonstration scripting
// Select the above button
const button = document.querySelector("#popout-menu-button")
const menuItems = document.querySelector("#popout-menu");

// Listen for clicks in the button
button.addEventListener("click", function (e) {
console.log("Button clicked", e)
menuItems.classList.toggle("menu-items-hidden");
})
}())
</script>

Properties #

Property Attribute Description Type Default
accessibleRole accessible-role Exposes the aria role for optimizing accessibility. string undefined
actions -- Define actions for all items in a table An alternative to inline HTML table. required for Sortable tables { icon: string; color: string; background: string; size: DuetActionButtonIconSize; name: string; map?: string[]; label?: DuetLangObject; }[] undefined
breakpoint breakpoint Duet-table: By default the table is responsive - it will be flattened at narrow viewport widths. This prop controls the breakpoint at which the table should be rendered as a regular table. Set to "none" to disable the responsive functionality. Set to "none-scrollable" to disable responsive functionality and allow horizontal scrolling - this is useful for comparison tables where it's important to maintain column and row layout. "large" | "medium" | "none" | "none-scrollable" | "small" | "x-large" | "x-small" | "xx-large" | "xx-small" | "xxx-large" | "xxx-small" "small"
columns -- Define columns for a table An alternative to inline HTML table. required for Sortable tables DuetEditableTableColumn[] undefined
groupId group-id Optional id that get passed to the table and used to setup ::parts string ""
hideHeadVisually hide-head-visually Hide a thead section visually. The content is still available to screen readers. boolean false
margin margin Duet-table: margin of the component. "auto" | "none" "auto"
rows -- Define rows for a table An alternative to inline HTML table. required for Sortable tables Record<string, any>[] undefined
sortable sortable Controls whether the table is sortable by headers boolean false
sticky sticky Duet-table: Controls whether the table has a sticky header. Sticky headers are not compatible with breakpoint="none-scrollable". boolean false
stickyDistance sticky-distance Duet-table: Adjust the distance from top of the viewport (in pixels) when the table header becomes sticky. "none" | "with-links" | "without-links" "with-links"
theme theme Theme of the table. "" | "default" | "turva" ""
variation variation Duet-table: Style variation of the table. "fixed" | "plain" | "striped" "striped"

Events #

Event Description Type
duetMenuClick Event emitted when table is sortable and a header item is clicked/enter is pressed CustomEvent<{ component: "duet-editable-table"; originalEvent: KeyboardEvent | MouseEvent; }>
duetTableToggle Event emitted when table is sortable and a header item is clicked/enter is pressed CustomEvent<{ component: "duet-editable-table"; sort_order?: number; direction: 1 | -1; index: number; key: string; originalEvent: KeyboardEvent | MouseEvent; }>

Usage #

This section includes guidelines for designers and developers about the usage of this component in different contexts.

The component is automatically Theme aware, and will try to add the given theme to any colors set in actions.

When to use #

  • When you need to display tabular data with actions associated with them.
  • When you want the user to be able to interact with each line item.

When not to use #

  • To display name/value pairs such as terms and definitions. Use list component instead.
  • To display a glossary list. Use list component instead.

Accessibility #

This component has been validated to meet the WCAG 2.1 AA accessibility guidelines. You can find additional information regarding accessibility of this component below.


Integration

For integration, event and theming guidelines, please see Using Components. This documentation explains how to implement and use Duet’s components across different technologies like Angular, React or Vanilla JavaScript.

Integration guidelines


Tutorials

Follow these practical tutorials to learn how to build simple page layouts using Duet’s CSS Framework, Web Components and other features:

Tutorials

Building Layouts

Tutorials

Using CLI Tools

Tutorials

Creating Custom Patterns

Tutorials

Server Side Rendering

Tutorials

Sharing Prototypes

Tutorials

Usage With Markdown


Troubleshooting

If you experience any issues while using a component, please head over to the Support page for more guidelines and help.