Search
Loading...
Skip to content

Dock

The dock provides quick access to content libraries and editing tools, appearing at the bottom of the editor interface. This guide shows you how to customize dock items and their layout to match your app’s content strategy and user workflow. While examples use the Design Editor, the same configuration principles apply to all editor solutions.

Explore a complete code sample on GitHub.

Dock Architecture#

Dock

The dock displays horizontally at the bottom of the editor and provides quick access to content libraries and editing tools. It adapts its content based on the selected editor solution.

Key Components:

  • Dock.Item - Protocol that all dock items conform to
  • Dock.Button - Pre-built button implementation with icon and title
  • Dock.Context - Provides access to the engine, asset library, and event handler
  • Custom Items - Create fully custom components by implementing Dock.Item

Configuration#

Dock customization uses SwiftUI modifiers in the .imgly namespace. You can configure the complete item list or modify the default items.

Available modifiers:

  • dockItems - Define the complete list of dock items and their order. Items are only displayed when isVisible(_:) returns true.

  • modifyDockItems - Modify the default item list by adding, replacing, or removing specific items without rebuilding the entire configuration.

The Dock.Context provides access to the engine, asset library, and event handler. Use this for advanced customization logic and to maintain consistency with the current editor state.

Default Dock Items#

Each editor solution has its own default dock configuration optimized for its content workflow:

These are the default items recommended to be used with the Design Editor:

.imgly.dockItems { _ in
Dock.Buttons.elementsLibrary()
Dock.Buttons.imglyPhotoRoll()
Dock.Buttons.systemCamera()
Dock.Buttons.imagesLibrary()
Dock.Buttons.textLibrary()
Dock.Buttons.shapesLibrary()
Dock.Buttons.stickersLibrary()
Dock.Buttons.resize()
}

These are the default items recommended to be used with the Photo Editor:

.imgly.dockItems { _ in
Dock.Buttons.adjustments()
Dock.Buttons.filter()
Dock.Buttons.effect()
Dock.Buttons.blur()
Dock.Buttons.crop()
Dock.Buttons.textLibrary()
Dock.Buttons.shapesLibrary()
Dock.Buttons.stickersLibrary()
}

These are the default items recommended to be used with the Video Editor:

.imgly.dockItems { _ in
Dock.Buttons.imglyPhotoRoll()
Dock.Buttons.imglyCamera()
Dock.Buttons.overlaysLibrary()
Dock.Buttons.textLibrary()
Dock.Buttons.stickersAndShapesLibrary()
Dock.Buttons.audioLibrary()
Dock.Buttons.voiceover()
Dock.Buttons.reorder()
Dock.Buttons.resize()
}

Apparel Editor and Postcard Editor don’t have predefined dock items by default, but you can customize them by providing your own dock configuration using .imgly.dockItems. This will also enable the use of .imgly.modifyDockItems for fine-tuning.

Modify Dock Items#

Use the .imgly.modifyDockItems modifier to adjust the default item list without rebuilding the entire configuration:

