onFocus so your app can run custom logic — navigation, uploads, help modals, etc.
Decorator model
| Property | Type | Notes |
|---|---|---|
action | string | Required. Non-empty. Unique within its scope (path). |
icon | string? | See Supported icons. |
label | string? | Text label. |
color | string? | 6-digit hex (#RRGGBB). |
icon or label. Action-only entries are stored but not displayed.
Setup
ImportDecoratorManager from @joyfill/components and pass an instance to <JoyDoc> via the decoratorManager prop:
decoratorManager instance.
Constructing a path
Every path starts withpageId/fieldPositionId. What you append after that determines what gets decorated.
Reserved keywords. The path grammar uses three reserved tokens —schemas,rows, andcolumns. Anything else in a path slot is treated as an id (page id, field-position id, row id, column id, or schema key). Don’t use these keywords as ids.
Field decorators
Just the two ids. Applies to the field’s header.Table — /rows, /columns/colId, or specific rowId / rowId/colId
A table has four decorator scopes, two common (defaults applied everywhere) and two specific (overrides for one row or cell):
| What you want | Path suffix | Example |
|---|---|---|
| Common decorators on every row | /rows | pageId/fpId/rows |
| Decorators on one specific row | /{rowId} | pageId/fpId/row_42 |
| Common decorators on every cell in a column | /columns/{colId} | pageId/fpId/columns/col_status |
| Decorators on one specific cell | /{rowId}/{colId} | pageId/fpId/row_42/col_status |
/rows shows on row_42 until you write to row_42 directly.
Collection — same as table, plus /schemas/schemaKey/… for nested rows
A collection’s root rows behave like a table — the four scopes above use the exact same path shapes.
Take a “People” collection where each person row holds a nested “Addresses” schema:
| What you want | Path shape | Example |
|---|---|---|
| Common rows in any schema | pageId/fpId/schemas/sk/rows | pageId/fpId/schemas/addresses/rows |
| Common columns in any schema | pageId/fpId/schemas/sk/columns/colId | pageId/fpId/schemas/addresses/columns/col_zip |
schemas/sk/, then the nested row id:
| What you want | Path shape | Example |
|---|---|---|
| Specific nested row | …/rowId/schemas/sk/nestedRowId | pageId/fpId/p_alice/schemas/addresses/addr_home |
| Specific nested cell | …/rowId/schemas/sk/nestedRowId/colId | pageId/fpId/p_alice/schemas/addresses/addr_home/col_zip |
Schema keys come from the field’sschemamap. The schema markedroot: trueholds top-level rows; itschildrenarray names the nested schemas reachable from a row in this schema.
API
Four methods onDecoratorManager:
Handling clicks
Decorator clicks come throughonFocus. When params.type is non-empty (and not 'fieldPositionFocus'), the focus event is a decorator tap — the value of params.type is the decorator’s action. Use params.fieldRowId and params.fieldColumnId to know exactly where the user clicked.
onFocus parameter reference.
Behavior to know
-
Collection license gating. Writes against a collection field require a license that enables collection features. Without it, the call emits
decoratorErrorand is rejected. -
Decorator visibility in PDFs. Decorators are hidden in
readonlyandpdfmodes and are only clickable infillmode.
Errors
All four APIs report errors through theonError event handler:
- Path didn’t resolve (bad ids, deleted row, malformed grammar)
- Validation (
actionempty,colornot#RRGGBB) - Duplicate
actionin batch or against an existing entry removeDecorator/updateDecoratorwith an unknownaction- Collection write without a valid license
getDecorators) on an unresolvable path also emit onError and return [].
Display limits
DecoratorConfig, passed to <JoyDoc> via the decoratorManager, controls how many decorators render inline before the rest collapse into a kebab menu.
Supported icons
The SDK supports the following named icons:camera, import, paperclip, image, file, comment, comments, upload, download, rotate, cloud, filter, share, paper-plane, folder, folder-open, magnet, eye, circle-info, add, plus, print, flag, pencil, pen-to-square. Unknown names fall back to a default icon.