Component

Theme switcher

<DomThemeSwitcher>

A DOM Studio light, dark, and system theme preference control.

Playground

Try every prop live

Theme switcher playground

The switcher stores the selected DOM Studio theme preference and updates the document theme.

System theme
Playground.vuevue
<script setup>
import { reactive } from 'vue';
import { DomThemeSwitcher } from '@getdom/studio/vue';

const data = reactive({
	  "modelValue": null,
	  "label": "Theme mode",
	  "showLabel": true,
	  "size": "icon-sm"
	});
</script>

<template>
	<DomThemeSwitcher
		v-bind="data"
		@update:modelValue="data.modelValue = $event"
	/>
</template>

Demo

Settings row

Use the labelled row where a menu or settings surface needs to show the current theme preference.

System theme

Stored preference

<script setup>
import { ref } from 'vue';
import { DomThemeSwitcher } from '@getdom/studio/vue';

const lastChange = ref('Stored preference');
</script>

<template>
	<div class="w-full max-w-sm rounded-xl border border-border bg-canvas p-3">
		<DomThemeSwitcher @change="lastChange = `${$event.mode} preference`" />

		<p class="mt-3 text-xs text-muted-fg">
			{{ lastChange }}
		</p>
	</div>
</template>

Demo

Toolbar control

Hide the label when the segmented control sits in compact app chrome.

Northstar Studio

Theme follows the DOM Studio preference.

<script setup>
import { DomThemeSwitcher } from '@getdom/studio/vue';
</script>

<template>
	<div class="flex w-full max-w-xl items-center justify-between rounded-xl border border-border bg-canvas px-3 py-2 shadow-sm">
		<div class="min-w-0">
			<p class="truncate text-sm font-semibold">Northstar Studio</p>
			<p class="truncate text-xs text-muted-fg">Theme follows the DOM Studio preference.</p>
		</div>

		<DomThemeSwitcher :show-label="false" />
	</div>
</template>

Reference

Props

Control props

NameTypeTSDefaultDescription
modelValue'light' | 'dark' | 'system'stringOptional controlled theme mode. Omit this to use the stored DOM Studio preference.
labelstringstring'Theme mode'Accessible label for the segmented control.
showLabelbooleanbooleantrueShow the current preference label beside the segmented control.
size'icon-sm' | 'icon-md' | 'sm' | 'md' | 'lg'string'icon-sm'Button size for the segmented control.

Auto-generated from Theme switcher.props and inline _edit hints.

Events

NamePayloadDescription
@update:modelValue(mode
mode: "light" | "dark" | "system";
: "light" | "dark" | "system")
Emitted when the stored theme mode changes.
@change({ mode, theme })Emitted with the selected preference mode and resolved light or dark theme.

Names auto-detected from defineEmits and source emit() calls; payload and description from __doc.events when present.