Skip to main content
Decorators are clickable indicators (icon + label) attached to a field, column, row, or cell. Clicks are delivered through onFocus so your app can run custom logic — navigation, uploads, help modals, etc.

Decorator model

A decorator renders only when it has a non-empty icon or label. Action-only entries are stored but not displayed.

Setup

Import DecoratorManager from @joyfill/components and pass an instance to <JoyDoc> via the decoratorManager prop:
All four API methods are called directly on the decoratorManager instance.

Constructing a path

Every path starts with pageId/fieldPositionId. What you append after that determines what gets decorated.
Reserved keywords. The path grammar uses three reserved tokens — schemas, rows, and columns. 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): Specific paths inherit from the matching common path on the first write — anything you set on /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:
Common rows / columns of any schema — root or nested — are schema-level defaults: A specific nested row or cell lives under a particular parent. Walk through that parent’s row id, then schemas/sk/, then the nested row id:
Schema keys come from the field’s schema map. The schema marked root: true holds top-level rows; its children array names the nested schemas reachable from a row in this schema.

API

Four methods on DecoratorManager:
The same four methods work for every path scope. A few examples:

Handling clicks

Decorator clicks come through onFocus. 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.
See Event handling for the full 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 decoratorError and is rejected.
  • Decorator visibility in PDFs. Decorators are hidden in readonly and pdf modes and are only clickable in fill mode.

Errors

All four APIs report errors through the onError event handler:
  • Path didn’t resolve (bad ids, deleted row, malformed grammar)
  • Validation (action empty, color not #RRGGBB)
  • Duplicate action in batch or against an existing entry
  • removeDecorator / updateDecorator with an unknown action
  • Collection write without a valid license
Reads (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.