Data table

The Datepicker component is a form element that allows users to select a date from a calendar. It is used to input a date in a user-friendly way.

Examples

The datatable componet is based on the Tanstack Table library. Almost all the properties of the Tanstack Table are supported.

Default

The default datatable only needs the data and columns properties to be set. Check the Tanstack table column definition for more information.

HTML

Js

{/* <dap-ds-datatable id="auto"></dap-ds-datatable> */}

  const dataCount = 100
  const dataManual = () => Array.from({ length: dataCount }, (_, i) => ({
      id: i,
      title: `Title ${i}`,
      category: `Category ${i}`,
      price: 100 + i,
      rating: 4.5 + i / 10,
  }))

  const datatable = document.querySelector('dap-ds-datatable')
  datatable.data = dataManual()
  datatable.columns = [
    {
      id: 'title',
      accessorKey: 'title',
      header: 'Title',
    },
    {
      id: 'category',
      accessorKey: 'category',
      header: 'Category',
    },
    {
      id: 'price',
      accessorKey: 'price',
      header: 'Price',
    },
    {
      id: 'rating',
      accessorKey: 'rating',
      header: 'Rating',
    },
  ]
Selection

The datatable component supports selection of rows. By default the selection is disabled. To enable selection, set the enableRowSelection property to true. You can use the dds-selection-change event to get the selected rows. You can use the rowSelection property to set the initial selection. Read more about the rowKey property.

HTML

Js

{/* <dap-ds-datatable id="auto" enableRowSelection></dap-ds-datatable> */}

  autoTable.addEventListener('dds-selection-change', event => {
    console.log(`Selected ${Object.keys(event.detail.selection).length} rows`)
  })

  {/* Set initial selection
      The key is the row id and the value is a boolean.
      If the value is true, the row is selected.
      You can change the key with the `rowKey` property on the table.
  */}
  autoTable.rowKey = 'title'
  autoTable.rowSelection = {
    'Title 1': true,
    'Title 2': true,
  }
Sorting

The datatable component supports sorting by clicking on the column header. By default the sorting is disabled. To enable sorting, set the enableSorting property to true. The default sorting mechanism is using the getToggleSortingHandler function.

The default behavior when using either the getToggleSortingHandler or toggleSorting APIs is to cycle through the sorting states like this: 'none' -> 'desc' -> 'asc' -> 'none' -> 'desc' -> 'asc' -> ...

HTML

Js

{/* <dap-ds-datatable id="auto" enableSorting></dap-ds-datatable> */}

  const datatable = document.querySelector('dap-ds-datatable')
  datatable.enableSorting = true
  datatable.columns = [
    {
      id: 'title',
      accessorKey: 'title',
      header: 'Title',
    },
    ...
  ]   
Manual sorting

If you want to use a custom sorting mechanism, you can use the manualSorting property. In this case clicking on the column header will not trigger the sorting. Instead the sorting is triggered by the dds-sorting-change event. You can also pass a default sorting state to the sorting property. These are useful when you use remote data.

datatable.sorting = [{
  desc : false,
  id : "title"
}]

datatable.addEventListener('dds-sorting-change', event => {
  console.log(event.detail.sorting[0])
  // [{
  //   desc : false
  //   id : "title"
  // }]
})
Remote data

The datatable component supports remote data. If you choose to use remote data you have to handle the pagination, sorting and filtering yourself. First you have to set the manualPagination and manualSorting property to true. Then you have to handle the dds-pagination-change, dds-sorting-change events.

HTML

Js

{/* <dap-ds-datatable id="auto" manualPagination manualSorting></dap-ds-datatable> */}

  const fetchData = (table, skip, pageSize, sort, search) => {
    if (search) {
      fetch(`https://dummyjson.com/products/search?q=${search}`)
        .then(res => res.json())
        .then(data => {
            console.log(data)
            table.data = data?.products

            // Set the total number of rows to make the pager work
            table.rowCount = data.total
        })
    } else {
      fetch(
        `https://dummyjson.com/products?limit=${pageSize}&skip=${skip}${sort ? `&sortBy=${sort.id}&order=${sort.desc ? 'desc' : 'asc'} ` : ''}${search ? `&search=${search}` : ''}`,
      )
      .then(res => res.json())
      .then(data => {
          console.log(data)
          table.data = data?.products

          // Set the total number of rows to make the pager work
          table.rowCount = data.total
      })
    }
  }
    
  const pageSize = 11
  let pageIndex = 0 //page * pageSize
  datatable.manualPagination = true
  datatable.manualSorting = true

  datatable.pagination = {
    pageIndex,
    pageSize,
  }
  datatable.pageSizeOptions = [11, 12, 23]
  datatable.enableRowSelection = true
  datatable.rowSelection = {
    4: true,
    6: true,
  }

  datatable.addEventListener('dds-sorting-change', event => {
    console.log(event.detail.sorting)

    fetchData(
      datatable,
      datatable.pagination.pageSize * datatable.pagination.pageIndex,
      datatable.pagination.pageSize,
      event.detail.sorting[0],
      null,
    )
  })

  datatable.addEventListener('dds-selection-change', event => {
    console.log(event.detail.selection)
  })

  datatable.addEventListener('dds-pagination-change', event => {
    console.log(event.detail)
    pageIndex = event.detail.pagination.pageIndex

    fetchData(
      datatable,
      event.detail.pagination.pageSize * event.detail.pagination.pageIndex,
      event.detail.pagination.pageSize,
      null,
      null,
    )
  })

  fetchData(datatable, 0, 10, null, null)
