diff --git a/src/main/kotlin/androidx/compose/material/ExposedDropDownMenu.kt b/src/main/kotlin/androidx/compose/material/ExposedDropDownMenu.kt
new file mode 100644
index 0000000000000000000000000000000000000000..92450c6cfb65c85c90b92b8508824b12e4ca0d8d
--- /dev/null
+++ b/src/main/kotlin/androidx/compose/material/ExposedDropDownMenu.kt
@@ -0,0 +1,226 @@
+/*
+ * Briar Desktop
+ * Copyright (C) 2021-2022 The Briar Project
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package androidx.compose.material
+
+import androidx.compose.animation.core.animateFloatAsState
+import androidx.compose.foundation.background
+import androidx.compose.foundation.border
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.IntrinsicSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.width
+import androidx.compose.foundation.shape.ZeroCornerSize
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.ArrowDropDown
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.draw.drawBehind
+import androidx.compose.ui.draw.rotate
+import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.geometry.Size
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.Shape
+import androidx.compose.ui.layout.onGloballyPositioned
+import androidx.compose.ui.platform.LocalDensity
+import androidx.compose.ui.platform.LocalFocusManager
+import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.toSize
+import org.briarproject.briar.desktop.utils.PreviewUtils.preview
+
+// ExposedDropDownMenu is not yet available in JetBrains Compose
+// This is a reimplementation while waiting.
+// Taken from https://stackoverflow.com/a/69042850 and slightly adapted to follow Material theming
+// See https://github.com/JetBrains/compose-jb/issues/1673 as tracking issue
+
+fun main() = preview {
+    val values = (0..5).map { "Test $it" }
+    var selected by remember { mutableStateOf(-1) }
+
+    ExposedDropDownMenu(
+        values = values,
+        selectedIndex = selected,
+        onChange = { selected = it },
+    )
+
+    OutlinedExposedDropDownMenu(
+        values = values,
+        selectedIndex = selected,
+        onChange = { selected = it },
+    )
+}
+
+@Composable
+fun ExposedDropDownMenu(
+    values: List<String>,
+    selectedIndex: Int,
+    onChange: (Int) -> Unit,
+    label: @Composable () -> Unit = {},
+    modifier: Modifier = Modifier,
+    backgroundColor: Color = MaterialTheme.colors.onSurface.copy(alpha = TextFieldDefaults.BackgroundOpacity),
+    shape: Shape = MaterialTheme.shapes.small.copy(bottomEnd = ZeroCornerSize, bottomStart = ZeroCornerSize)
+) {
+    ExposedDropDownMenuImpl(
+        values = values,
+        selectedIndex = selectedIndex,
+        onChange = onChange,
+        label = label,
+        modifier = modifier,
+        backgroundColor = backgroundColor,
+        shape = shape,
+        decorator = { color, width, content ->
+            Box(
+                Modifier
+                    .drawBehind {
+                        val strokeWidth = width.value * density
+                        val y = size.height - strokeWidth / 2
+                        drawLine(
+                            color,
+                            Offset(0f, y),
+                            Offset(size.width, y),
+                            strokeWidth
+                        )
+                    }
+            ) {
+                content()
+            }
+        }
+    )
+}
+
+@Composable
+fun OutlinedExposedDropDownMenu(
+    values: List<String>,
+    selectedIndex: Int,
+    onChange: (Int) -> Unit,
+    label: @Composable () -> Unit = {},
+    modifier: Modifier = Modifier,
+    backgroundColor: Color = MaterialTheme.colors.onSurface.copy(alpha = TextFieldDefaults.BackgroundOpacity),
+    shape: Shape = MaterialTheme.shapes.small
+) {
+    ExposedDropDownMenuImpl(
+        values = values,
+        selectedIndex = selectedIndex,
+        onChange = onChange,
+        label = label,
+        modifier = modifier,
+        backgroundColor = backgroundColor,
+        shape = shape,
+        decorator = { color, width, content ->
+            Box(
+                Modifier
+                    .border(width, color, shape)
+            ) {
+                content()
+            }
+        }
+    )
+}
+
+@Composable
+private fun ExposedDropDownMenuImpl(
+    values: List<String>,
+    selectedIndex: Int,
+    onChange: (Int) -> Unit,
+    label: @Composable () -> Unit,
+    modifier: Modifier,
+    backgroundColor: Color,
+    shape: Shape,
+    decorator: @Composable (Color, Dp, @Composable () -> Unit) -> Unit
+) {
+    var expanded by remember { mutableStateOf(false) }
+    var boxSize by remember { mutableStateOf(Size.Zero) }
+
+    val indicatorColor =
+        if (expanded) MaterialTheme.colors.primary.copy(alpha = ContentAlpha.high)
+        else MaterialTheme.colors.onSurface.copy(alpha = TextFieldDefaults.UnfocusedIndicatorLineOpacity)
+    val indicatorWidth = if (expanded) 2.dp else 1.dp
+    val labelColor =
+        if (expanded) MaterialTheme.colors.primary.copy(alpha = ContentAlpha.high)
+        else MaterialTheme.colors.onSurface.copy(alpha = ContentAlpha.medium)
+    val trailingIconColor = MaterialTheme.colors.onSurface.copy(alpha = TextFieldDefaults.IconOpacity)
+
+    val rotation: Float by animateFloatAsState(if (expanded) 180f else 0f)
+
+    val focusManager = LocalFocusManager.current
+
+    Box(modifier = modifier.width(IntrinsicSize.Min)) {
+        decorator(indicatorColor, indicatorWidth) {
+            Box(
+                Modifier
+                    .fillMaxWidth()
+                    .background(color = backgroundColor, shape = shape)
+                    .onGloballyPositioned { boxSize = it.size.toSize() }
+                    .clip(shape)
+                    .clickable {
+                        expanded = !expanded
+                        focusManager.clearFocus()
+                    }
+                    .padding(start = 16.dp, end = 12.dp, top = 7.dp, bottom = 10.dp)
+            ) {
+                Column(Modifier.padding(end = 32.dp).align(Alignment.CenterStart).width(IntrinsicSize.Max)) {
+                    ProvideTextStyle(value = MaterialTheme.typography.caption.copy(color = labelColor)) {
+                        label()
+                    }
+                    if (selectedIndex >= 0 && selectedIndex <= values.size) {
+                        Text(
+                            text = values[selectedIndex],
+                            modifier = Modifier.padding(top = 1.dp)
+                        )
+                    }
+                }
+                Icon(
+                    imageVector = Icons.Filled.ArrowDropDown,
+                    contentDescription = "Change",
+                    tint = trailingIconColor,
+                    modifier = Modifier
+                        .align(Alignment.CenterEnd)
+                        .padding(top = 4.dp)
+                        .rotate(rotation)
+                )
+            }
+        }
+        DropdownMenu(
+            expanded = expanded,
+            onDismissRequest = { expanded = false },
+            modifier = Modifier
+                .width(with(LocalDensity.current) { boxSize.width.toDp() })
+        ) {
+            values.forEachIndexed { i, v ->
+                DropdownMenuItem(
+                    onClick = {
+                        onChange(i)
+                        expanded = false
+                    }
+                ) {
+                    Text(v)
+                }
+            }
+        }
+    }
+}
diff --git a/src/main/kotlin/org/briarproject/briar/desktop/settings/SettingDetails.kt b/src/main/kotlin/org/briarproject/briar/desktop/settings/SettingDetails.kt
index 658177089dc844ed69f3d592e938fe5ec45c013d..83f75609aa95e1e0789b3c6fb62a06d425f483dd 100644
--- a/src/main/kotlin/org/briarproject/briar/desktop/settings/SettingDetails.kt
+++ b/src/main/kotlin/org/briarproject/briar/desktop/settings/SettingDetails.kt
@@ -27,9 +27,10 @@ import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.foundation.layout.fillMaxWidth
 import androidx.compose.foundation.layout.height
 import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.widthIn
 import androidx.compose.material.MaterialTheme
+import androidx.compose.material.OutlinedExposedDropDownMenu
 import androidx.compose.material.Surface
-import androidx.compose.material.Switch
 import androidx.compose.material.Text
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Alignment
@@ -49,9 +50,14 @@ fun SettingDetails(viewModel: SettingsViewModel) {
                 // TODO: Change this to `settings.display.title` once more categories are implemented
                 SettingDetail(i18n("settings.title")) {
                     DetailItem {
-                        Text(i18n("settings.display.theme"))
-                        val isDarkMode = viewModel.isDarkMode.value
-                        Switch(checked = isDarkMode, onCheckedChange = { viewModel.toggleTheme() })
+                        Text(i18n("settings.display.theme.title"))
+
+                        OutlinedExposedDropDownMenu(
+                            values = viewModel.themesList.map { i18n("settings.display.theme.${it.name.lowercase()}") },
+                            selectedIndex = viewModel.selectedTheme.value.ordinal,
+                            onChange = { viewModel.selectTheme(viewModel.themesList[it]) },
+                            modifier = Modifier.widthIn(min = 200.dp)
+                        )
                     }
                 }
             }
diff --git a/src/main/kotlin/org/briarproject/briar/desktop/settings/SettingsViewModel.kt b/src/main/kotlin/org/briarproject/briar/desktop/settings/SettingsViewModel.kt
index 3c3aec2b22b10f5bb049fb2c76a815b279bc25f7..529f95039be0f3a7c9fcbd35f96e320bc4de0869 100644
--- a/src/main/kotlin/org/briarproject/briar/desktop/settings/SettingsViewModel.kt
+++ b/src/main/kotlin/org/briarproject/briar/desktop/settings/SettingsViewModel.kt
@@ -19,8 +19,6 @@
 package org.briarproject.briar.desktop.settings
 
 import androidx.compose.runtime.mutableStateOf
-import org.briarproject.briar.desktop.settings.Settings.Theme.DARK
-import org.briarproject.briar.desktop.settings.Settings.Theme.LIGHT
 import org.briarproject.briar.desktop.viewmodel.ViewModel
 import org.briarproject.briar.desktop.viewmodel.asState
 import javax.inject.Inject
@@ -42,15 +40,17 @@ constructor(
     private val _selectedSetting = mutableStateOf(SettingCategory.DISPLAY)
     val selectedSetting = _selectedSetting.asState()
 
-    private val _isDarkMode = mutableStateOf(settings.theme == DARK)
-    val isDarkMode = _isDarkMode.asState()
+    val themesList = Settings.Theme.values()
+
+    private val _selectedTheme = mutableStateOf(settings.theme)
+    val selectedTheme = _selectedTheme.asState()
 
     fun selectSetting(selectedOption: SettingCategory) {
         _selectedSetting.value = selectedOption
     }
 
-    fun toggleTheme() { // todo: set theme instead
-        settings.theme = if (settings.theme == DARK) LIGHT else DARK
-        _isDarkMode.value = settings.theme == DARK
+    fun selectTheme(theme: Settings.Theme) {
+        settings.theme = theme
+        _selectedTheme.value = theme
     }
 }
diff --git a/src/main/resources/strings/BriarDesktop.properties b/src/main/resources/strings/BriarDesktop.properties
index 67c428179df2bfed55558ac2e9e1ac30381e37ee..48f1732f85d29cd7c8c93a1f3413ef710a4c0ce4 100644
--- a/src/main/resources/strings/BriarDesktop.properties
+++ b/src/main/resources/strings/BriarDesktop.properties
@@ -219,8 +219,6 @@ settings.general.title=General
 
 # Settings Display
 settings.display.title=Display
-# todo: to be removed
-settings.display.theme=Dark Theme
 settings.display.theme.title=Theme
 settings.display.theme.auto=System default
 settings.display.theme.dark=Dark