Add custom buttons to extend editor functionality with app-specific actions across four UI components.

Overview#
Add buttons using component-specific modifiers (.imgly.modifyDockItems, .imgly.modifyCanvasMenuItems, etc.) with [Component].Button types. Each component provides context for conditional logic.
| Component | Selection Context | Best For |
|---|---|---|
| Dock | - | Global actions |
| CanvasMenu | context.selection | Selection-specific actions |
| InspectorBar | context.selection | Property-related actions |
| NavigationBar | - | App-level navigation |
Adding to Dock#
Add global action buttons using .imgly.modifyDockItems. Use reverse domain notation for IDs to avoid conflicts.
.imgly.modifyDockItems { context, items in items.addFirst { Dock.Button( id: "my.app.dock.button.export", action: { context in print("Custom export button tapped") }, label: { context in Label("Export", systemImage: "square.and.arrow.up") }, ) }}id- Unique identifier (e.g.,"my.app.dock.button.export")action- Closure executed on taplabel- SwiftUILabelfor button appearance
Adding to Canvas Menu#
Add selection-specific buttons using .imgly.modifyCanvasMenuItems. Use context.selection to control button state based on the selected element:
.imgly.modifyCanvasMenuItems { context, items in items.addFirst { CanvasMenu.Button( id: "my.app.canvasMenu.button.favorite", action: { context in print("Favorite button tapped") }, label: { context in Label("Favorite", systemImage: "star.fill") }, // Disable for stickers (shows grayed out) isEnabled: { context in context.selection.kind != "sticker" }, // Only show for graphic blocks (hidden otherwise) isVisible: { context in context.selection.type == .graphic }, ) }}Use isEnabled and isVisible closures to control button state based on selection properties:
// Disable for stickers (shows grayed out)isEnabled: { context in context.selection.kind != "sticker"},// Only show for graphic blocks (hidden otherwise)isVisible: { context in context.selection.type == .graphic},Adding to Inspector Bar#
Add property-related buttons using .imgly.modifyInspectorBarItems. Use isEnabled and isVisible to control button state based on selection:
isEnabled- Whenfalse, the button appears grayed out but remains visibleisVisible- Whenfalse, the button is completely hidden
.imgly.modifyInspectorBarItems { context, items in items.addFirst { InspectorBar.Button( id: "my.app.inspectorBar.button.process", action: { context in print("Process button tapped") }, label: { context in Label("Process", systemImage: "gearshape") }, // Disable for text blocks (shows grayed out) isEnabled: { context in context.selection.type != .text }, // Only show for blocks with fill (hidden otherwise) isVisible: { context in context.selection.fillType != nil }, ) }}Adding to Navigation Bar#
Add app-level buttons using .imgly.modifyNavigationBarItems. Specify placement for each button.
.imgly.modifyNavigationBarItems { context, items in // Add to trailing side items.addFirst(placement: .topBarTrailing) { NavigationBar.Button( id: "my.app.navbar.button.help", ) { context in print("Help button tapped") } label: { context in Label("Help", systemImage: "questionmark.circle") } }
// Add to leading side items.addLast(placement: .topBarLeading) { NavigationBar.Button( id: "my.app.navbar.button.settings", ) { context in print("Settings button tapped") } label: { context in Label("Settings", systemImage: "gearshape") } } }| Placement | Position |
|---|---|
.topBarLeading | Leading side |
.topBarTrailing | Trailing side |
.principal | Center |
Button Parameters#
All button types accept these parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
id | String | Yes | - | Unique identifier |
action | (Context) -> Void | Yes | - | Closure executed on tap |
label | (Context) -> Label | Yes | - | Button appearance |
isEnabled | (Context) -> Bool | No | true | When false, button is grayed out |
isVisible | (Context) -> Bool | No | true | When false, button is hidden |
API Reference#
| API | Description |
|---|---|
Dock.Button() | Create a custom dock button |
CanvasMenu.Button() | Create a canvas menu button |
InspectorBar.Button() | Create an inspector bar button |
NavigationBar.Button() | Create a navigation bar button |
.imgly.modifyDockItems() | Insert buttons into the dock |
.imgly.modifyCanvasMenuItems() | Insert buttons into the canvas menu |
.imgly.modifyInspectorBarItems() | Insert buttons into the inspector bar |
.imgly.modifyNavigationBarItems() | Insert buttons into the navigation bar |
Next Steps#
- Rearrange Buttons - Customize button order in UI components
- Customize Dock - Full dock customization patterns
- Customize Navigation Bar - Navigation bar configuration
- Canvas Menu - Contextual menu customization