Layout and columns
Tune density, resizing, pinning, ordering, and empty states.
Choose a layout preset for an administrative screen, a catalog, or a compact preview. Then override the few behaviors that matter to your product.
Responsive toolbar
The toolbar splits the view switcher, on the left, from View settings and
the Data button, on the right. Desktop has one row: view tabs (or the
named view trigger, with its icon, view name and chevron), search,
application actions, View settings, Data and create. actionsAsIcons
controls application-action labels; there is no desktop overflow menu. Below
768px, or when the container cannot fit the row, it becomes view · + · …:
the view trigger shrinks to an icon-only button — accessible name and
unsaved-changes dot only, no visible label or chevron — so search keeps the
room on the row, collapsing into a button that opens the field. Archives is
an application example, not a built-in action.
View settings holds presentation only — layout, density, properties,
filter, sort, group, footer calculations and card settings; there is no Data
section inside it. Export, Connect and Share live in their own Data
menu, opened from a database-icon button next to View settings: an
Export › row, a Connect › row (custom connect
destinations, hidden without any) and a
Share › row (a screen listing "Copy link" followed by custom share
destinations, or a direct copy action without any), both declared in
actions.destinations. On compact layouts the Data menu also lists the
application toolbar actions; there is no separate data-actions panel. On wide
screens those application actions stay as toolbar buttons before View
settings, whose icon button carries a badge counting active filters and
sorts.
View settings use an anchored desktop panel and a scrolling modal on compact layouts. Mobile targets are at least 44px. Layout and density are rows showing their current value that open a list of choices, like properties, filter, sort and group; those screens have Back navigation. Configured quick filters move into Filters on compact layouts. Desktop toolbar controls remain 32px high; density only changes records.
| Setting | Table | Kanban | Gallery |
|---|---|---|---|
| Search, filters, sort | Available | Available | Available |
| Grouping fields | Up to 2 | 1 | 1 |
| Density | XS, S, M, L, XL, 2XL | Hidden | Hidden |
| Properties | Columns, sizing, pinning | Card properties | Card properties |
| Footer calculations | When enabled | Hidden | Hidden |
| Card presentation | Hidden | Title, properties, labels | Also image, ratio, fit and size |
Mode and density are direct controls in the view menu. Both use a visible label and an evenly spaced row of buttons, with the selected choice highlighted. Catalogue flags and column capabilities can hide additional settings. Switching presentation preserves inactive settings. Column-header shortcuts still open filters and sorting.
Advanced numeric filters keep a local draft until Enter or the confirmation
button (Done in React, Apply in Vue). Typing 24 leaves the current
results unchanged until confirmation; it never applies 2 and 4 separately.
Zero, negative numbers and decimals are supported. Both range endpoints must be
complete before applying. Escape discards pending edits. Filters use flat
menu rows and standard inputs, without nested cards or an implicit 0–100 slider.
The runnable Vue example enables enableAdvancedFilters so this flow can be
tested alongside sorting and grouping.
Configuration example
Start from the React quick start or Vue quick start. The following file extends their product catalog. Pass this configuration through getTableConfig in React or config in Vue.
import { defineTableConfig } from "@/components/ui/yayaw-table/config/helpers";
import { productConfig } from "./product-config";
export const layoutConfig = defineTableConfig({
...productConfig,
table: {
...productConfig.table,
layoutPreset: "admin",
density: "small",
actionsAsIcons: false,
enableViews: true,
allowViewSave: true,
enableColumnDnd: true,
enableColumnDragDropByDefault: false,
enableColumnResizing: true,
enableColumnPinning: true,
emptyState: {
title: "No products match",
description: "Clear filters or try another name.",
},
},
});import { defineTableConfig } from "@/components/ui/yayaw-table-vue/config";
import { productConfig } from "./product-config";
export const layoutConfig = defineTableConfig({
...productConfig,
table: {
...productConfig.table,
layoutPreset: "admin",
density: "small",
actionsAsIcons: false,
enableViews: true,
allowViewSave: true,
enableColumnDnd: true,
enableColumnDragDropByDefault: false,
enableColumnResizing: true,
enableColumnPinning: true,
emptyState: {
title: "No products match",
description: "Clear filters or try another name.",
},
},
});Make changes reversible
Column order, visibility, widths and pinning are user state. Mandatory columns remain available. Keep stable column IDs when renaming headers so existing views still resolve. enableColumnDnd exposes the feature; enableColumnDragDropByDefault controls its initial activation.
Design for small screens
Use the host Shadcn theme and give the table a container that can shrink (min-width: 0). Test long cell values, a narrow viewport, the bulk menu, and an empty filtered result. A hidden toolbar also removes the controls a user may need to recover from an old saved filter.
The panel uses the host's Shadcn popover colors, borders and radius. Its height follows its content; a single scroll area takes over only when the available height is exceeded. Grouping preserves the configured column order, including the selection column, so group headings and record cells remain aligned.
The runnable React and Vue examples include a Custom onBulkEdit switch:
select multiple records, open Bulk edit, and apply a status to those records.
With the switch off, the generated catalogue form handles bulk editing. In a
custom React handler, invalidate both tableData and tableColumnCalculations
queries after a write so filtered records and footer totals refresh together.
React's getTableActions().list is responsible for applying the supplied global
search, column filters, advanced filters and sort before pagination. The toolbar
only changes the query; returning unchanged records does not filter or sort them.
The responsive example searches every data column, including status, number and
boolean values. Vue's local-data example applies the same query before pagination.
Use labelled desktop actions
Keep desktop actions labelled. At compact widths the toolbar switches to the icon-only view trigger, a search button, View settings and Create; menu entries retain readable labels.
Copy this complete configuration beside product-config.ts. Use () => exampleConfig as React’s getTableConfig, or :config="exampleConfig" in Vue.
Sample data. Changes stay in this preview.
import { defineTableConfig } from "@/components/ui/yayaw-table/config/helpers";
import { productConfig } from "./product-config";
export const exampleConfig = defineTableConfig({
...productConfig,
table: {
...productConfig.table,
actionsAsIcons: false,
density: "medium",
enableViews: false,
},
});Sample data. Changes stay in this preview.
import { defineTableConfig } from "@/components/ui/yayaw-table-vue/config";
import { productConfig } from "./product-config";
export const exampleConfig = defineTableConfig({
...productConfig,
table: {
...productConfig.table,
actionsAsIcons: false,
density: "medium",
enableViews: false,
},
});Use icons and a denser table
The icon flag affects desktop actions. Density belongs to the current view and is only offered in Table mode.
Copy this complete configuration beside product-config.ts. Use () => exampleConfig as React’s getTableConfig, or :config="exampleConfig" in Vue.
Sample data. Changes stay in this preview.
import { defineTableConfig } from "@/components/ui/yayaw-table/config/helpers";
import { productConfig } from "./product-config";
export const exampleConfig = defineTableConfig({
...productConfig,
table: {
...productConfig.table,
actionsAsIcons: true,
density: "small",
displayModes: ["table", "kanban", "gallery"],
kanban: { groupBy: "status", titleColumn: "name" },
gallery: { titleColumn: "name" },
},
});Sample data. Changes stay in this preview.
import { defineTableConfig } from "@/components/ui/yayaw-table-vue/config";
import { productConfig } from "./product-config";
export const exampleConfig = defineTableConfig({
...productConfig,
table: {
...productConfig.table,
actionsAsIcons: true,
density: "small",
displayModes: ["table", "kanban", "gallery"],
kanban: { groupBy: "status", titleColumn: "name" },
gallery: { titleColumn: "name" },
},
});