Multi-row Selection

Selecting multiple records.

Customer orders
Order Customer Total
#1042A. Whitfield£64.00
#1041R. Okafor£128.50
#1040M. Iqbal£22.00
#1039S. Novak£40.00
#1038L. Duarte£96.20

html

<div class="mrow" data-count="1" style="--accent:#241430;">
  <div class="mrow__scroll">
    <table class="mrow__table">
      <caption>Customer orders</caption>
      <thead><tr>
        <th scope="col" class="">
          <button type="button" role="checkbox" aria-checked="mixed" class="mrow__headerchk" aria-label="Select all rows"><span class="mrow__box" aria-hidden="true"></span></button>
        </th>
        <th scope="col" class="">Order</th>
        <th scope="col" class="">Customer</th>
        <th scope="col" class="">Total</th>
      </tr></thead>
      <tbody>
        <tr><td><label class="mrow__chk"><input type="checkbox" checked><span class="sr-only">Select order #1042</span></label></td><td>#1042</td><td>A. Whitfield</td><td>£64.00</td></tr>
        <tr><td><label class="mrow__chk"><input type="checkbox"><span class="sr-only">Select order #1041</span></label></td><td>#1041</td><td>R. Okafor</td><td>£128.50</td></tr>
        <tr><td><label class="mrow__chk"><input type="checkbox" checked><span class="sr-only">Select order #1040</span></label></td><td>#1040</td><td>M. Iqbal</td><td>£22.00</td></tr>
        <tr><td><label class="mrow__chk"><input type="checkbox"><span class="sr-only">Select order #1039</span></label></td><td>#1039</td><td>S. Novak</td><td>£40.00</td></tr>
        <tr><td><label class="mrow__chk"><input type="checkbox" checked><span class="sr-only">Select order #1038</span></label></td><td>#1038</td><td>L. Duarte</td><td>£96.20</td></tr>
      </tbody>
    </table>
  </div>
