You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 107dc0a
Browse filesBrowse the repository at this point in the historyBrowse files
Copy file name to clipboardExpand all lines: apps/ui/content/docs/components/composer.mdx
+20-9Lines changed: 20 additions & 9 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -188,7 +188,7 @@ To extend the anatomy above, pass `triggers={triggers}` to `Composer` and insert
188
188
</ComposerPopup>
189
189
```
190
190
191
-
Configure only the triggers you need. Queries can contain spaces: `@sam r` finds Sam Rivera. A space immediately after the trigger closes the suggestions. Selecting an item inserts a token into the draft; it does not send the message or execute an action.
191
+
Configure only the triggers you need. Queries can contain spaces: `@sam r` finds Sam Rivera. A space immediately after the trigger closes the suggestions. By default, selecting an item inserts a token into the draft; it does not send the message or execute an action. Supply `onAction` to handle items with `type: "action"` as commands: Composer removes the active query and calls your handler without inserting a token or submitting. Your application owns execution.
192
192
193
193
To open a trigger from a button inside `ComposerActions`, call `useComposerContext().insertTrigger("@")` or `insertTrigger("/")`. The trigger is inserted at the caret and opens the same suggestions as typing it.
194
194
@@ -207,7 +207,7 @@ By default, selected mentions and actions appear as `text-primary font-medium` t
207
207
208
208
<ComponentPreviewname="p-composer-6" />
209
209
210
-
The selected item's `kind` reaches `renderToken`, so a person and a team selected from the same `@` menu can use different icons or styles. The structured draft keeps `type`, `kind`, `id`, `label`, and `trigger`; `getComposerText(value)`still returns textsuch as `@Sam Rivera` when a chip hides the trigger visually. An item's `icon` is available to the suggestion list renderer but is not stored in the draft. A native textarea remains plain text and does not render tokens.
210
+
The selected item's `kind` reaches `renderToken`, so a person and a team selected from the same `@` menu can use different icons or styles. The structured draft keeps `type`, `kind`, `id`, `label`, `trigger`, and optional `data` and `text`; `getComposerText(value)` returns the explicit `text` or defaults to text such as `@Sam Rivera`, even when a chip hides the trigger visually. An item's `icon` is available to the suggestion list renderer but is not stored in the draft. A native textarea remains plain text and does not render tokens.
211
211
212
212
### Custom filtering
213
213
@@ -217,13 +217,15 @@ The default filter ignores case and accents. Set a trigger's `filter` to customi
217
217
218
218
### Async results
219
219
220
-
Fetch results in response to `onQueryChange`. Use `filter: null` for prefiltered results and `itemsFor` to identify the query they belong to. A completed query with no matches closes the popup.
220
+
Fetch results in response to `onQueryChange`. Use `filter: null` for prefiltered results and `itemsFor` to identify their query text. For caret-sensitive results, return the opaque `ComposerQuery.key` as the trigger’s `queryKey`; results from a different query position cannot be selected even when the text matches. Do not persist or parse the key.
221
+
222
+
A completed query with no matches closes the popup by default. Set `showEmpty: true` to keep it open and render an empty state with `ComposerStatus`. `maxQueryLength` optionally limits the query text after the trigger. When a popup has no selectable results, Enter is blocked by default; `submitOnEmptySuggestions` lets Enter follow the normal submission policy, including during loading or error states.
221
223
222
224
<ComponentPreviewname="p-composer-2" />
223
225
224
226
### Keyboard shortcuts
225
227
226
-
While suggestions are open, ↑ and ↓ navigate, Enter selects, Escape dismisses, and Tab moves focus normally. Otherwise, Enter submits and Shift+Enter inserts a line break in the native contenteditable input or textarea. Set `submitOnEnter="desktop"` to submit only with a fine pointer, or `"never"` to let Enter insert a line break.
228
+
While suggestions are open, ↑ and ↓ navigate, Enter selects, Escape dismisses, and Tab moves focus normally. Shift+Enter dismisses suggestions and inserts a line break. Otherwise, Enter submits and Shift+Enter inserts a line break in the native contenteditable input or textarea. Set `submitOnEnter="desktop"` to submit only with a fine pointer, or `"never"` to let Enter insert a line break.
227
229
228
230
## In a drawer
229
231
@@ -246,7 +248,9 @@ The styled frame and state owner for one input. It renders a form by default and
|`onAction`|`(item: ComposerItemValue, query: ComposerQuery) => void`| — | Removes the query and reports an action selection without inserting a token or submitting |
253
+
|`submitOnEmptySuggestions`|`boolean`|`false`| Allows Enter to follow the submission policy when the open popup has no selectable results |
250
254
|`submitOnEnter`|`"desktop" \| "always" \| "never"`|`"always"`| Enter behavior for either input |
251
255
|`layout`|`"stacked" \| "adaptive"`|`"stacked"`| Keep actions below the input, or place them beside a one-line draft and move them below when it wraps |
252
256
|`disabled`|`boolean`|`false`| Disables editing, suggestions, and submission |
@@ -417,7 +421,7 @@ type ComposerValue = readonly ComposerPart[]
Item IDs must be unique within each trigger. Set `disabled:true` on an item to skip it during keyboard navigation and prevent selection. `type` defaults to `"mention"`; set `"action"` for slash actions. Use `kind` for your own categories, such as `"person"` and `"team"`, even when both come from `@`. The selected part retains `kind`. `getComposerText(value)`returns the plain-text representation with trigger characters, including when chips hide them visually.
443
+
Item IDs must be unique within each trigger. Set `disabled:true` on an item to skip it during keyboard navigation and prevent selection. `type` defaults to `"mention"`; set `"action"` for slash actions. Use `kind` for your own categories, such as `"person"` and `"team"`, even when both come from `@`. The selected part retains `kind`. `getComposerText(value)`uses a token’s optional `text` field, or falls back to its trigger and label. Optional `data` is an opaque string preserved through editing, undo/redo, and supported structured copy/paste; the editor never interprets it as HTML. Keep domain validation and authorization in your application.
436
444
437
445
`ComposerTrigger` configures one source:
438
446
@@ -442,11 +450,14 @@ Item IDs must be unique within each trigger. Set `disabled: true` on an item to
| `itemsFor` | `string` | — | Query the async items belong to |
445
-
| `status` | `"ready" \|"loading" \|"error"` | `"ready"` | Loading/error feedback keeps the popup open; zero ready matches hide it |
453
+
| `queryKey` | `string` | — | Opaque query identity returned by `onQueryChange`; mismatched results cannot be selected |
454
+
| `showEmpty` | `boolean` | `false` | Keeps the popup open when there are no ready matches |
455
+
| `maxQueryLength` | `number` | Unlimited | Maximum query text length after the trigger |
456
+
| `status` | `"ready" \|"loading" \|"error"` | `"ready"` | Loading/error feedback keeps the popup open; zero ready matches hide it unless `showEmpty` is enabled |
446
457
447
458
### Draft lifecycle
448
459
449
-
Copying or cutting a token includes its trigger in plain text, even when a chip hides it. Pasted or dropped text stays plain textand never acquires a mention ID. Keep application records keyed by the token's `id` and `kind`; display icons are not part of the submitted document.
460
+
Copying or cutting includes the token’s `text`, or its trigger and label by default, in plain text. It also writes `application/x-coss-composer` data so compatible composers can preserve tokens and metadata. Structured paste validates the document shape and accepts at most 1,000 parts and 100,000 serialized characters; unsupported or invalid structured data falls back to plain text. External text, HTML, and dropped text do not acquire mention IDs. Clipboard metadata is untrusted input and never grants access to application records. Display icons are not part of the submitted document.
450
461
451
462
Contenteditable edits have a local undo history, including token insertion, paste, and cut. Replacing the draft externally or resetting it starts a new history. Selection is preserved and clamped to the updated draft. If an external value changes during IME composition, it is applied after composition finishes. A native textarea keeps its browser editing history.
0 commit comments