Skip to content

ObjectsGrid ​

Which table to use

For a table-like list that breaks down into cards on narrow screens, use ObjectsGrid. For a native HTML table that keeps its table layout at every width, use the Tables primitives.

This page shows the Visual Contract of ObjectsGrid, the responsive object list that ViewList and FieldSetTabularInline render their rows through. It also covers the grid's cell components: ObjectsGridTableHeader, ObjectsGridBodyCell, ObjectsGridCardCell, ObjectsGridBodyCellSkeleton, and ObjectsGridCardCellSkeleton. Components describes the rules every component page shares.

Layout switch ​

One ObjectsGrid renders the same rows and fields in two layouts: a table at or above its tableBreakpoint, and a grid of cards below it. The default breakpoint is lg.

  • The switch follows the viewport width, so a grid in a narrow container still renders a table on a wide viewport.
  • Breakpoint names come from utils/breakpoints.breakpointsVueda, from 2xs to inf.
  • xs always renders the table. inf keeps cards at any practical viewport width.
  • The grid emits update:isTable on mount and on every switch, with true for the table layout.

ViewList passes its own tableBreakpoint to the grid. CRUD Views describes the list chrome around the grid.

Both layouts render div elements with ARIA table, row, and cell roles.

Table layout ​

  • Surface: the root (ObjectsGrid.root) carries the card fill in both layouts. In table layout it also carries the radius and Hairline edge that close the last row. A wide table scrolls sideways inside the root.
  • Embedded grids: an ancestor marked data-flush removes the root's radius and edge, so the parent draws the only frame. FieldSetTabularInline works this way. ViewList removes them through its own ViewList.objectsGrid key, so its strips above and below frame the grid.
  • Header: header cells (ObjectsGrid.headerCell, with content from ObjectsGridTableHeader) show the field label and are display-only. Sorting uses the SortControl menu and the active sort chips outside the grid.
  • Dividers: a hairline on each row's cells divides that row from the next one. The same hairline divides the header band from the first data row. The root edge closes the grid below the last row. ObjectsGrid.table fills the root.
  • Row height: body cells (ObjectsGridBodyCell.root) set row height from the density prop: default, compact, or condensed, each tighter than the last. A table cell treats that height as a minimum, so a row holding a chip or an avatar renders taller.
  • Numbers: the grid renders numbers with tabular figures. A field descriptor with numeric: true right-aligns its header and cells.

The demo forces table mode with tableBreakpoint="xs".

Card layout ​

Below tableBreakpoint, each row renders as a card.

The demo uses tableBreakpoint="inf" so the cards show at every practical viewport width. It also removes the three-column step with a theme override, because the demo sits in a column narrower than the viewport.

Row states ​

ObjectsGrid.bodyRow styles each row in both layouts. A row takes its state from a data-state attribute, which the rowAttrs function can set per row.

  • Hover and press: the row takes an accent tint.
  • selected: a low primary tint and a primary rail on the leading edge, so a selected row stays distinct from a hovered one.
  • marked-destroy: a destructive tint and a strikethrough on every field except the item-action-bar column, so its undo control stays readable. FieldSetTabularInline sets it on rows that the user marks for removal.

ObjectsGrid.rowActions provides classes for row controls that a consumer places in a cell. The container stays hidden at rest and shows when the pointer is over the row, the row holds focus, or the row is selected. Its action class styles compact icon buttons. Apply both classes in your cell content.

Loading and empty ​

When loading is true and the grid has no rows, it renders skeletonRows rows of skeleton cells, one per field. getSkeletonClassForField sizes each skeleton by field type, and a field descriptor's skeletonClass replaces that size. A grid that already has rows keeps them on screen while it loads.

When the grid has no rows and is not loading, it renders one empty-state row:

  • Width: the row spans the full width in both layouts. In table layout its cell is a td with colspan (ObjectsGrid.emptyText); in card layout the row spans the card grid.
  • Default content: an icon and the emptyText prop as the title, laid out by ObjectsGrid.emptyContent. The icon comes from the Icon Registry entry for ObjectsGrid, keyed by the variant.
  • Variants: emptyVariant is empty, filtered, loading, or error. It sets data-variant on the content, and the theme spins the icon for loading and colors it destructive for error.
  • Custom content: the empty slot replaces the icon and title. It receives variant.
  • No row: :empty-text="null" removes the empty-state row unless you pass an empty slot. Inline grids embedded in forms use this.

Tabular inline editing ​

FieldSetTabularInline embeds an editable ObjectsGrid in its own fieldset. The fieldset draws the outer edge and the separator above help and validation messages, so it is the only frame around the grid. Below its breakpoint (lg by default), the rows switch to cards.

Field picker menus ​

The sort and filter add-menus (SortControl and FilterMenu) list their available fields with FieldPickerMenuList. The list has a capped height (FieldPickerMenuList.list). A list longer than the cap keeps its scrollbar visible before any hover or scroll; a shorter list fits its content with no scrollbar. The same list appears in the desktop popover and the mobile dialog.

Theme keys and class props ​

Theme keys change every grid:

Class props change one grid, keyed by field name: fieldClasses, tableFieldClasses, and cardFieldClasses style cells; headerClasses, tableHeaderClasses, and cardHeaderClasses style labels. The unprefixed prop applies in both layouts; the table and card props apply in one. Use them to tune a numeric column, an action column's width, or a compact field in one grid.