Modals

Modals allow you to present content in a modal dialog on top of the current page. By default they are presented with a backdrop, vertically centered in a medium size on the screen.

Showing Modals

A modal is displayed using the ShowModal(id:) action.

Here is simple modal:

Button("Show simple Modal") {
    ShowModal(id: "showModalId")
}
.role(.primary)

Modal(id: "showModalId") {
    Text("Dismiss me by clicking on the backdrop.")
        .horizontalAlignment(.center)
        .font(.title3)
        .margin(.xLarge)
}

Dismissing Modals

Modals can either be dismissed by clicking on the backdrop, unless otherwise configured in the Presentation Options, by pressing the Esc key or programmatically by using the DismissModal(id:) action.

This modal can be dismissed through a cose button in the top right corner:

Modal(id: "dismissModalId") {
    Section {
        Button().role(.close).onClick {
            DismissModal(id: "dismissModalId")
        }
    }
    .horizontalAlignment(.trailing)

    Text("Dismiss me by clicking on the close button.")
        .horizontalAlignment(.center)
        .font(.title3)
        .margin(.xLarge)
}

Modal Size

The height of a modal is determined by the height of the content. However, the width can be adjusted by using the size() modifier. By default a modal takes a medium width but it can be adjusted to .small, .large, .xLarge and .fullscreen

Here are a few examples:

Modal(id: "smallModalId") {
    Text(markdown: "Modal with size `.small`")
        .horizontalAlignment(.center)
        .font(.title3)
        .margin(.xLarge)
}
.size(.small)

Modal(id: "xLargeModalId") {
    Text(markdown: "Modal with size `.xLarge`")
        .horizontalAlignment(.center)
        .font(.title3)
        .margin(.xLarge)
}
.size(.xlarge)

Modal(id: "fullscreenModalId") {
    Section {
        Button().role(.close).onClick {
            DismissModal(id: "fullscreenModalId")
        }
    }
    .horizontalAlignment(.trailing)

    Text(markdown: "Modal with size `.fullscreen`.")
        .horizontalAlignment(.center)
        .font(.title3)
        .margin(.xLarge)
}
.size(.fullscreen)

Modal Position

Modals are always horizontally centered but the vertical position can be changed from Position.center to Position.top by using the .modalPosition() modifier.

Here is a modal with Position.top:

Modal(id: "topModalId") {
    Text(markdown: "Modal with `Position.top`")
        .horizontalAlignment(.center)
        .font(.title3)
        .margin(.xLarge)
}
.position(.top)

Headers and Footers

Optionally modals can have a header and/or a footer.

Here is how they look like:

Modal(id: "headerModalId") {
    Text("Body")
} header: {
    Text("Header").font(.title5)

    Button().role(.close).onClick{
        DismissModal(id: "headerModalId")
    }
}

Modal(id: "footerModalId") {
    Text("Body")
} footer: {
    Button("Close") {
        DismissModal(id: "footerModalId")
    }
    .role(.secondary)

    Button("Go") {
        // Do something
    }
    .role(.primary)
}

Modal(id: "headerAndFooterModalId") {
    Text("Body")
} header: {
    Text("Header").font(.title5)

    Button().role(.close).onClick{
        DismissModal(id: "headerAndFooterModalId")
    }
} footer: {
    Button("Close") {
        DismissModal(id: "headerAndFooterModalId")
    }
    .role(.secondary)

    Button("Go") {
        // Do something
    }
    .role(.primary)
}

Note how the content in the header is inlined and placed on the leading edge. However, a button with the role close is moved to the trailing edge. Content in the footer on the other hand is placed on the trailing edge.

Scrollable Content

For content that is too long to fit on the screen, the body content can be made scrollable by using the scrollableContent() modifier.

Here is a Modal with a long text:

Modal(id: "modal7" {
    Text(placeholderLength: 1000)
} header: {
    Text("Long text")
        .font(.title5)
}
.size(.large)
.scrollableContent(true)

Presentation Options

The ShowModal action accepts an array of options that allow you to configure various presentation settings:

Option
Description

noBackdrop

Disables the backdrop, making the modal non-dismissible by clicking outside it.

backdrop(dismissible: Bool)

Enables the backdrop by default. If `dismissible` is set to `false`, the modal cannot be dismissed by clicking outside.

keyboard(Bool)

Allows the modal to be dismissed by pressing the ESC key when set to `true`. If `false`, this behavior is disabled. The default is `true`.

focus(Bool)

When `true`, the modal will autofocus on the modal when opened. The default is `true`.

A modal which can not be dismissed by clicking on the backdrop can be configured like this:

Button("Show Modal") {
    ShowModal(id: "showModalId", option [.backdrop(dismissable: false)])
}

Created in Swift with Ignite