DataTable enables users to act upon complex datasets with a variety of features including filtering and sorting.
withColumnsSettings) rather than showing them by default.data, columns, and caption.withRowSelection, withSearch, withSorting, withFilters, withPagination, and bulkActions.layout="fixed" — the default. Columns divide the available width equally regardless of content, and horizontal scrolling is disabled.layout="auto" — columns size to their content. Use when cell content must stay readable.layout="auto".meta.width on its column definition. Accepts pixels ('200px'), a number, a percentage ('50%'), or a fractional unit ('2fr') that divides the remaining space.meta.minWidth and meta.maxWidth.meta.align and meta.bodyCellVerticalAlign.isStriped) — alternates row backgrounds. Use for large datasets, especially with infinite scrolling.isBorderless) — removes row borders. Use for a cleaner look on small datasets.shouldHighlightOnHover) — highlights the row under the pointer. Applied automatically to selectable rows; set it explicitly on non-selectable rows.isLoading) — renders skeleton rows. Set loadingState.rowCount for the number of placeholder rows.withEmptyState, default true) — renders when data is empty. Configure title, description, icon, and actions through emptyState.withRowSelection is on.withSorting. Users sort from the column header or the Sort menu in the header.sorting.value and sorting.onChange. Set sorting.isManual for server-side sorting.withSearch. Renders a search input in the header that filters across all columns.search.value, search.onSearch, and search.onSearchInput. Set search.isManual for server-side search, or pass search.globalFilterFn for a custom client-side matcher.search.defaultIsExpanded={false}.withFilters and pass a filters config holding the filter definitions, active values, and change handlers.withPagination. Renders page controls below the table.pagination; control it with pagination.page and pagination.onPageChange. Set pagination.isManual when data arrives already paginated.withVirtualizer to render only visible rows for large datasets. Use it as the alternative to pagination, not alongside it.virtualizerOptions.withRowSelection — true for every row, or a function to decide per row.rowSelection and onRowSelectionChange.enableMultiRowSelection={false}.getRowCanSelect.bulkActions alongside withRowSelection. The bar appears in the header once rows are selected.promotedActions render as buttons; dropdownActions render inside a dropdown.rowActions as a config object, or a function receiving the row. Renders a dropdown in a trailing cell on each row.dropdownActions takes either action items or grouped actions.withRowExpanding to add an expander toggle column.children array by default. Override the accessor with getSubRows.getRowCanExpand, pre-expand rows with initiallyExpandedRows, and react to changes with onRowExpansionChange.withColumnsSettings to add a Columns button in the header for toggling visibility.defaultColumnVisibility; control visibility with columnVisibility and onColumnVisibilityChange.defaultColumnOrder, or control it with columnOrder and onColumnOrderChange.meta.getCellColSpan on the column definition.withSavedViews and configure the view list, creation, editing, and deletion through savedViews.loadNew to surface a row at the top of the table when new data is available.loadMore to surface a row at the bottom for appending the next batch.caption — a short, descriptive noun phrase. It is required and read by assistive technology, but not visible.data, columns, and caption are required. Build columns with createColumnHelper from @tanstack/table-core — they are TanStack Table column definitions.cell function on a column definition. Use it for formatting, badges, links, or any component in place of the raw value.emptyStateComponent, which replaces the whole emptyState block. React takes a component receiving table; Ember takes a component with a @table arg.expandedRowComponent, which replaces sub-row rendering under withRowExpanding. React takes a component receiving row; Ember takes a component with a @row arg. Pair it with getRowCanExpand.children (Ember: the default block) to replace the entire default composition — Header, Table, and Pagination — with your own arrangement of DataTableHeader, DataTableTable, and DataTablePagination.getRowId, then the id property on each row, then the row index. Override with getRowId whenever rows have a stable key.meta.shouldWrapCellContent on a column to wrap instead.meta.name when a column's header is not a plain string — the columns menu and sort menu need a readable label. Use meta.loadingPlaceholder for a column-specific skeleton and meta.sortDirectionLabelType to switch the sort labels to text.meta.minWidth and meta.maxWidth accept numbers, px, and % only — fr units are rejected. meta.width accepts fr as well.columnOrder. These private columns are stripped from onColumnOrderChange and onColumnVisibilityChange payloads.BaseTableProps JSDoc says auto — the component's actual default is layout="fixed".sorting.onChange instead of the top-level onSortingChange, and sorting.value (a { id, desc } object inside the sorting config) instead of passing { id, desc } as sorting itself.as overrides the root element (default div).<PlumaDataTable @data={{this.data}} @columns={{this.columns}} @caption="Items" @withSearch={{true}} />. Arg names and defaults match React; config objects (sorting, search, pagination, filters) take the same shape.