Custom cell renderer

The datatable component supports custom cell renderer. You can pass a function to the cell property of the column definition. Because the whole library is written in lit, the cell renderer is also written in lit. This means if you want to pass a custom cell renderer, you need to pass a lit template. This can be done by using the html tag from the lit library. You can install it with npm install lit-html. Read more about lit here.

HTML

Js

import { html } from 'lit/static-html.js'

{/* <dap-ds-datatable id="auto"></dap-ds-datatable> */}

const dataCount = 100
datatable.columns = [
    {
    id: 'title',
    accessorKey: 'title',
    header: 'Title',
    cell: row => 
      html`<div>
            <dap-ds-button>
              <dap-ds-icon name="home-6-line"></dap-ds-icon>
            </dap-ds-button>
            ${row.getValue()}
          </div>`
  },
]
Custom cell editor

The datatable component supports custom cell editor. You can pass a function to the cell property of the column definition. Because the whole library is written in lit, the cell editor is also written in lit. This means if you want to pass a custom cell editor, you need to pass a lit template. This can be done by using the html tag from the lit library. You can install it with npm install lit-html. Read more about lit here.

To make a cell editable, you can replace the default content on a click event for example, and render the desired editor component. This example uses the dap-ds-input component as an editor. Click a cell in the title column to see the custom cell editor.

HTML

Js

