Mode

New
GitHub

Directive to apply light, dark, or inverted color mode to any element or region.

Preview

Usage

Use the v-dt-mode directive to control the color mode of a region, component, or element. It creates a scoped region with the specified mode. Descendant elements retain their original styling but are rendered with the specified mode.

Inverting

This effectively removes the need for inverted props or variants on elements or components.

For example, instead of using inverted on a DtButton, use v-dt-mode:invert

Dynamic mode

Bind a reactive variable as the directive arg to switch modes at runtime.

Conditional

Pass a boolean value to conditionally apply or remove the directive. When false, mode attributes are removed entirely.

<dt-button v-dt-mode:invert="isInverted">Button</dt-button>

Guidance

Do

  • Use sparingly for specific needs, not general theming
  • Use only to force a region to a controlled theme for a unique purpose
  • Always test in both light and dark root themes
  • Ensure content remains readable when mode changes

Don’t

  • Do not overuse mode islands, respect user theme preference
  • Do not use purely for decoration. Ensure mode island use serves a functional and unique purpose
  • Avoid nesting deeply. Keep hierarchy shallow for maintainability

How it works

  • CSS tokens activate via [data-dt-mode="light"] and [data-dt-mode="dark"] attribute selectors
  • High-contrast tokens layer via [data-dt-mode][data-dt-contrast="high"]
  • Contrast is inherited from the root <html> element and kept in sync via MutationObserver
  • Material is inherited from the root <html> element the same way — data-dt-material propagates onto the island/directive element so --dt-color-black-* re-binds correctly inside inverted regions
  • For invert mode, the directive reads the nearest ancestor's data-dt-mode, computes the opposite, and reacts when it changes
  • data-dt-brand (theme) and data-dt-material cannot be overridden on mode islands — brand and material are root-level by design (material is paired to brand for visual coherence; see brand-locked materials)

Variants

Inverted

The default mode — inverts relative to the nearest parent mode boundary or the root. When no arg is provided, v-dt-mode defaults to invert.

Light

Explicitly set to light mode regardless of parent or root mode.

Dark

Explicitly set to dark mode regardless of parent or root mode.

Nesting

Mode boundaries can be nested. Each v-dt-mode:invert reads the nearest parent boundary and flips. In this example the first level is explicitly set to light mode, the second level inverts against that, and the third level inverts again.

Custom background

The background surface of a Mode Island defaults to the root surface color. To override, use a CSS Utility class.

Examples

Callbar

A real-world pattern: the callbar container already exists as a semantic element. The directive applies mode theming directly — no wrapper needed.

Positioned Components

Popovers, Dropdowns, Modals, and Hovercards render their content outside the normal DOM tree, so v-dt-mode on the component itself won't reach the positioned element. These components provide a contentMode prop that applies the mode directly to the positioned content.

Component

The <dt-mode-island> component is the underlying abstraction that the directive builds on. The key rendered difference is that it creates a wrapper element, while the directive attaches to mode to the existing element.

Vue API

Directive

import { DtModeDirective } from '@dialpad/dialtone-vue';
app.use(DtModeDirective);

Component

import { DtModeIsland } from '@dialpad/dialtone-vue';

Slots

Name
Type
default

Slot for main content

Props

Name
Default
Type
as
'div'
"div" | "section" | "nav" | "article" | "aside" | "header" | "footer" | "main"

Set this prop to render the mode island as a specific HTML element.

mode
inverted
"inverted" | "light" | "dark"

The mode to apply to the island.

  • 'inverted': Opposite of parent or root mode
  • 'light': Always light mode
  • 'dark': Always dark mode

Accessibility

Purely visual. No semantic HTML impact. Supports high contrast mode via auto contrast inheritance.

Mode documentation last updated Thursday, June 18, 2026