Table States
Tables render loading, empty, and load-error states.
These states are configured under table.states. Loading and empty text are read directly from table.states. Load-error copy is resolved through the message pipeline.
Loading
<FluiKit schema={usersSchema} loading />table: {
states: {
loading: {
text: "Loading users..."
}
}
}Loading never replaces the whole table. The toolbar, search, filters, Create button, column headers, and pagination controls stay on screen the entire time:
- No rows loaded yet (first load): the loading text renders inside a full-width table body row, the same treatment as the empty state below.
- Rows already loaded (a query change while paginating, sorting, filtering, or switching a multi-resource tab): the existing rows stay visible, dimmed, with a thin progress indicator above the table, instead of being replaced by the loading text. This keeps re-queries from flashing the table to empty.
Empty
<FluiKit schema={usersSchema} data={[]} />table: {
states: {
empty: {
text: "No users found."
}
}
}Empty state renders inside a full-width table body row.
Load error
<FluiKit schema={usersSchema} error={new Error("Network timeout")} />Unlike loading/empty text, table.states.error.text is not read directly — it is passed in as a fallback to the shared message pipeline for the loadError key. Resolution order is: a backend/caught error message first, then messages.defaults.loadError, then table.states.error.text, then the built-in default "Unable to load data.".
table: {
states: {
error: {
text: "Unable to load users."
}
}
}messages: {
defaults: {
loadError: "Unable to load users."
}
}Both forms above work, but messages.defaults.loadError wins if both are set — use it instead of table.states.error.text when the same fallback text should also apply outside the table (e.g. through a message resolver). Load error renders inside a full-width table body row.
Defaults
| State | Default text |
|---|---|
| loading | Loading... |
| empty | No data available. |
| error | Unable to load data. |