
Canvas Icon Picker: a visual icon picker for Drupal Canvas
How Canvas Icon Picker puts a visual icon picker on Canvas string props using core's Icon API.
Get Canvas Icon Picker on Drupal.orgChoosing an icon for a Canvas component prop means typing an identifier by hand. Get the name slightly wrong, arrow-right instead of arrow-right-short, say, and nothing breaks visibly: there is just a hole where the glyph should be. The only way to know the string was right is to look at the rendered page. A mistake that nothing reports is the kind that sits on a live site for months.
Why Canvas gives you a textfield
Canvas builds prop controls from the component’s JSON Schema. Its prop docs map a plain type: string to a text input and a string with an enum to a dropdown. An icon identifier is a string, so it gets a textfield and the editor types whatever they think the name is.
An enum swaps the textfield for a select of machine names. That catches typos, but the editor still chooses from a list of words with no glyph beside them, and the list has to be kept in step with the icon pack by hand in every component that declares one.
How canvas_icon_picker fixes it
Core’s Icon API, added in Drupal 11.1, is what made this tractable. Icon packs are declared in *.icons.yml files, discovered at runtime, and rendered with an icon() Twig function. The list of valid icons already exists outside the component. The module’s job is to recognize that a prop holds an icon and hand Canvas a picker bound to that list. That is why canvas_icon_picker requires Drupal ^11.1 || ^12.
A component opts a string prop in with x-canvas-icon:
props: type: object properties: icon: type: string title: Icon x-canvas-icon: trueSet it to an array of pack IDs, such as x-canvas-icon: ['bootstrap_icons'], to scope that one prop to specific packs, narrower than the site-wide allow list on the settings page.
Under the hood, the module implements hook_canvas_storable_prop_shape_alter(). For any type: string prop carrying x-canvas-icon, it sets the field widget to canvas_icon_picker. The widget renders a chip that opens a drawer with search, a pack filter, recently used icons and keyboard navigation. JavaScript fills the drawer from two endpoints, /canvas-icon-picker/index (ids and labels as JSON) and /canvas-icon-picker/sprite (one SVG <symbol> per icon). Both are gated by Canvas’s own _canvas_ui_access check, so anyone who can edit in Canvas can browse icons and nobody needs a new permission.
The prop stays type: string. The stored value is pack_id:icon_id, which splits straight into core’s icon() function:
{% if icon %} {% set parts = icon|split(':') %} {{ icon(parts[0], parts[1], { size: 24 }) }}{% endif %}Another approach
UI Icons ships a ui_icons_canvas submodule that makes its ui_icon field type and icon widget editable as a Canvas component input. That route gives the prop a dedicated field type. canvas_icon_picker keeps the prop a plain string and changes only the editing control, so the component declares an ordinary SDC string prop with one extra key.
What I want more of is a site builder with real components finding a gap, filing a clear reproduction and attaching a patch. If you have an icon prop that the picker handles badly, the issue queue is open.
What this came from
- ModuleCanvas Icon Picker
- Modulecanvas_icon_picker repository
- ArticleDrupal Canvas SDC prop types