Field API Integration
When to Use
Exposing an icon picker on a content type, taxonomy term, paragraph, or any fieldable entity.
Pattern
Enable ui_icons_field. Add a field of type Icon to the bundle.
| Field type | Widget | Formatter | Storage |
|---|---|---|---|
ui_icon |
icon_widget |
icon_formatter |
one target_id column, varchar_ascii(128), not null, indexed |
Field settings include allowed_icon_pack (array) — restrict the picker to specific packs.
Storage Format
The column is named target_id, not value, and it is the field's main property (IconType::mainPropertyName()). It holds the full pack_id:icon_id string and carries a Regex constraint, IconType::ICON_ID_PCRE = /^[a-z0-9_]+:.+$/.
The
target_idcolumn is verified on 1.1.2; the main-property and constraint claims are not.IconType::schema()really does declare a singletarget_idcolumn (varchar_ascii(128),not null, indexed) on 1.1.2. But that version'sIconTypedeclares neithermainPropertyName()norICON_ID_PCRE, and noRegexconstraint anywhere — so on 1.x the inheritedFieldItemBase::mainPropertyName()still answersvalue, naming a property the field does not define, and nothing validates the stored string's shape. Both are plausible 2.0.0 additions and both are unread. If you are writing code that depends on either, check your ownIconType.phpfirst.
# Example field value (single column)
field_icon:
- target_id: "my_theme_icons:arrow-left"
There is no per-value settings storage. Size, color, and the rest are not saved alongside each icon — they are configured once on the display, in icon_formatter's icon_settings setting, and applied to every value the formatter renders. If editors need per-value control, expose those choices as separate fields; the icon field cannot carry them.
Pattern: Drupal Canvas (ui_icons_canvas)
Enable ui_icons_canvas to make icons editable inside the Drupal Canvas builder. It wires two things:
- The field widget. A client-side transform
uiIconis registered onicon_widget. Canvas throws aLogicExceptionfor any widget without transform metadata, and the stockmainPropertytransform is not enough here because both selectors (icon_autocomplete, andicon_pickerwhich extends it) nest their output undervalue[icon_id]. - SDC props. Any SDC string prop tagged
x-canvas-prop: ui-iconis routed to theui_iconfield'starget_idproperty and edited withicon_widget:
# my_component.component.yml
props:
type: object
properties:
icon:
type: string
title: "Icon"
pattern: '^[a-z0-9_]+:.+$'
x-canvas-prop: ui-icon
The pattern matters: Canvas's shape matcher compares the field's Regex constraint against the pattern derived from the prop's JSON Schema by value, so it must be exactly ^[a-z0-9_]+:.+$ or the prop will not match the icon field.
This whole subsection is unverified, and the installed Canvas does not recognise
x-canvas-prop.ui_icons_canvasdoes not exist in UI Icons 1.1.2, so nothing here could be read first-hand. Checking the other half — Canvas 1.10.1 on the reference site — the stringx-canvas-propappears nowhere in the module. The schema-extension keywords Canvas 1.10.1 does honour arex-formatting-context,x-translation-context,x-allowed-schemesandx-required-variables. Two supporting mechanisms are real:hook_canvas_storable_prop_shape_alteris declared incanvas.api.php, andJsonSchemaTypereally does turn a JSON-Schemapatterninto aRegexshape requirement — so apattern-driven match is the plausible route. Thex-canvas-prop: ui-iconkey itself needs confirmation against UI Icons 2.0.0 plus the Canvas release it targets before anyone writes a.component.ymlaround it.
Decision: Link Field Enhancement
UI Icons also enhances the core Link field:
| Widget | Use |
|---|---|
icon_link_widget |
Adds icon picker before/after URL + title |
icon_link_attributes_widget |
Same plus integration with link_attributes module |
| Formatter | Use |
|---|---|
icon_link_formatter |
Renders [icon] link text or link text [icon] |
Integration sub-submodules: ui_icons_field_link_attributes (Link + Link Attributes), ui_icons_field_linkit (Link + Linkit), ui_icons_field_linkit_attributes (all three).
Common Mistakes
- Wrong: restricting
allowed_icon_packto a pack that's later disabled → Right: audit before disabling packs in production; field values reference the pack ID and become orphaned otherwise - Wrong: using a regular Link field where editors need icons → Right: switch to
icon_link_widgetinstead of building a custom field - Wrong: writing
valuewhen setting the field programmatically or in a migration → Right: the column istarget_id; avaluekey is ignored and the save produces an empty icon - Wrong: expecting per-icon settings to persist → Right: they live on the formatter, so every value in the field renders at the same size and color
- Wrong: relying on
IconType::mainPropertyName()orICON_ID_PCREon a 1.x site → Right: neither exists on 1.1.2;mainPropertyName()falls back tovaluethere and nothing validates the stored string - Wrong: writing a
.component.ymlaroundx-canvas-prop: ui-iconagainst an installed Canvas without checking its version → Right: Canvas 1.10.1 does not recognize that keyword at all; confirm against the actual Canvas release before relying on it
See Also
- UI Patterns Integration
- Settings & Rendering
- Reference:
modules/ui_icons_field/src/Plugin/Field/FieldType/IconType.php - Reference:
modules/ui_icons_canvas/src/Hook/UiIconsCanvasHooks.php