Render svelte component inside ag-grid

Viewed 184

Does anyone have an example of how to render a svelte component inside of ag grid? Similar to how you can render an angularjs or react component inside of ag-grid.

1 Answers

Since there isn't a svelte extension for AG-Grid, you might have to handle this using the Svelte client-side component API.

EDIT: Tested working approach below

Create CellRenderer

import SiteAccountCellButtonSvelte from "./SiteAccountCellButton.svelte";

export class SiteAccountButtonRenderer {
  constructor() {
    // create empty div to place svelte component in
    this.eGui = document.createElement("div");
  }

  init(params: ICellRendererParams) {
    this.value = params.value;

    new SiteAccountCellButtonSvelte({
      target: this.eGui,
      props: {
        // your props here
        siteBalance: params.data,
      },
    });
  }

  getGui() {
    return this.eGui;
  }

  refresh(params) {
    this.value = params.value;
    this.eGui.innerHTML = '';

    return true;
  }
}

Configure AG-Grid options

const gridOptions: GridOptions = {
  pagination: true,
  paginationPageSize: 15,
  domLayout: "autoHeight",
  rowHeight: 56,
  defaultColDef: {
    sortable: true,
    unSortIcon: true,
    resizable: true,
    flex: 1,
    minWidth: 170,
  },
  columnDefs: [
    {
      headerName: "account name",
      field: "accountName",
      filter: true,
      floatingFilter: true,
      cellClass: (_params: CellClassParams) => {
        return "fw-bold";
      },
      cellRenderer: SiteAccountButtonRenderer,
    },
    // more columnDefs here
  ],
};

Initialize Grid in Parent Svelte Component

  <script lang="ts">
    import { Grid } from "@ag-grid-community/core";
    import { onMount } from "svelte";
    import type { SiteBalance, SiteBalancesViewModel } from "../../../typings/Payments";
    import { createGridOptions } from "./SiteBalances";
  
    export let vm: SiteBalancesViewModel;
    export let data: SiteBalance[];
  
    let gridEl: HTMLElement;
  
    onMount(async () => {
      const gridOptions = createGridOptions(vm);
      new Grid(gridEl, gridOptions);
      gridOptions.api.setRowData(data);
    });
  </script>
  
  <div style="height: 100%;" bind:this={gridEl} class="ag-theme-alpine" />

Original Answer

I haven't set this up before, but the general set up might be something like:

  1. Create Svelte component with props per usual
  2. Set up an ag-grid Cell Renderer 2a. In the init method, make sure the this.eGui.innerHTML property is set to an empty div with the CSS selector of the svelte component (<div class="svelte-widget"></div>) 2b. In the same init method, initialize the svelte component:
import SvelteWidget, { selector as SvelteWidgetSelector } from "./your-path/SvelteWidget.svelte";

class SvelteWidgetRenderer {
    init(params) {
        this.eGui = document.createElement('div');
        this.eGui.classList.add('svelte-widget');

        // initialize svelte widget with client-side component API
        new SvelteWidget({ target: this.eGui, props: { /* your props */ });
    }
}

the svelte widget "selector" is optional because we are attaching the svelte component to the ag-grid DOM element

Related