Mode

New
Source

Directive for scoping light, dark, or inverted color mode.

Usage

Use v-dt-mode by default on the element that defines the region. It adds no wrapper and does not paint a background. Choose DtModeIsland when you deliberately want its container and automatic primary surface together, or cannot use the directive.

Both APIs scope token-based styles to the specified color mode. Putting the directive on an existing element preserves layout relationships, such as direct children of a flex or grid container.

Directive or component?

Use v-dt-mode by default for new mode-scoping code.

Situation Recommendation
The region already has a container (section, card, toolbar, or button) v-dt-mode
You need a new container, including a painted surface Usually a native container with v-dt-mode; add d-bgc-primary when needed
You deliberately want the component's container and automatic primary surface together DtModeIsland is a reasonable convenience
You cannot install the currently exported directive plugin DtModeIsland
Explicit light/dark attributes must appear in server-rendered HTML Consider DtModeIsland; verify rendering and hydration in your setup
Positioned overlay content The positioned component's content-mode prop

The current directive applies attributes after mounting; the component binds them in its template. This makes the component worth considering for explicit light/dark server markup. It does not guarantee correct inverted mode, root-derived contrast/material, or hydration in every SSR setup.

The directive and content-mode prop use invert; the component uses mode="inverted".

Basic usage

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
  • Keep data-dt-brand (theme) and data-dt-material at the root; do not set local overrides on mode boundaries. 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 directive scopes color mode without supplying a background. Keep the region's existing background styling, or choose a surface explicitly with d-bgc-primary or the surface prop when using DtBox. For example, <dt-box v-dt-mode:invert surface="primary"> scopes the mode and paints its primary surface. Check foreground and background contrast in both root modes.

The component's d-mode-island class automatically paints var(--dt-color-surface-primary) from the island's active mode. A background utility can override that surface.

These live examples choose backgrounds explicitly with the directive, or use the component's automatic surface:

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. Use their content-mode prop (contentMode in JavaScript) to apply the mode directly to the positioned content.

Mode Island component

Both APIs create scoped mode regions and share utility functions, but have separate implementations. The component renders a container, controlled by its as prop, and paints the active mode's primary surface. The directive attaches to an existing element, such as <span v-dt-mode:invert>...</span>, without adding a container or background.

The component's default mode is inverted, equivalent in intent to the directive's invert argument. See Directive or component? for registration and server-rendering considerations.

Accessibility

Changing color mode is visual. The directive preserves the element's semantics; the component's as prop determines its container semantics. Both inherit the root's high-contrast setting. Check readability against the chosen background in light, dark, and high-contrast modes.

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

Mode documentation last updated Tuesday, October 20, 2026