Here is an example of using the Flex Table in a plain html page:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<link href="https://developer.temenos.com/uux/base.css" rel="stylesheet" />
<script src="https://developer.temenos.com/uux/unified-ux-web.min.js"></script>
</head>
<body>
<uwc-flex-table></uwc-flex-table>
</body>
<script>
const recordData = [
{
firstName: "Sterling",
lastName: "Archer",
actor: "Harry Jon Benjamin",
tvSeries: "Archer"
},
{
firstName: "Malory",
lastName: "Archer",
actor: "Jessica Walter",
tvSeries: "Archer"
},
{
firstName: "Lana",
lastName: "Kane",
actor: "Aisha Tyler",
tvSeries: "Archer"
},
{
firstName: "Cheryl",
lastName: "Tunt",
actor: "Judy Greer",
tvSeries: "Archer"
},
{
firstName: "Algernop",
lastName: "Krieger",
actor: "Matt \"Lucky\" Yates",
tvSeries: "Archer"
},
{
firstName: "Pam",
lastName: "Poovey",
actor: "Amber Nash",
tvSeries: "Archer"
},
{
firstName: "Cyril",
lastName: "Figgis",
actor: "Chris Parnell",
tvSeries: "Archer"
},
{
firstName: "Ray",
lastName: "Gillette",
actor: "Adam Brooks Reed",
tvSeries: "Archer"
},
{
firstName: "Philip",
lastName: "Fry",
actor: "Billy West",
tvSeries: "Futurama"
},
{
firstName: "Leela",
lastName: "Turanga",
actor: "Katy Sagal",
tvSeries: "Futurama"
},
{
firstName: "Bender",
lastName: "Rodríguez",
actor: "John DiMaggio",
tvSeries: "Futurama"
},
{
firstName: "Hermes",
lastName: "Conrad",
actor: "Phil Lamar",
tvSeries: "Futurama"
},
{
firstName: "Hubert",
lastName: "Farnsworth",
actor: "Billy West",
tvSeries: "Futurama"
},
{
firstName: "John",
lastName: "Zoidberg",
actor: "Billy West",
tvSeries: "Futurama"
}
];
const tableSpec = {
columnSpecs: [
{
label: "First Name",
fieldName: "firstName",
horizontalAlignment: "end"
},
{
label: "Last Name",
fieldName: "lastName",
},
{
label: "Actor/Voice",
fieldName: "actor",
//cssWidthValue: "200px"
//horizontalAlignment: "center"
},
{
label: "TV series",
fieldName: "tvSeries",
horizontalAlignment: "center",
renderFieldValueAsAction: true
}
],
recordLevelActionSpecs: [
{
actionId: "viewProfile",
title: "View profile",
icon: "account_circle",
//iconColorOrCSSVarname: "--uwc-status-warn-dark",
presentationStyle: "icon"
},
{
actionId: "edit",
title: "Edit",
icon: "edit",
presentationStyle: "link"
},
{
actionId: "sendFlowers",
title: "Send flowers",
presentationStyle: "menu"
},
{
actionId: "sendDinnerInvitation",
title: "Invite to dinner",
presentationStyle: "menu"
},
{
actionId: "sendMarriageProposal",
title: "Propose marriage",
presentationStyle: "menu"
}
],
dataRecords: recordData
};
document.querySelector("uwc-flex-table").tableSpec = tableSpec;
</script>
</html>

For reference, here's the JavaScript source of the genCharismaIconSpec() (and supporting) function(s) referenced as the value of the (optional) dataCellIconSpecGenerator property in the tableSpec.columnSpecs[] element for the "charisma" column in the With "charisma" values rendered as icons and With "charisma" values rendered as (field-level-action) icon buttons examples in the Live Demo below:

