Non-Modal Dialog

A non-modal dialog is a floating, non-blocking interface element that allows users to continue interacting with the underlying UI while the dialog remains open. It is designed for secondary or supportive tasks that can be performed in parallel with the main workflow.


Basic

  • NonModalDialog component can be controlled by open and onClose props.
  • NonModalDialog component can be self-closed by 3 reasons specified in the NonModalDialogCloseReason type: escape-key | close-icon.
  • NonModalDialog component requires at least one DialogHeader, one DialogContent and one DialogAction to render.

Differences from Modal Dialog

Non-modal dialogs differ from modal dialogs in the following ways:

  • Focus management: Focus is not trapped within the dialog; users can interact with elements outside.

  • Backdrop interaction: Users can click and interact with content behind the dialog.

  • Scroll locking: Main content scrolling is not locked by default.

  • Draggable: Non-modal dialogs are draggable, allowing users to reposition them.

  • Resizable: Non-modal dialogs are resizable, allowing users to resize them.

  • Use case: Suitable for secondary tasks that don’t require immediate attention or blocking the main workflow.

  • Unlike modal dialog, non-modal dialog allows users to continue interacting with the underlying UI while the dialog remains open.

  • Non-modal dialog is draggable by default using the header as a drag handle.

Source Code

import { WarningOutline } from '@ocean-network-express/magenta-ui/icons';
import {
  Button,
  DialogAction,
  DialogContent,
  DialogHeader,
  NonModalDialog,
  Text,
} from '@ocean-network-express/magenta-ui/react';
import { useState } from 'react';

export function Basic() {

Customized Header

  • You can customize the dialog header with additional elements like subtitles or action buttons.
  • Headers can include icons, titles, subtitles, and action buttons like “More Info”.

Source Code

import {
  InfoCircleOutline,
  MenuMoreVerticalOutline,
} from '@ocean-network-express/magenta-ui/icons';
import {
  Button,
  DialogAction,
  DialogContent,
  DialogHeader,
  IconButton,
  NonModalDialog,
  Text,

Customized Close Button

  • You can customize the close button by setting the closeButton prop.

Source Code

import { CloseCircleOutline, WarningOutline } from '@ocean-network-express/magenta-ui/icons';
import {
  Button,
  DialogAction,
  DialogContent,
  DialogHeader,
  IconButton,
  NonModalDialog,
  Text,
} from '@ocean-network-express/magenta-ui/react';
import { useState } from 'react';

Full width

  • The default width of the NonModalDialog component is fit-content. To make it full of available width, set the fullWidth prop to true.

Source Code

import {
  Button,
  DialogAction,
  DialogContent,
  DialogHeader,
  NonModalDialog,
  Text,
} from '@ocean-network-express/magenta-ui/react';
import { useState } from 'react';

function DialogInstance({
  open,

Max width

  • You can change dialog max width by setting maxWidth prop to predefined values: xs, sm, md, lg, xl.
  • The default maxWidth value is sm.

Max width

Value

xs

448px

sm

608px

md

924px

lg

1240px

xl

1556px

Source Code

import {
  Button,
  DialogAction,
  DialogContent,
  DialogHeader,
  DialogProps,
  NonModalDialog,
  Text,
} from '@ocean-network-express/magenta-ui/react';
import * as React from 'react';

const MAX_WIDTH_OPTIONS: NonNullable<DialogProps['maxWidth']>[] = ['xs', 'sm', 'md', 'lg', 'xl'];

Draggable

  • Non-modal dialog are draggable by default, allowing users to reposition them on the screen.
  • Users can drag the dialog by clicking and holding the header area.
  • The dragOffsetTop prop can be used to set the initial vertical position offset from the top of the viewport (default is 80px).

Source Code

<NonModalDialog 
  open={open} 
  onClose={(open) => setOpen(open)}
  dragOffsetTop={100} // Position dialog 100px from top initially
>
  {/* Dialog content */}
</NonModalDialog>

Resizable

  • Non-modal dialog are resizable by default, allowing users to resize them on the screen.
  • Users can resize the dialog by the eight resize handles:
    • Corners: top-left, top-right, bottom-left, bottom-right (resize both width and height)
    • Edges: top, bottom (resize height only), left, right (resize width only)
  • The dialog respects the maxWidth prop as the maximum resizable width.

Using with Form

Source Code

import {
  Autocomplete,
  AutocompleteOption,
  Button,
  DialogAction,
  DialogContent,
  DialogHeader,
  Input,
  ListItemText,
  NonModalDialog,
  Select,
  SelectOption,

Scrolling long content of dialog

When dialog become too long for the user’s viewport or device, the content of the DialogContent will be scrollable.

Source Code

import { WarningOutline } from '@ocean-network-express/magenta-ui/icons';
import {
  Button,
  DialogAction,
  DialogContent,
  DialogHeader,
  NonModalDialog,
  Text,
} from '@ocean-network-express/magenta-ui/react';
import { useState } from 'react';
export function ScrollDialog() {
  const [open, setOpen] = useState(false);

Scroll and return focus

  • Unlike modal dialog, non-modal dialog do not lock the main content scroll by default, allowing users to interact with the underlying page.
  • The lockScroll prop can be set to true to prevent scrolling of the main content when the dialog is open.
  • When a dialog is open, returnFocus prop determines whether the focus should be returned to the element that initiated the dialog when it closes.
  • Default value for returnFocus is true, while lockScroll defaults to false for non-modal dialog.

Source Code

import {
  Button,
  DialogAction,
  DialogContent,
  DialogHeader,
  NonModalDialog,
  Text,
} from '@ocean-network-express/magenta-ui/react';
import React from 'react';

export function ScrollableBodyAndReturnFocus() {
  const [open, setOpen] = React.useState(false);

Accessibility

NonModalDialog component follows WAI-ARIA recommendations on accessibility.

Roles, States, and Properties

NonModalDialog is a regular div[role="dialog"] element. It has states and props as follows:

  • NonModalDialog has aria-modal attribute set to false (unlike modal dialogs).
  • NonModalDialog has aria-labelledby attribute set to the id of the DialogHeader component.
  • NonModalDialog has aria-describedby attribute set to the id of the DialogContent component.

Keyboard interactions

Key

Function

Condition

Tab

Moves focus to next focusable element (including elements outside the dialog).

Unlike modal dialogs, focus is not trapped within the non-modal dialog.

Shift + Tab

Moves focus to previous focusable element (including elements outside the dialog).

Unlike modal dialogs, focus is not trapped within the non-modal dialog.

Enter

Triggers the selected element.

Escape

Closes the dialog.

Can be disabled by setting closeByEscape to false. Only triggers when focus is within the dialog or any of its elements.
Arrow Keys

Moves the dialog position on the screen when the header is focused.

The header shows a focus ring (light magenta) to indicate it can be moved with arrow keys.

Tab Order

1. Header container (if draggable)

2. Start with the first interactive element in the header, from left to right and top to bottom.

3. Proceed left to right and top to bottom through the rest of the body elements.

4. Negative action

5. Secondary action

6. Primary action

7. Corner & edge (if resizable): top, bottom, left, right, top-left, top-right, bottom-left, bottom-right.

Was this page helpful?