{/* <dap-ds-datatable id="auto"></dap-ds-datatable> */}

  table.columns = [
  {
    accessorKey: 'title',
    cell: ({ getValue, row, column, table }) => {
      const initialValue = getValue()

      const span = document.createElement('span')
      span.textContent = getValue()
      span.addEventListener('click', () => {
        const input = document.createElement('dap-ds-input')
        input.value = span.textContent
        input.addEventListener('dds-blur', () => {
          console.log('dds-blur', input.value, row, column, table)

          // optimistic update
          span.textContent = input.value
          input.replaceWith(span)

          // call the update here
          ...
        })
        input.addEventListener('dds-keydown', event => {
          if (event.detail.event.key === 'Enter') {
            input.blur()
          }
        })

        // replace the span with the edit input
        span.replaceWith(input)
        input.updateComplete.then(() => {
          console.log('input focus')
          input.focus()
        })
      })

      return span
    },
  ]
Custom header renderer

The datatable component supports custom header renderer. You can pass a function to the header (header API) property of the column definition. Because the whole library is written in lit, the header renderer is also written in lit. This means if you want to pass a custom header renderer, you need to pass a lit template. This can be done by using the html tag from the lit library. You can install it with npm install lit-html. Read more about lit here. Use the disableDefaultSorting attribute to disable the default sorting.

Click the title to see the custom header renderer. This example uses the <dap-ds-command> component to create a custom header renderer.

HTML

Js

{/*import { html } from 'lit/static-html.js' */}
{/* <dap-ds-datatable id="auto" customHeader></dap-ds-datatable> */}

datatable.columns = [
  {
    id: 'title',
    accessorKey: 'title',
    disableDefaultSorting: customHeader,
    header: () => html`<dap-ds-command floatingStrategy="fixed">
          <dap-ds-button variant="clean" slot="trigger"
            >Title</dap-ds-button
          >
          <dap-ds-command-group label="Sort" exclusive>
            <dap-ds-command-item
              value="asc"
              selectable
              ?selected=${header.column.getIsSorted() === 'asc'}
              @dds-command-item-click=${() => {
                if (header.column.getIsSorted() === 'asc') {
                  header.column.clearSorting()
                } else {
                  header.column.toggleSorting(false)
                }
              }}
              >Asc</dap-ds-command-item
            >
            <dap-ds-command-item
              value="desc"
              selectable
              ?selected=${header.column.getIsSorted() === 'desc'}
              @dds-command-item-click=${() => {
                if (header.column.getIsSorted() === 'desc') {
                  header.column.clearSorting()
                } else {
                  header.column.toggleSorting(true)
                }
              }}
              >Desc</dap-ds-command-item
            >
          </dap-ds-command-group>
          <dap-ds-command-item value="hide">Hide</dap-ds-command-item>
        </dap-ds-command>`
  }
]
Importing
import { DapDSDataTable } from 'dap-design-system/dist/dds'
Importing React
import { DapDSDataTableReact } from 'dap-design-system/dist/react'
Attributes
PropertyTypeDefaultDescription
dataRowData[][]Data to display in the table
columnsExtendedColumnDef<T>[][]Columns to display in the table
rowKeystring'id'Row key to use for row selection, this should be a unique key for each row
enableRowSelectionboolean, ((row: Row<T>) => boolean)falseEnable row selection on the table, can be a boolean or a function that returns a boolean
enableSortingbooleanfalseEnable sorting on the table
manualSortingbooleanfalseEnable manual sorting on the table
manualPaginationbooleanfalseEnables manual pagination. If this option is set to true, the table will not automatically paginate rows and instead will expect you to manually paginate the rows before passing them to the table. This is useful if you are doing server-side pagination and aggregation.
autoResetPageIndexbooleanfalseIf set to true, pagination will be reset to the first page when page-altering state changes eg. data is updated, filters change, grouping changes, etc. This behavior is automatically disabled when manualPagination is true but it can be overridden by explicitly assigning a boolean value to the autoResetPageIndex table option.
enableRowClickbooleanfalseEnable row click on the table
loadingbooleanfalseLoading state of the table
enableStripedRowsbooleanfalseWhether to enable striped rows
rowCountnumber, undefinedNumber of rows in the table
pagerbooleanfalseWhether to show the pager component
showPageSizeOptionsstring'true'Show the page size options.
showPageIndexstring'true'Show the page index.
showPageCountstring'true'Show the page count.
showFirstButtonstring'true'Show the first button.
showPreviousButtonstring'true'Show the previous button.
showNextButtonstring'true'Show the next button.
showLastButtonstring'true'Show the last button.
firstButtonLabelstringThe label of the first button
previousButtonLabelstringThe label of the previous button
nextButtonLabelstringThe label of the next button
lastButtonLabelstringThe label of the last button
pageStateText(pageIndex:number, pageSize: number, totalRows: number) => stringThe function to determine the pager text
pageSizeOptionsnumber[][10, 25, 50, 100]Available page size options for the pager
sortingSortingStateSorting state of the table
rowSelectionRowSelectionStateSelection state of the table
paginationPaginationStatePagination state of the table
Slots

No slots available.

Events
Event NameDescriptionType
dds-sorting-changeFired when the sorting of the table changes.{sorting: SortingState }
dds-selection-changeFired when the selection of the table changes.{selection: RowSelectionState }
dds-pagination-changeFired when the pagination of the table changes.{pagination: PaginationState }
dds-row-clickFired when a row is clicked.{row: Row<T> }
CSS Parts
Part NameDescription
baseThe main table container.
headerThe header of the table.
header-rowThe header row of the table.
header-cellAll cells of the header.
bodyThe body of the table.
rowAll rows of the table.
cellAll cells of the table.
pagerThe pager of the table.
CSS Custom Properties
Property NameDescription
--dds-datatable-bg-colorBackground color of the table
--dds-datatable-border-colorBorder color of the table cells
--dds-datatable-header-bg-colorBackground color of the table header
--dds-datatable-header-text-colorText color of the table header
--dds-datatable-row-hover-bg-colorBackground color of hovered rows
--dds-datatable-row-selected-bg-colorBackground color of selected rows
--dds-datatable-cell-paddingPadding of table cells
--dds-datatable-header-paddingPadding of header cells
--dds-datatable-border-widthWidth of table borders
--dds-datatable-font-sizeFont size of the table
--dds-datatable-line-heightLine height of the table
--dds-datatable-header-font-weightFont weight of the header
--dds-datatable-stripe-colorBackground color for striped rows
--dds-datatable-stripe-enabledWhether to enable striped rows
--dds-datatable-border-radiusBorder radius of the table
--dds-datatable-shadowBox shadow of the table
--dds-datatable-transition-durationDuration of hover/selection transitions
--dds-datatable-z-indexZ-index of the table
--dds-datatable-min-heightMinimum height of the table
--dds-datatable-max-heightMaximum height of the table
--dds-datatable-overflow-xHorizontal overflow behavior
--dds-datatable-overflow-yVertical overflow behavior