.imgly.modifyDockItems { context, items in

Parameters:

  • context - provides access to the engine, asset library, and event handler
  • items - mutable array of dock items that can be modified

Available modification operations:

  • addFirst - prepends new Dock.Items:
items.addFirst {
Dock.Button(id: "my.package.dock.button.first") { context in
print("First Button action")
} label: { context in
Label("First Button", systemImage: "arrow.backward.circle")
}
}
  • addLast - appends new Dock.Items:
items.addLast {
Dock.Button(id: "my.package.dock.button.last") { context in
print("Last Button action")
} label: { context in
Label("Last Button", systemImage: "arrow.forward.circle")
}
}
  • addAfter - adds new Dock.Items right after the item with the provided id:
items.addAfter(id: Dock.Buttons.ID.imglyPhotoRoll) {
Dock.Button(id: "my.package.dock.button.afterIMGLYPhotoRoll") { context in
print("After IMGLY Photo Roll action")
} label: { context in
Label("After IMGLY Photo Roll", systemImage: "arrow.forward.square")
}
}
  • addBefore - adds new Dock.Items right before the item with the provided id:
items.addBefore(id: Dock.Buttons.ID.systemCamera) {
Dock.Button(id: "my.package.dock.button.beforeSystemCamera") { context in
print("Before Camera action")
} label: { context in
Label("Before Camera", systemImage: "arrow.backward.square")
}
}
  • replace - replaces the Dock.Item with the provided id with new Dock.Items:
items.replace(id: Dock.Buttons.ID.textLibrary) {
Dock.Button(id: "my.package.dock.button.replacedTextLibrary") { context in
print("Replaced Text action")
} label: { context in
Label("Replaced Text ", systemImage: "arrow.uturn.down.square")
}
}
  • remove - removes the Dock.Item with the provided id:
items.remove(id: Dock.Buttons.ID.shapesLibrary)

Dock.Item Configuration#

Each Dock.Item conforms to EditorComponent. Its id must be unique which is a requirement of the underlying SwiftUI ForEach type. Depending on your needs there are multiple ways to define an item. In this example, we demonstrate your options with increasing complexity.

Use Predefined Buttons#

The most basic option is to use our predefined buttons which are provided in the nested Dock.Buttons. namespace. All available predefined buttons are listed below.

Dock.Buttons.elementsLibrary()

Customize Predefined Buttons#

All parameters of our predefined buttons are initialized with default values which allows you to change any of them if needed to finetune the button’s behavior and style:

Dock.Buttons.imagesLibrary(
action: { context in
context.eventHandler.send(.openSheet(type: .libraryAdd { context.assetLibrary.imagesTab }))
},
title: { context in Text("Image") },
icon: { context in Image.imgly.addImage },
isEnabled: { context in true },
isVisible: { context in true },
)

Available parameters:

  • action - the action to perform when the user triggers the button. In this example, the event handler is used to open a sheet with the Asset Library for adding an image.

  • title - the title View that should be used to label the button. Don’t encode the visibility in this view. Use isVisible instead. In this example, a Text view is used.

  • icon - the icon View that should be used to label the button. Don’t encode the visibility in this view. Use isVisible instead. You can use any custom icon or system image. We also provide icon images in the Image.imgly namespace for convenience.

  • isEnabled - whether the button is enabled. In this example, true is always used.

  • isVisible - whether the button should be visible. Prefer using this parameter to toggle the visibility instead of encoding it in the title and icon views. In this example, true is always used.

Create New Buttons#

If our predefined buttons don’t fit your needs you can create your own:

Dock.Button(
id: "my.package.dock.button.newButton",
) { context in
print("New Button action")
} label: { context in
Label("New Button", systemImage: "star.circle")
} isEnabled: { context in
true
} isVisible: { context in
true
}

Required and optional parameters:

  • id - the unique id of the button. This parameter is required.

  • action - the action to perform when the user triggers the button. This parameter is required.

  • label - a View that describes the purpose of the button’s action. Don’t encode the visibility in this view. Use isVisible instead. This parameter is required.

  • isEnabled - whether the button is enabled. By default, true is always used.

  • isVisible - whether the button should be visible. Prefer using this parameter to toggle the visibility instead of encoding it in the label view. By default, true is always used.

Create New Custom Items#

If you need something completely custom you can use arbitrary views as items.

Therefore, you need to conform your type to the Dock.Item protocol:

private struct CustomDockItem: Dock.Item {
var id: EditorComponentID { "my.package.dock.newCustomItem" }
func body(_ context: Dock.Context) throws -> some View {
ZStack {
RoundedRectangle(cornerRadius: 10)
.fill(.conicGradient(colors: [.red, .yellow, .green, .cyan, .blue, .purple, .red], center: .center))
Text("New Custom Item")
.padding(4)
}
.onTapGesture {
print("New Custom Item action")
}
}
func isVisible(_ context: Dock.Context) throws -> Bool {
true
}
}

Then use it in your dock items:

CustomDockItem()

Protocol requirements:

  • var id: EditorComponentID { get } - the unique id of the item. This property is required.

  • func body(_: Dock.Context) throws -> some View - the body of your view. Don’t encode the visibility in this view. Use isVisible instead. This property is required.

  • func isVisible(_: Dock.Context) throws -> Bool - whether the item should be visible. Prefer using this parameter to toggle the visibility instead of encoding it in the body view. By default, true is always used.

List of Available Dock.Buttons#

All predefined buttons are available as static functions in the Dock.Buttons namespace. Each function returns a Dock.Button with default parameters that you can customize as shown in the Customize Predefined Buttons section.

ButtonIDDescription
Dock.Buttons.elementsLibraryDock.Buttons.ID.elementsLibraryOpens library sheet with elements via editor event .openSheet. By default, the corresponding library is picked from the Asset Library.
Dock.Buttons.overlaysLibraryDock.Buttons.ID.overlaysLibraryOpens library sheet with overlays via editor event .openSheet. By default, the corresponding library is picked from the Asset Library.
Dock.Buttons.stickersAndShapesLibraryDock.Buttons.ID.stickersAndShapesLibraryOpens library sheet with stickers and shapes via editor event .openSheet. By default, the corresponding library is picked from the Asset Library.
Dock.Buttons.imagesLibraryDock.Buttons.ID.imagesLibraryOpens library sheet with images via editor event .openSheet. By default, the corresponding library is picked from the Asset Library.
Dock.Buttons.textLibraryDock.Buttons.ID.textLibraryOpens library sheet with text via editor event .openSheet. By default, the corresponding library is picked from the Asset Library.
Dock.Buttons.shapesLibraryDock.Buttons.ID.shapesLibraryOpens library sheet with shapes via editor event .openSheet. By default, the corresponding library is picked from the Asset Library.
Dock.Buttons.stickersLibraryDock.Buttons.ID.stickersLibraryOpens library sheet with stickers via editor event .openSheet. By default, the corresponding library is picked from the Asset Library.
Dock.Buttons.audioLibraryDock.Buttons.ID.audioLibraryOpens library sheet with audio via editor event .openSheet. By default, the corresponding library is picked from the Asset Library.
Dock.Buttons.systemPhotoRollDock.Buttons.ID.systemPhotoRollOpens the system photo roll via editor event .addFromSystemPhotoRoll.
Dock.Buttons.imglyPhotoRollDock.Buttons.ID.imglyPhotoRollOpens the IMG.LY photo roll via editor event .addFromIMGLYPhotoRoll.
Dock.Buttons.systemCameraDock.Buttons.ID.systemCameraOpens the system camera via editor event .addFromSystemCamera.
Dock.Buttons.imglyCameraDock.Buttons.ID.imglyCameraOpens the IMG.LY camera via editor event .addFromIMGLYCamera.
Dock.Buttons.voiceoverDock.Buttons.ID.voiceoverOpens voiceover sheet via editor event .openSheet.
Dock.Buttons.reorderDock.Buttons.ID.reorderOpens reorder sheet via editor event .openSheet.
Dock.Buttons.adjustmentsDock.Buttons.ID.adjustmentsOpens adjustment sheet via editor event .openSheet.
Dock.Buttons.filterDock.Buttons.ID.filterOpens filter sheet via editor event .openSheet.
Dock.Buttons.effectDock.Buttons.ID.effectOpens effect sheet via editor event .openSheet.
Dock.Buttons.blurDock.Buttons.ID.blurOpens blur sheet via editor event .openSheet.
Dock.Buttons.cropDock.Buttons.ID.cropOpens crop sheet via editor event .openSheet.
Dock.Buttons.resizeDock.Buttons.ID.resizeOpens resize sheet via editor event .openSheet.
Dock.Buttons.assetLibraryDock.Buttons.ID.assetLibraryOpens asset library sheet via editor event .openSheet.