Modal

Modals are a handy JavaScript component for displaying an action the user must take. Modals are highly customizable from both a CSS and JavaScript perspective.



Example

To display a Modal, call the Modal Component via Frontbx's Container:

let modal = frontbx.Modal({
    title            : 'Use X\'s location service?',
    content          : 'Let X help apps determine location. This means sending anonymous location data to X, even when no apps are running.',
    cancelBtn        : 'Disagree',
    confirmBtn       : 'Agree',
});

The content option can be either a String, HTMLElement, NodeList or Array


Content

By default the Modal will structure provided content and title into a card element. In cases where more customized content is needed, set custom:true in the options to create your own markup.

let modal = frontbx.Modal({
    content: '...',
    custom: true,
    closeAnywhere: true
});

Scrollable

When a Modal becomes too long for the user's viewport or device the content will scroll. By default the entire modal itself will scroll. You can customize this by setting the scroll option to either modal (default) or content.

The example below shows the difference:

let modal = frontbx.Modal({
    title   : '...',
    content : '...',
    scrollable: 'modal',
});

Customization

Modal positioning, sizing and animations are set via local CSS Variables on .modal-wrap. You can create a custom modal by either overriding the variables, or passing a custom modifier class to the classes option and then modifying the variables from there.

The example below shows a simple example of a modal that slides in from the bottom of the page without an overlay element:

.modal-wrap.custom-modal
{
    --fbx-modal-transform-off: translate3d(0, 100%, 0);
    --fbx-modal-transition: opacity .125s ease, transform .225s ease;
    align-items: flex-end;
    padding-bottom: 50px;
}
let modal = frontbx.Modal({
    title : 'Subscribe for $1?',
    content : 'Subscribe for $1 and get all my posts for free!',
    cancelBtn : 'Nah',
    confirmBtn : 'YES!',
    classes: 'custom-modal',
    overlay: false,
    closeAnywhere: false,
});

Callbacks

There are a number of callbacks available depending on what access you require. In the example below, the callbackOpen option is used to focus an input within the modal when it pops up:

See the Options Section for a full list of callbacks.

frontbx.Modal( {
    title: 'Subscribe',
    content: '....',
    callbackOpen: (modal) => find('.js-modal-input', modal).focus(),
});

Methods

Once a Modal instance is created, there are a few methods to interact with the modal:

The open method will animate and open the modal:

modal.open();

The close method will animate and close the modal:

modal.close();

The direction method returns the modal state which will be either closed or open:

if (modal.state() === 'closed')
{

}

The state method returns the modal state which will be either closed or open:

if (modal.state() === 'closed')
{

}

The opened method returns true if the modal is open or false if not

if (modal.opened())
{

}

The closed method returns true if the modal is closed or false if not

if (modal.closed())
{

}

Finally the destroy method completely removes the modal from the DOM and all related event listeners:

modal.destroy()

Options

There are a number of options for a modal depending on a given purpose. The table below outlines the available options:

Option key Var Type Behavior Required Default
title string Text to be displayed inside .card-title. no null
message string, Array, Nodelist, HTMLElement Content to be displayed inside .card-body >. no null
classes string Any additional classes to pass to the modal no null
custom Boolean Creates an un-formatted modal based on content no false
state string Initial state when first created - open or closed. no open
overlay string Boolean Either light , dark or false if no overlay is wanted no dark
closeAnywhere boolean Modal can be closed by clicking anywhere outside of it. no true
cancelBtn string Inner text on cancel button. No cancel button will be rendered if not provided. no null
cancelClass string Btn variant/context class for cancel btn. e.g .btn-danger. no null
confirmBtn string Inner text on confirm button. No confirm button will be rendered if not provided. no null
confirmClass string Btn variant/context class for cancel btn. e.g .btn-success. no ``
callbackBuilt function Callback function to be called when modal is built but not rendered. no null
callbackRender function Callback function to be called when modal is rendered into DOM. no null
callbackOpen function Callback function to be called when modal is opened. no null
callbackClose function Callback function to be called when modal is closed. no null
callbackValidate function Callback function to validate if modal can be closed. Must return boolean no null

HTML Initialization

For basic use-cases where access to the underlying JavaScript is not required, Modals can be enabled through HTML markup via an anchor element with the .js-modal-trigger class.

For basic HTML string content, simply use the data-content attribute with any required string content to populate the modal.

For more complex requirements point to the id of a hidden target element element in the DOM with the data-content attribute. Remember to always include the # character before the ID as this differentiates it from it being interpenetrated as a string.

All other options can be set through data-attributes on the anchor element in hyphen-case. For example to set the closeAnywhere option, you would set the data-close-anywhere="true" attribute.

<button type="button" class="btn js-modal-trigger" data-content="#my-modal">Toggle</button>

<div id="my-modal">...</div>

CSS Customization

Modals use a combination of both local CSS variables on .modal-wrap, .modal-overlay and Sass variables for enhanced component customization and styling.

Default values are set in the scss/_config.scss file in Frontbx's source.

scss/_config.scss
$modal-max-width:               680px !default;
$modal-max-height:              80vh !default;
$modal-shadow:                  3 !default; //0,1,2,3 
$modal-overlay-bg:              rgba(255, 255, 255, 0.8) !default;
$modal-overlay-bg-dark:         rgba(0, 0, 0, 0.5) !default;
$modal-title-size:              1.8rem !default;
$modal-transform-on:            translate3d(0px, 0px, 0px) !default;
$modal-transform-off:           translate3d(0px, -50px, 0px) !default;
$modal-transition:              opacity .225s ease-out .225s, transform .225s ease-out .225s !default;
$modal-overlay-transition:      opacity .225s ease-out !default;
scss/components/_modal.scss
.modal-wrap
{
    --fbx-modal-title-size: #{$modal-title-size};
    --fbx-modal-transition: #{$modal-transition};
    --fbx-modal-max-width: #{$modal-max-width};
    --fbx-modal-max-height: #{$modal-max-height};
    --fbx-modal-transform-on: #{$modal-transform-on};
    --fbx-modal-transform-off: #{$modal-transform-off};
}
.modal-overlay
{
    --fbx-modal-overlay-bg: #{$modal-overlay-bg};
    --fbx-modal-overlay-bg-dark: #{$modal-overlay-bg-dark};
    --fbx-modal-overlay-transition: #{$modal-overlay-transition};
}