/**
* Copied verbatim from demos\flex-table\index.html, this function is referenced as the value of the (optional)
* dataCellIconSpecGenerator property in the tableSpec.columnSpecs[] element for the "charisma" column for the
* 'With "charisma" values rendered as icons' and 'With "charisma" values rendered as (field-level-action) icon buttons'
* examples.
*/
function genCharismaIconSpec(dataRecord) {
const { charisma } = dataRecord;
if (charisma >= 90) return {
icon: "local_fire_department",
iconColorOrCSSVarname: "yellow",
tooltip: genEffectiveIconTooltip({ lookupKey: "table.charismaIconTooltips.incandescent", defaultValue: "Incandescent !"}),
sortKey: genEffectiveIconSortKey("Z")
};
if (charisma >= 80) return {
icon: "local_fire_department",
iconColorOrCSSVarname: "red",
tooltip: genEffectiveIconTooltip({ lookupKey: "table.charismaIconTooltips.prettyDamnHot", defaultValue: "Pretty damn hot !" }),
sortKey: genEffectiveIconSortKey("Y")
};
if (charisma >= 70) return {
icon: "local_fire_department",
iconColorOrCSSVarname: "orange",
tooltip: genEffectiveIconTooltip({ lookupKey: "table.charismaIconTooltips.smouldering", defaultValue: "Smouldering" }),
sortKey: genEffectiveIconSortKey("X")
};
if (charisma >= 60) return {
icon: "flourescent",
iconColorOrCSSVarname: "greenyellow",
tooltip: genEffectiveIconTooltip({ lookupKey: "table.charismaIconTooltips.lightWithoutHeat", defaultValue: "Somewhat witty" }),
sortKey: genEffectiveIconSortKey("W")
};
if (charisma >= 50) return {
icon: "emoji_objects",
iconColorOrCSSVarname: "--uwc-status-warn-primary",
tooltip: genEffectiveIconTooltip({ lookupKey: "table.charismaIconTooltips.lowWattageBulb", defaultValue: "Not entirely dim" }),
sortKey: genEffectiveIconSortKey("V")
};
if (charisma >= 40) return {
icon: "light",
iconColorOrCSSVarname: "--uwc-status-warn-dark",
tooltip: genEffectiveIconTooltip({ lookupKey: "table.charismaIconTooltips.shadedLowWattageLightBulb", defaultValue: "Generally dull" }),
sortKey: genEffectiveIconSortKey("U")
}
if (charisma >= 30) return {
icon: "sentiment_neutral",
tooltip: genEffectiveIconTooltip({ lookupKey: "table.charismaIconTooltips.charismaVacuum", defaultValue: "Charisma vaccum" }),
sortKey: genEffectiveIconSortKey("T")
}
if (charisma >= 10) return {
icon: "question_mark",
tooltip: genEffectiveIconTooltip({ lookupKey: "table.charismaIconTooltips.nonEntity", defaultValue: "Non entity" }),
sortKey: genEffectiveIconSortKey("S")
}
if (charisma >= 10) return {
icon: "trending_down",
tooltip: genEffectiveIconTooltip({ lookupKey: "table.charismaIconTooltips.barelyAlive", defaultValue: "Barely alive" }),
sortKey: genEffectiveIconSortKey("R")
}
return {
icon: "warning",
iconColorOrCSSVarname: "blue",
tooltip: genEffectiveIconTooltip({ lookupKey: "table.charismaIconTooltips.totallyBoring", defaultValue: "Totally boring" }),
sortKey: genEffectiveIconSortKey("Q")
}
}; // genCharismaIconSpec()
/**
* This (functionally redundant) supporting function is included to facilitate simple copy/paste updates of
* genCharismaIconSpec() (below) from demos\flex-table\index.html :-)
*/
function genEffectiveIconSortKey(sortKey) {
return sortKey;
} // genEffectiveIconSortKey()
/**
* This supporting function is included to facilitate simple copy/past updates of genCharismaIconSpec()
* (below) from demos\flex-table\index.html :-)
*
* The implementation here reflects the fact that (unlike in demos\flex-table\index.html), we're *not* currently
* including any translation examples in our Live Demo examples.
*/
function genEffectiveIconTooltip(tooltip) {
if (tooltip) {
switch(typeof tooltip) {
case "object":
const { defaultValue } = tooltip;
return (defaultValue && (typeof defaultValue === "string")) ? defaultValue : undefined;
case "string":
return tooltip;
}
}
return undefined;
} // genEffectiveIconTooltip()

For reference, here's the JavaScript source of the genTextCellColorSpecBasedOnCrucialityOfCharacterToSeries() function referenced as the value of the textCellColorSpecGenerator property in the tableSpec.columnSpecs[] elements for the First Name and Last Name columns in the With color highlighting of First / Last Name values for main / important characters example in the Live Demo below:

/**
* Copied verbatim from demos\flex-table\index.html, this function is referenced as the value of the (optional)
* textCellColorSpecGenerator property in the tableSpec.columnSpecs[] elements for the "First Name" and "Last Name"
* columns for the "With color highlighting of First / Last Name values for main / important characters" example.
*/
function genTextCellColorSpecBasedOnCrucialityOfCharacterToSeries(dataRecord) {
const { crucialityToTvSeries } = dataRecord;
let result = undefined;
if (typeof crucialityToTvSeries === "number") {
let cellBackgroundColorOrCSSVarname = undefined;
switch(crucialityToTvSeries) {
case 1:
cellBackgroundColorOrCSSVarname = "yellow";
break;
case 2:
cellBackgroundColorOrCSSVarname = "orange";
break;
}
if (cellBackgroundColorOrCSSVarname) {
result = {
textColorOrCSSVarname: "blue",
cellBackgroundColorOrCSSVarname: cellBackgroundColorOrCSSVarname
};
}
}
return result;
}; // genTextCellColorSpecBasedOnCrucialityOfCharacterToSeries()

