Svelte Carbon Component System Data Table Row background Color

102 views Asked by At

Is there a way to customize back ground color for rows based on data in a cell? I need the color of the row to be aqua for rule: "Round Robin" and green if rule:"DNS Delegation" Example:

<script>
    import { DataTable, Pagination } from "carbon-components-svelte";
  
    let rows = Array.from({ length: 10 }).map((_, i) => ({
      id: i,
      name: "Load Balancer " + (i + 1),
      protocol: "HTTP",
      port: 3000 + i * 10,
      rule: i % 2 ? "Round robin" : "DNS delegation",
    }));
    let pageSize = 5;
    let page = 1;
  </script>
  
  <DataTable
    sortable
    title="Load balancers"
    description="Your organization's active load balancers."
    headers={[
      { key: "name", value: "Name" },
      { key: "protocol", value: "Protocol" },
      { key: "port", value: "Port" },
      { key: "rule", value: "Rule" },
    ]}
    {pageSize}
    {page}
    {rows}
  />
  <Pagination
    bind:pageSize
    bind:page
    totalItems={rows.length}
    pageSizeInputDisabled
  />
  <style>
    :global(.round-robin) {
        background-color: aqua;
    }
    :global(.dns-delegation) {
        background-color: green;
    }
  </style>

I was hoping to apply a class to the Row item:

<DataTableRow class={row.item.rule}>
:global(.round-robin) {
     background-color: aqua;
}
:global(.dns-delegation) {
     background-color: green;
}
2

There are 2 answers

0
Manasi Gopala On BEST ANSWER
<script>
    import { DataTable, Pagination } from "carbon-components-svelte";
    import { CellTower, LogicalPartition } from "carbon-icons-svelte";
    import { onMount } from "svelte";

    let rows = Array.from({ length: 10 }).map((_, i) => ({
        id: i,
        name: "Load Balancer " + (i + 1),
        protocol: "HTTP",
        port: 3000 + i * 10,
        rule: i % 2 ? "Round robin" : "DNS delegation",
    }));
    let pageSize = 5;
    let page = 1;
    const rr = rows
        .filter((row) => row.rule === "Round robin")
        .map((row) => row.id);
    const dns = rows
        .filter((row) => row.rule === "DNS delegation")
        .map((row) => row.id);
    let rule1 = rr.map((id) => `[data-row="${id}"]`).join(",");
    let rule2 = dns.map((id) => `[data-row="${id}"]`).join(",");
    const styles = `
    <style>
      ${rule1} {
        --cds-layer: red;
      }
      ${rule2} {
        --cds-layer: green;
      }
    <\/style>
  `;
</script>

<svelte:head>
    {@html styles}
</svelte:head>
<DataTable
    id="events-table"
    sortable
    title="Load balancers"
    description="Your organization's active load balancers."
    headers={[
        { key: "name", value: "Name" },
        { key: "protocol", value: "Protocol" },
        { key: "port", value: "Port" },
        { key: "rule", value: "Rule" },
    ]}
    {pageSize}
    {page}
    {rows}
></DataTable>

<Pagination
    bind:pageSize
    bind:page
    totalItems={rows.length}
    pageSizeInputDisabled
/>
0
brunnerh On

There does not appear to be a clean/well supported way of doing this right now.

Can think of two ways, both of which involve using the cell slot:

  • Place an element (e.g. a <span>) and mark it with a data-attribute or a class according to the cell data. You then can use a tr:has(...) selector to target the row; Firefox is currently still lacking support, though.
  • Place an element and attach and action, passing the relevant data to distinguish the type. The action can find the closest('tr') and add a class to it for styling.