# Table Proposal

Review card for an AI-proposed table. Accept it to create and populate the table.

## Add it to an app

1. Open the app builder and find **Table Proposal** in the component palette.
2. Insert it into the intended region or container.
3. Set its properties in the inspector. Use a literal for a fixed value or a binding for a value supplied by the app.
4. Connect its events where the app should respond to a user gesture.
5. Preview with representative data and save after resolving validation problems.

The type name in the builder’s code view is `table_proposal`.

## Settings

| Setting | Accepted value | Required | Default | What it controls |
| --- | --- | --- | --- | --- |
| Busy (`busy`) | boolean | No | Not specified | Supports expression bindings. Disables the actions. |
| Populate error (`populateError`) | string | No | Not specified | Supports expression bindings. The populate source's runError. |
| Populate status (`populateStatus`) | string | No | Not specified | Supports expression bindings. The populate source's runStatus. |
| Proposal (`proposal`) | object or null | No | Not specified | Supports expression bindings. The proposal record {table_name, columns: [{key, label, type}], rationale?, id?}. |
| Section label (`title`) | string | No | "" | The listed default is inserted when adding a new component. |
| Quiet when unchanged (`unchangedNotice`) | boolean | No | false | The listed default is inserted when adding a new component. |

## Values available to bindings

| Value | Type | Initial value | Meaning |
| --- | --- | --- | --- |
| `acceptedColumns` | list of object or null | null | The accepted columns. |
| `acceptedLibraryKey` | string or null | null | The accepted proposal's schema-library key. |
| `acceptedMode` | "created" / "refreshed" | null | Whether the accept created the table or refreshed an existing one. |
| `acceptedProposalId` | string or null | null | The accepted proposal's id. |
| `acceptedTableId` | string or null | null | The target table id, created or refreshed. |
| `acceptedTableName` | string or null | null | The target table's name. |
| `dismissedKey` | string or null | null | The dismissed proposal's id, else its content signature. |
| `openRequest` | object or null | null | Open the target table: {id, label, revision, columns}. |

Refer to these values through `components.<component-id>.<value>` in a binding. Use the identifier assigned to this instance of Table Proposal, not the component type name.

## Events

- `onAccept` — An accept settled (after the publish patch); Retry re-fires it.

- `onDismiss` — The proposal was dismissed.

Connect only the actions the app needs. An event can fetch results, run an enabled data source, set state, update another component, show a notification, or navigate where supported.

## Keyboard and accessible labels

Updates are announced through the component’s live status region.

## Example: Proposal card that populates the accepted table

| Setting | Example value |
| --- | --- |
| `busy` | "{{ dataSources.populate.isRunning }}" |
| `populateError` | "{{ dataSources.populate.runError }}" |
| `populateStatus` | "{{ dataSources.populate.runStatus }}" |
| `proposal` | "{{ dataSources.proposals.data[0] }}" |
| `title` | "Proposed table" |

When `onAccept` occurs, the example performs:

- `triggerDataSource` with {"dataSourceId":"populate","mode":"run"}

## Example: Auto-proposing app: quiet when nothing changed

| Setting | Example value |
| --- | --- |
| `proposal` | "{{ dataSources.proposals.data[0] }}" |
| `unchangedNotice` | true |

## If it is empty or unavailable

Check the source binding, the selected item, and the app’s access. A hosted document, table, review, or storage component needs the corresponding app capability; an offline preview cannot supply live private data. A source running with no results is different from an invalid binding. Inspect the app’s workflow and data source before changing the presentation.