For reference, here's the JavaScript source of the genDefaultRowColorsBasedOnCrucialityOfCharacterToSeries() function referenced as the value of the tableSpec.recordRowColorGeneratorFunction in the With color highlighting of record rows for main / important characters example in the Live Demo below:

function genDefaultRowColorsBasedOnCrucialityOfCharacterToSeries(dataRecord) {
const { crucialityToTvSeries } = dataRecord;
let result = undefined;
if (typeof crucialityToTvSeries === "number") {
let defaultRowBackgroundColorOrCSSVarname = undefined;
switch(crucialityToTvSeries) {
case 1:
defaultRowBackgroundColorOrCSSVarname = "yellow";
break;
case 2:
defaultRowBackgroundColorOrCSSVarname = "orange";
break;
}
if (defaultRowBackgroundColorOrCSSVarname) {
result = {
defaultRowForegroundColorOrCSSVarname: "blue",
defaultRowBackgroundColorOrCSSVarname: defaultRowBackgroundColorOrCSSVarname
};
}
}
return result;
}; // genDefaultRowColorsBasedOnCrucialityOfCharacterToSeries()

For reference, here's the JavaScript source of the getRecordGroupAnnotations() function (and supporting constants) supplied as the value for tableSpec.recordGroupAnnotationFunction in the Pre-sorted by "Updated" (asc) with record grouping example in the Live Demo below:

const
LOG_MSG_PREFIX = "[flex-table/examples.js] ",
MONTH_HAMES = [
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December"
];
/**
* The tableSpec used for the "Pre-sorted by "Updated"..." Live Demo examples reference this function as the
* the value of its recordGroupAnnotationFunction property.
*
* This implementation returns "<monthName> <year>" annotations (based on record values for the
* "lastUpdatedYYYYMMDD" field) if (and only if) the supplied sortSpec indicates that "lastUpdatedYYYYMMDD"
* is the primary (i.e. most significant) active sort field.
*
* @param renderableDataRecords an array of record objects representing the subset of data records
* for which any applicable record group annotations are requested
*
* @param sortSpec an object functioning as an ordered map of (active) sort directions
* ("unsorted" | "ascending" | "descending") keyed by effective sort field
* name (i.e. sortFieldName | fieldName as defined by the column spec for
* each sorted column).
*
* @returns a (possibly empty) Map whose (number-typed) keys represent the indices at which each record group
* annotation is to be inserted, and whose (string-typed) values define the text content of those
* annotations.
*/
function getRecordGroupAnnotations(renderableDataRecords, sortSpec) {
console.log(
`${LOG_MSG_PREFIX}getRecordGroupAnnotations():`,
`\n- renderableDataRecords`, renderableDataRecords,
`\n- sortSpec: `, sortSpec
);
const renderableRecordCount = (renderableDataRecords instanceof Array) ? renderableDataRecords.length : 0;
let result = new Map();
if (renderableRecordCount && (typeof sortSpec === "object")) {
const
primarySortFieldName = sortSpec ? Object.keys(sortSpec)[0] : undefined,
renderableRecordCount = renderableDataRecords.length;
if (primarySortFieldName === "lastUpdatedYYYYMMDD") {
let
prevLastUpdatedYYYYMMDDValue = undefined,
prevAnnotationText = undefined;
for(let i = 0; i < renderableRecordCount; ++i) {
const currLastUpdatedYYYYMMDDValue = renderableDataRecords[i].lastUpdatedYYYYMMDD || "";
if ((! currLastUpdatedYYYYMMDDValue) || (currLastUpdatedYYYYMMDDValue === prevLastUpdatedYYYYMMDDValue))
continue;
const lastUpdatedDateParts = currLastUpdatedYYYYMMDDValue.split("-");
if (lastUpdatedDateParts.length != 3)
continue;
const
year = lastUpdatedDateParts[0] || "",
monthNumber = parseInt(lastUpdatedDateParts[1]),
monthName = (isNaN(monthNumber) ? undefined : MONTH_HAMES[monthNumber - 1]) || "",
annotationText = (monthName && year) ? `${monthName} ${year}` : "";
if (annotationText != prevAnnotationText) {
result.set(i, annotationText);
prevLastUpdatedYYYYMMDDValue = currLastUpdatedYYYYMMDDValue;
prevAnnotationText = annotationText;
}
}
}
}
console.log("> returning: ", result);
return result;
} // getRecordGroupAnnotations()

For reference, here's JavaScript source of the handleRecordsForTablePageRequested() function (and supporting constants) that's registered as the listener for "recordsForTablePageRequested" events within the various External pagination... examples within the Live Demo below:

