Lattice Grid Buy a licence

demo D220

Open positions board

A recruitment dashboard screen: a progress bar, a status pill and a templated kebab, on a card

render: 'progress' · 'pill' · cell.template

Loading a live grid…

The configuration

<script>
  import { createGrid } from 'https://cdn.jsdelivr.net/npm/@toclocoinc/lattice-grid@1.28.0/lattice-grid.esm.min.js';
  import createLatticeAction from 'https://cdn.jsdelivr.net/npm/@toclocoinc/lattice-grid@1.28.0/modules/svelte.esm.min.js';

  const lattice = createLatticeAction({ createGrid });

  const jobs = [
    { id: '1', title: 'Senior Frontend Developer', dept: 'Engineering', fill: 72, location: 'San Francisco, CA', applications: 24, status: 'Open' },
    { id: '2', title: 'Product Manager', dept: 'Product', fill: 45, location: 'New York, NY', applications: 18, status: 'Open' },
    { id: '3', title: 'UX Designer', dept: 'Design', fill: 30, location: 'Austin, TX', applications: 31, status: 'Interviewing' },
    // …
  ];

  const config = {
    rowKey: 'id',
    density: 'spacious',               // the generous row rhythm
    showColumnFunctions: false,        // quiet headers, no sort/filter/menu furniture
    autoHeight: true,
    columns: [
      { field: 'title', title: 'Job title', layout: { width: 280 }, cell: { class: 'is-strong' } },
      { field: 'fill', title: 'Department', sort: { enabled: false }, layout: { width: 230 },
        cell: { render: 'progress', props: { min: 0, max: 100, showValue: false, variant: 'amber', label: 'Pipeline filled' } } },
      { field: 'dept', title: ' ', sort: { enabled: false }, layout: { width: 140 }, header: { render: () => '' } },
      { field: 'location', title: 'Location', layout: { width: 180 } },
      { field: 'applications', title: 'Applications', type: 'number', total: 'sum', layout: { width: 130 } },
      { field: 'status', title: 'Status', layout: { width: 150 },
        cell: { render: 'pill', props: { shape: 'pill',
          variant: { map: { Open: 'success', Interviewing: 'info', Offer: 'accent', Paused: 'warning' }, default: 'neutral' } } } },
      { id: 'act', title: 'Action', sort: { enabled: false }, layout: { width: 90 },
        cell: { template: '<button class="kebab" aria-label="Row actions">⋮</button>' } },
    ],
    rows: jobs,
  };
</script>

<svelte:head>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@toclocoinc/lattice-grid@1.28.0/lattice-grid.min.css">
  <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@400;500;600;700&display=swap">
  <!-- The look, asked of the theme rather than fought: the card, the re-tinted
       pill variants through the grid's own tokens, the hatched amber progress
       track, and the templated-cell buttons. Global rather than the component's
       scoped styles, so the rules reach the grid the action builds. -->
  <style>
    body { font-family: "IBM Plex Sans", system-ui, sans-serif; background: #EFEDE4; padding: 34px; }
    .card { background: #FBFAF5; border-radius: 20px; padding: 22px 24px 12px;
      box-shadow: 0 1px 2px rgba(20,22,28,.04), 0 18px 46px -30px rgba(20,22,28,.4); }
    .card-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; }
    .card-head h2 { font-size: 1.25rem; font-weight: 700; margin: 0; }

    /* The grid adopts the card's palette through the theme's real token names. */
    .lattice {
      --lattice-background: transparent;
      --lattice-border-color: #EDEAE0;
      --lattice-header-foreground: #8C8A80;
      --lattice-accent: #F0A94C;
      /* Re-tint the four built-in pill variants. The pill renderer reads its
         variant from its own props, so these tokens are the extension point. */
      --lattice-variant-success-fill: #DEF7EC; --lattice-variant-success-text: #036C4F;
      --lattice-variant-info-fill: #E1EFFE;    --lattice-variant-info-text: #1A56DB;
      --lattice-variant-accent-fill: #EDE9FE;  --lattice-variant-accent-text: #6D28D9;
      --lattice-variant-warning-fill: #FEF0DC; --lattice-variant-warning-text: #92400E;
    }
    .lattice .lat-header-cell, .lattice .lat-cell { border-right: 0; }
    .lattice .is-strong { font-weight: 600; }
    /* props.variant is written out as data-variant, so keying off it here is what
       makes the amber progress bar its own colour over a hatched track. */
    .lattice [data-variant="amber"] .lat-progress-track {
      background-image: repeating-linear-gradient(-45deg, #E7EBF3 0 4px, #F4F6FA 4px 8px);
      background-color: #F4F6FA; border-radius: 999px; height: 12px;
    }
    .lattice [data-variant="amber"] .lat-progress-fill { background: #F5B863; border-radius: 999px; }
    .lattice .kebab { font: inherit; font-size: 18px; color: #8C8A80; background: none; border: 0; cursor: pointer; }
  </style>
</svelte:head>

<div class="card">
  <div class="card-head"><h2>Open Job Positions</h2></div>
  <div use:lattice={config}></div>
</div>