</div>
<style>
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;}
.mrow { font: 14px system-ui, sans-serif; color: #241430; background: #FAF7F2; max-width: 480px; border: 1px solid #24143020; border-radius: 10px; overflow: hidden; }
.mrow__scroll { max-height: 210px; overflow: auto; }
.mrow__table { border-collapse: collapse; width: 100%; }
.mrow__table caption { text-align: left; font-weight: 600; padding: 10px 14px; }
.mrow__table th, .mrow__table td { padding: 9px 14px; text-align: left; border-bottom: 1px solid #24143020; white-space: nowrap; }
.mrow__table th { background: var(--accent); color: #FAF7F2; }
.mrow__sticky { position: sticky; top: 0; }
.mrow__table input[type="checkbox"] { accent-color: var(--accent); width: 16px; height: 16px; }
.mrow__headerchk { background: none; border: 0; padding: 0; cursor: pointer; display: inline-flex; }
.mrow__box { width: 16px; height: 16px; border: 1.5px solid #FAF7F2; border-radius: 3px; display: inline-block; position: relative; }
.mrow__headerchk[aria-checked="true"] .mrow__box::after { content: ""; position: absolute; left: 3px; top: 0px; width: 5px; height: 9px; border: solid #FAF7F2; border-width: 0 2px 2px 0; transform: rotate(40deg); }
.mrow__headerchk[aria-checked="mixed"] .mrow__box::after { content: ""; position: absolute; inset: 5px 2px; background: #FAF7F2; border-radius: 1px; }
.mrow__headerchk:focus-visible { outline: 2px solid #FAF7F2; outline-offset: 2px; }
.mrow[data-count="1"] tbody tr:nth-child(-n+1) { background: #A8E6C155; }
.mrow[data-count="3"] tbody tr:nth-child(-n+3) { background: #A8E6C155; }
</style>

tailwind

<div class="max-w-[480px] rounded-[10px] border border-[#24143020] font-sans text-sm text-[#241430] bg-[#FAF7F2] overflow-hidden" data-count="1" style="--accent:#241430;">
  <div class="max-h-[210px] overflow-auto">
    <table class="border-collapse w-full">
      <caption class="text-left font-semibold px-3.5 py-2.5">Customer orders</caption>
      <thead><tr class="text-[#FAF7F2]" style="background:#241430">
        <th scope="col" class="p-2.5"><button type="button" role="checkbox" aria-checked="mixed" class="mrow__headerchk bg-transparent border-0 p-0 cursor-pointer inline-flex focus-visible:outline focus-visible:outline-2 focus-visible:outline-white"><span aria-hidden="true" class="mrow__box w-4 h-4 border-[1.5px] border-white rounded-[3px] inline-block relative"></span></button></th>
        <th scope="col" class="p-2.5 text-left whitespace-nowrap">Order</th>
        <th scope="col" class="p-2.5 text-left whitespace-nowrap">Customer</th>
        <th scope="col" class="p-2.5 text-left whitespace-nowrap">Total</th>
      </tr></thead>
      <tbody>
        <tr><td class="p-2.5 border-b border-[#24143020]"><label class="inline-flex"><input type="checkbox" checked class="[accent-color:var(--accent)] w-4 h-4"><span class="sr-only">Select order #1042</span></label></td><td class="p-2.5 border-b border-[#24143020] whitespace-nowrap">#1042</td><td class="p-2.5 border-b border-[#24143020] whitespace-nowrap">A. Whitfield</td><td class="p-2.5 border-b border-[#24143020] whitespace-nowrap">£64.00</td></tr>
        <tr><td class="p-2.5 border-b border-[#24143020]"><label class="inline-flex"><input type="checkbox" class="[accent-color:var(--accent)] w-4 h-4"><span class="sr-only">Select order #1041</span></label></td><td class="p-2.5 border-b border-[#24143020] whitespace-nowrap">#1041</td><td class="p-2.5 border-b border-[#24143020] whitespace-nowrap">R. Okafor</td><td class="p-2.5 border-b border-[#24143020] whitespace-nowrap">£128.50</td></tr>
        <tr><td class="p-2.5 border-b border-[#24143020]"><label class="inline-flex"><input type="checkbox" checked class="[accent-color:var(--accent)] w-4 h-4"><span class="sr-only">Select order #1040</span></label></td><td class="p-2.5 border-b border-[#24143020] whitespace-nowrap">#1040</td><td class="p-2.5 border-b border-[#24143020] whitespace-nowrap">M. Iqbal</td><td class="p-2.5 border-b border-[#24143020] whitespace-nowrap">£22.00</td></tr>
        <tr><td class="p-2.5 border-b border-[#24143020]"><label class="inline-flex"><input type="checkbox" class="[accent-color:var(--accent)] w-4 h-4"><span class="sr-only">Select order #1039</span></label></td><td class="p-2.5 border-b border-[#24143020] whitespace-nowrap">#1039</td><td class="p-2.5 border-b border-[#24143020] whitespace-nowrap">S. Novak</td><td class="p-2.5 border-b border-[#24143020] whitespace-nowrap">£40.00</td></tr>
        <tr><td class="p-2.5 border-b border-[#24143020]"><label class="inline-flex"><input type="checkbox" checked class="[accent-color:var(--accent)] w-4 h-4"><span class="sr-only">Select order #1038</span></label></td><td class="p-2.5 border-b border-[#24143020] whitespace-nowrap">#1038</td><td class="p-2.5 border-b border-[#24143020] whitespace-nowrap">L. Duarte</td><td class="p-2.5 border-b border-[#24143020] whitespace-nowrap">£96.20</td></tr>
      </tbody>
    </table>
  </div>
</div>
<style>
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;}
.mrow__headerchk[aria-checked="true"] .mrow__box::after { content: ""; position: absolute; left: 3px; top: 0px; width: 5px; height: 9px; border: solid #FAF7F2; border-width: 0 2px 2px 0; transform: rotate(40deg); }
.mrow__headerchk[aria-checked="mixed"] .mrow__box::after { content: ""; position: absolute; inset: 5px 2px; background: #FAF7F2; border-radius: 1px; }
[data-count="1"] tbody tr:nth-child(-n+1) { background: #A8E6C155; }
[data-count="3"] tbody tr:nth-child(-n+3) { background: #A8E6C155; }
</style>

react

function MultiRowSelection({
  caption = "Customer orders",
  accent = "#241430",
  count = "1",
  headerCheck = "mixed",
  stickyHeader = false,
}) {
  const rows = [
    ["#1042", "A. Whitfield", "£64.00"],
    ["#1041", "R. Okafor", "£128.50"],
    ["#1040", "M. Iqbal", "£22.00"],
    ["#1039", "S. Novak", "£40.00"],
    ["#1038", "L. Duarte", "£96.20"],
  ];
  const n = Number(count);
  const th = { padding: "9px 14px", textAlign: "left", whiteSpace: "nowrap", position: stickyHeader ? "sticky" : "static", top: 0, background: accent, color: "#FAF7F2" };
  const cell = { padding: "9px 14px", borderBottom: "1px solid #24143020", whiteSpace: "nowrap" };
  return (
    <div style={{ maxWidth: 480, borderRadius: 10, border: "1px solid #24143020", overflow: "hidden", font: "14px system-ui, sans-serif", color: "#241430", background: "#FAF7F2" }}>
      <div style={{ maxHeight: 210, overflow: "auto" }}>
        <table style={{ borderCollapse: "collapse", width: "100%" }}>
          <caption style={{ textAlign: "left", fontWeight: 600, padding: "10px 14px" }}>{caption}</caption>
          <thead>
            <tr>
              <th scope="col" style={th}>
                <button type="button" role="checkbox" aria-checked={headerCheck} aria-label="Select all rows" style={{ background: "none", border: 0, padding: 0, cursor: "pointer", display: "inline-flex" }}>
                  <span aria-hidden="true" style={{ width: 16, height: 16, border: "1.5px solid #FAF7F2", borderRadius: 3, display: "inline-block", position: "relative" }}>
                    {headerCheck === "true" && <span style={{ position: "absolute", left: 3, top: 0, width: 5, height: 9, border: "solid #FAF7F2", borderWidth: "0 2px 2px 0", transform: "rotate(40deg)" }} />}
                    {headerCheck === "mixed" && <span style={{ position: "absolute", inset: "5px 2px", background: "#FAF7F2", borderRadius: 1 }} />}
                  </span>
                </button>
              </th>
              <th scope="col" style={th}>Order</th>
              <th scope="col" style={th}>Customer</th>
              <th scope="col" style={th}>Total</th>
            </tr>
          </thead>
          <tbody>
            {rows.map((row, i) => (
              <tr key={row[0]} style={{ background: i < n ? "#A8E6C155" : "transparent" }}>
                <td style={cell}><input type="checkbox" defaultChecked={i < n} aria-label={`Select order ${row[0]}`} style={{ accentColor: accent, width: 16, height: 16 }} /></td>
                <td style={cell}>{row[0]}</td><td style={cell}>{row[1]}</td><td style={cell}>{row[2]}</td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </div>
  );
}