Logo

Modal

Dialog primitives powered by Angular CDK with trigger, close, layout, and programmatic opening support.

Preview

Usage

TS

import { FrButtonModule } from '@frame-ui-ng/components/button';
import { FrModalModule, FrModalService } from '@frame-ui-ng/components/modal';

HTML

<button frButton [frModalTrigger]="modal">Open modal</button>

<ng-template #modal="frModalContent" frModalContent aria-label="Workspace settings">
  <div frModalPanel>
    <div frModalHeader>
      <h2 frModalTitle>Workspace settings</h2>
      <p frModalDescription>Make focused changes without leaving the current page.</p>
    </div>

    <div frModalBody>
      Modal content goes here.
    </div>

    <div frModalFooter>
      <button frButton appearance="outline" frModalClose>Cancel</button>
      <button frButton [frModalClose]="'saved'">Save changes</button>
    </div>
  </div>
</ng-template>

TS

@Component({
  selector: 'app-settings-modal-body',
  template: `<p>{{ summary }}</p>`,
})
class SettingsModalBodyComponent {
  summary = input('This content is rendered from a dedicated body component.');
}

readonly modal = inject(FrModalService);

openFromCode(): void {
  this.modal.open(SettingsModalBodyComponent, {
    ariaLabel: 'Workspace settings',
    bodyInputs: {
      summary: 'Review the generated workspace settings before saving.',
    },
    description: 'The shell is configured through FrModalConfig.',
    footerActions: [
      { appearance: 'outline', label: 'Cancel', result: 'cancel' },
      { label: 'Save changes', result: 'saved' },
    ],
    title: 'Workspace settings',
    width: '32rem',
  });
}

Examples

Basic

Use a trigger and a template-backed content block for the common modal composition.

Programmatic open

Inject FrModalService when a modal needs to open from application logic instead of a direct trigger.

Without default close button

Set showCloseButton to false when users should choose an explicit footer action.

Disable outside close

Set disableClose on the content template when backdrop clicks should be ignored and the modal must be closed through explicit controls.

Scrollable with sticky footer

Enable scrollable and stickyFooter on the panel for longer content while keeping actions visible.

Custom Styling

Override modal tokens on a local wrapper when a product flow needs a branded surface, stronger radius, or more prominent elevation without replacing the CDK Dialog foundation.

Token Inspector

Hover the modal surface, header, title, description, body, or footer to inspect the tokens that shape the dialog composition.

Workspace settings

A composable modal built on top of Angular CDK Dialog.

Configure a focused workflow without sending people to a new route.

Design Tokens

Use these CSS custom properties to tune the modal surface, backdrop, spacing, radius, shadow, and close affordance.

SCSS


  --frame-modal-backdrop-blur: 3px;
  --frame-modal-backdrop-bg: rgb(0 0 0 / 0.52);
  --frame-modal-bg: var(--frame-background);
  --frame-modal-border: var(--frame-border);
  --frame-modal-color: var(--frame-foreground);
  --frame-modal-muted-color: var(--frame-muted-foreground);
  --frame-modal-radius: var(--frame-radius-lg);
  --frame-modal-shadow: 0 24px 80px rgb(0 0 0 / 0.18), 0 8px 24px rgb(0 0 0 / 0.12);
  --frame-modal-padding: 1.5rem;
  --frame-modal-gap: 1rem;
  --frame-modal-scrollable-height: min(calc(100dvh - 2rem), 28rem);
  --frame-modal-close-bg: transparent;
  --frame-modal-close-color: var(--frame-muted-foreground);
  --frame-modal-close-hover-bg: var(--frame-muted);
  --frame-modal-close-hover-color: var(--frame-foreground);
  --frame-modal-z-index: 1000;