const LOG_MSG_PREFIX = "[flex-table/examples.js] ";
function handleRecordsForTablePageRequested(e) {
const { detail, target: flexTableElem } = e;
console.log(`${LOG_MSG_PREFIX}recordsForTablePageRequested(e): e.detail: `, detail);
if (! detail)
return;
let
offsetOfFirstRecordForReturnedPage = -1,
recordsForPage = [],
availableRecordCount = 0;
if (dataRecords.length) {
const { filterSpec, sortSpec } = detail;
let filteredRecords = [ ...dataRecords ];
if (filterSpec) {
const
{ caseSensitive, filterValue, targetFieldNames } = filterSpec,
targetFieldNameCount = targetFieldNames ? targetFieldNames.length : 0;
if (filterValue) {
const caseAdaptedFilterValue = caseSensitive ? filterValue : filterValue.toLocaleLowerCase();
filteredRecords = filteredRecords.filter(dataRecord => {
for(let iFieldName = 0; iFieldName < targetFieldNameCount; ++iFieldName) {
const filterableStringForRecordAndField =
flexTableElem.getFilterableStringForDataRecordAndFieldName(dataRecord, targetFieldNames[iFieldName]);
if (filterableStringForRecordAndField == null)
continue;
if (filterableStringForRecordAndField.length < caseAdaptedFilterValue.length)
continue;
const caseAdaptedFieldValueString = caseSensitive
? filterableStringForRecordAndField
: filterableStringForRecordAndField.toLocaleLowerCase();
if (caseAdaptedFieldValueString.indexOf(caseAdaptedFilterValue) >= 0)
return true;
}
return false;
});
}
} // if (filterSpec)
const filteredRecordsSorted = filteredRecords;
if (filteredRecords.length && sortSpec && Object.keys(sortSpec).length) {
const fieldComparatorFunctionsArray = [];
Object.entries(sortSpec).forEach(([fieldName, columnSortDirection]) => {
let sortDirectionMultiplier = 0;
switch(columnSortDirection) {
case "ascending":
sortDirectionMultiplier = 1;
break;
case "descending":
sortDirectionMultiplier = -1;
break;
}
const dataCellIconSpecGenerator = flexTableElem.getIconSpecGeneratorFunctionForFieldName(fieldName);
const compareFn = dataCellIconSpecGenerator
? (dataRecord1, dataRecord2) => {
const
sortKey1 = flexTableElem.extractDataCellIconSortKey(dataCellIconSpecGenerator(dataRecord1)),
sortKey2 = flexTableElem.extractDataCellIconSortKey(dataCellIconSpecGenerator(dataRecord2));
return sortKey1.localeCompare(sortKey2) * sortDirectionMultiplier;
}
: (dataRecord1, dataRecord2) => {
const
fieldValue1 = dataRecord1[fieldName] || "",
fieldValue2 = dataRecord2[fieldName] || "";
if (fieldValue1 > fieldValue2)
return 1 * sortDirectionMultiplier;
if (fieldValue1 < fieldValue2)
return -1 * sortDirectionMultiplier;
return 0;
};
fieldComparatorFunctionsArray.push(compareFn);
});
const numFieldComparatorFunctions = fieldComparatorFunctionsArray.length;
const recordComparatorFn = (dataRecord1, dataRecord2) => {
for(let i = 0; i < numFieldComparatorFunctions; ++i) {
const compareResult = fieldComparatorFunctionsArray[i](dataRecord1, dataRecord2);
if (compareResult)
return compareResult;
}
return 0;
}
filteredRecordsSorted.sort(recordComparatorFn);
} // if filtering left us with some matching records and event.detail included a non-empty sortSpec
availableRecordCount = filteredRecordsSorted.length;
if (availableRecordCount) {
const
{ offsetOfFirstRequestedRecord, maxRecordsPerPage } = detail,
indexOfFinalAvailableRecord = availableRecordCount - 1;
offsetOfFirstRecordForReturnedPage = (offsetOfFirstRequestedRecord <= indexOfFinalAvailableRecord)
? offsetOfFirstRequestedRecord
: Math.floor(indexOfFinalAvailableRecord / maxRecordsPerPage) * maxRecordsPerPage;
recordsForPage = filteredRecordsSorted.slice(offsetOfFirstRecordForReturnedPage, offsetOfFirstRecordForReturnedPage + maxRecordsPerPage);
}
} // if (dataRecords.length)
const simulateRecordCountUnavailable = flexTableElem.classList.contains(CSSClassNames.NO_AVAILABLE_RECORD_COUNT);
setTimeout(
() => {
flexTableElem.showTablePage(
recordsForPage,
offsetOfFirstRecordForReturnedPage,
simulateRecordCountUnavailable ? undefined : availableRecordCount
)
},
500
);
} // handleRecordsForTablePageRequested()