diff --git a/app/src/main/java/eu/kanade/presentation/browse/SourcesScreen.kt b/app/src/main/java/eu/kanade/presentation/browse/SourcesScreen.kt
index d5b218d51..8bf449755 100644
--- a/app/src/main/java/eu/kanade/presentation/browse/SourcesScreen.kt
+++ b/app/src/main/java/eu/kanade/presentation/browse/SourcesScreen.kt
@@ -3,7 +3,6 @@ package eu.kanade.presentation.browse
 import androidx.compose.foundation.clickable
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.PaddingValues
-import androidx.compose.foundation.layout.Row
 import androidx.compose.foundation.layout.fillMaxWidth
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.lazy.items
@@ -13,7 +12,6 @@ import androidx.compose.material.icons.Icons
 import androidx.compose.material.icons.filled.PushPin
 import androidx.compose.material.icons.outlined.PushPin
 import androidx.compose.material3.AlertDialog
-import androidx.compose.material3.Checkbox
 import androidx.compose.material3.Icon
 import androidx.compose.material3.IconButton
 import androidx.compose.material3.LocalTextStyle
@@ -23,7 +21,6 @@ import androidx.compose.material3.TextButton
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.mutableStateListOf
 import androidx.compose.runtime.remember
-import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.platform.LocalContext
 import androidx.compose.ui.res.stringResource
@@ -35,6 +32,7 @@ import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourceScreenModel.Listi
 import eu.kanade.tachiyomi.util.system.LocaleHelper
 import tachiyomi.domain.source.model.Pin
 import tachiyomi.domain.source.model.Source
+import tachiyomi.presentation.core.components.LabeledCheckbox
 import tachiyomi.presentation.core.components.ScrollbarLazyColumn
 import tachiyomi.presentation.core.components.material.SecondaryItemAlpha
 import tachiyomi.presentation.core.components.material.padding
@@ -273,29 +271,18 @@ fun SourceCategoriesDialog(
         },
         text = {
             Column(Modifier.verticalScroll(rememberScrollState())) {
-                categories.forEach {
-                    Row(
-                        modifier = Modifier
-                            .fillMaxWidth()
-                            .clickable {
-                                if (it in newCategories) {
-                                    newCategories -= it
-                                } else {
-                                    newCategories += it
-                                }
-                            },
-                        verticalAlignment = Alignment.CenterVertically,
-                    ) {
-                        Checkbox(
-                            checked = it in newCategories,
-                            onCheckedChange = null,
-                        )
-
-                        Text(
-                            text = it,
-                            modifier = Modifier.padding(horizontal = MaterialTheme.padding.medium),
-                        )
-                    }
+                categories.forEach { category ->
+                    LabeledCheckbox(
+                        label = category,
+                        checked = category in newCategories,
+                        onCheckedChange = {
+                            if (it) {
+                                newCategories += category
+                            } else {
+                                newCategories -= category
+                            }
+                        },
+                    )
                 }
             }
         },
diff --git a/app/src/main/java/eu/kanade/presentation/history/components/HistoryDialogs.kt b/app/src/main/java/eu/kanade/presentation/history/components/HistoryDialogs.kt
index 40d3ecfa7..0ceab8f61 100644
--- a/app/src/main/java/eu/kanade/presentation/history/components/HistoryDialogs.kt
+++ b/app/src/main/java/eu/kanade/presentation/history/components/HistoryDialogs.kt
@@ -1,12 +1,8 @@
 package eu.kanade.presentation.history.components
 
-import androidx.compose.foundation.interaction.MutableInteractionSource
+import androidx.compose.foundation.layout.Arrangement
 import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.Row
-import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.selection.toggleable
 import androidx.compose.material3.AlertDialog
-import androidx.compose.material3.Checkbox
 import androidx.compose.material3.Text
 import androidx.compose.material3.TextButton
 import androidx.compose.runtime.Composable
@@ -14,12 +10,11 @@ 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.res.stringResource
 import androidx.compose.ui.unit.dp
 import eu.kanade.presentation.theme.TachiyomiTheme
 import eu.kanade.tachiyomi.R
+import tachiyomi.presentation.core.components.LabeledCheckbox
 import tachiyomi.presentation.core.util.ThemePreviews
 
 @Composable
@@ -34,28 +29,16 @@ fun HistoryDeleteDialog(
             Text(text = stringResource(R.string.action_remove))
         },
         text = {
-            Column {
+            Column(
+                verticalArrangement = Arrangement.spacedBy(8.dp),
+            ) {
                 Text(text = stringResource(R.string.dialog_with_checkbox_remove_description))
-                Row(
-                    modifier = Modifier
-                        .padding(top = 16.dp)
-                        .toggleable(
-                            interactionSource = remember { MutableInteractionSource() },
-                            indication = null,
-                            value = removeEverything,
-                            onValueChange = { removeEverything = it },
-                        ),
-                    verticalAlignment = Alignment.CenterVertically,
-                ) {
-                    Checkbox(
-                        checked = removeEverything,
-                        onCheckedChange = null,
-                    )
-                    Text(
-                        modifier = Modifier.padding(start = 4.dp),
-                        text = stringResource(R.string.dialog_with_checkbox_reset),
-                    )
-                }
+
+                LabeledCheckbox(
+                    label = stringResource(R.string.dialog_with_checkbox_reset),
+                    checked = removeEverything,
+                    onCheckedChange = { removeEverything = it },
+                )
             }
         },
         onDismissRequest = onDismissRequest,
diff --git a/app/src/main/java/eu/kanade/presentation/library/DeleteLibraryMangaDialog.kt b/app/src/main/java/eu/kanade/presentation/library/DeleteLibraryMangaDialog.kt
index 1f6317a97..49a9a8360 100644
--- a/app/src/main/java/eu/kanade/presentation/library/DeleteLibraryMangaDialog.kt
+++ b/app/src/main/java/eu/kanade/presentation/library/DeleteLibraryMangaDialog.kt
@@ -1,11 +1,7 @@
 package eu.kanade.presentation.library
 
-import androidx.compose.foundation.clickable
 import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.Row
-import androidx.compose.foundation.layout.fillMaxWidth
 import androidx.compose.material3.AlertDialog
-import androidx.compose.material3.Checkbox
 import androidx.compose.material3.Text
 import androidx.compose.material3.TextButton
 import androidx.compose.runtime.Composable
@@ -13,11 +9,10 @@ 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.res.stringResource
 import eu.kanade.tachiyomi.R
 import tachiyomi.core.preference.CheckboxState
+import tachiyomi.presentation.core.components.LabeledCheckbox
 
 @Composable
 fun DeleteLibraryMangaDialog(
@@ -62,27 +57,18 @@ fun DeleteLibraryMangaDialog(
         text = {
             Column {
                 list.forEach { state ->
-                    val onCheck = {
-                        val index = list.indexOf(state)
-                        if (index != -1) {
-                            val mutableList = list.toMutableList()
-                            mutableList[index] = state.next() as CheckboxState.State<Int>
-                            list = mutableList.toList()
-                        }
-                    }
-
-                    Row(
-                        modifier = Modifier
-                            .fillMaxWidth()
-                            .clickable { onCheck() },
-                        verticalAlignment = Alignment.CenterVertically,
-                    ) {
-                        Checkbox(
-                            checked = state.isChecked,
-                            onCheckedChange = { onCheck() },
-                        )
-                        Text(text = stringResource(state.value))
-                    }
+                    LabeledCheckbox(
+                        label = stringResource(state.value),
+                        checked = state.isChecked,
+                        onCheckedChange = {
+                            val index = list.indexOf(state)
+                            if (index != -1) {
+                                val mutableList = list.toMutableList()
+                                mutableList[index] = state.next() as CheckboxState.State<Int>
+                                list = mutableList.toList()
+                            }
+                        },
+                    )
                 }
             }
         },
diff --git a/app/src/main/java/eu/kanade/presentation/manga/ChapterSettingsDialog.kt b/app/src/main/java/eu/kanade/presentation/manga/ChapterSettingsDialog.kt
index e68ca961f..26264cd9f 100644
--- a/app/src/main/java/eu/kanade/presentation/manga/ChapterSettingsDialog.kt
+++ b/app/src/main/java/eu/kanade/presentation/manga/ChapterSettingsDialog.kt
@@ -12,7 +12,6 @@ import androidx.compose.foundation.verticalScroll
 import androidx.compose.material.icons.Icons
 import androidx.compose.material.icons.outlined.PeopleAlt
 import androidx.compose.material3.AlertDialog
-import androidx.compose.material3.Checkbox
 import androidx.compose.material3.DropdownMenuItem
 import androidx.compose.material3.Icon
 import androidx.compose.material3.MaterialTheme
@@ -34,6 +33,7 @@ import eu.kanade.presentation.components.TabbedDialogPaddings
 import eu.kanade.tachiyomi.R
 import tachiyomi.core.preference.TriState
 import tachiyomi.domain.manga.model.Manga
+import tachiyomi.presentation.core.components.LabeledCheckbox
 import tachiyomi.presentation.core.components.RadioItem
 import tachiyomi.presentation.core.components.SortItem
 import tachiyomi.presentation.core.components.TriStateItem
@@ -215,6 +215,7 @@ private fun SetAsDefaultDialog(
     onConfirmed: (optionalChecked: Boolean) -> Unit,
 ) {
     var optionalChecked by rememberSaveable { mutableStateOf(false) }
+
     AlertDialog(
         onDismissRequest = onDismissRequest,
         title = { Text(text = stringResource(R.string.chapter_settings)) },
@@ -224,20 +225,11 @@ private fun SetAsDefaultDialog(
             ) {
                 Text(text = stringResource(R.string.confirm_set_chapter_settings))
 
-                Row(
-                    modifier = Modifier
-                        .clickable { optionalChecked = !optionalChecked }
-                        .padding(vertical = 8.dp)
-                        .fillMaxWidth(),
-                    horizontalArrangement = Arrangement.spacedBy(12.dp),
-                    verticalAlignment = Alignment.CenterVertically,
-                ) {
-                    Checkbox(
-                        checked = optionalChecked,
-                        onCheckedChange = null,
-                    )
-                    Text(text = stringResource(R.string.also_set_chapter_settings_for_library))
-                }
+                LabeledCheckbox(
+                    label = stringResource(R.string.also_set_chapter_settings_for_library),
+                    checked = optionalChecked,
+                    onCheckedChange = { optionalChecked = it },
+                )
             }
         },
         dismissButton = {
diff --git a/app/src/main/java/eu/kanade/presentation/manga/components/MangaDialogs.kt b/app/src/main/java/eu/kanade/presentation/manga/components/MangaDialogs.kt
index 1f1322dff..f21d40b0a 100644
--- a/app/src/main/java/eu/kanade/presentation/manga/components/MangaDialogs.kt
+++ b/app/src/main/java/eu/kanade/presentation/manga/components/MangaDialogs.kt
@@ -1,17 +1,11 @@
 package eu.kanade.presentation.manga.components
 
 import androidx.compose.foundation.layout.BoxWithConstraints
-import androidx.compose.foundation.layout.Row
 import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.lazy.LazyColumn
-import androidx.compose.foundation.selection.selectable
 import androidx.compose.material3.AlertDialog
-import androidx.compose.material3.Checkbox
-import androidx.compose.material3.MaterialTheme
 import androidx.compose.material3.Text
 import androidx.compose.material3.TextButton
-import androidx.compose.material3.minimumInteractiveComponentSize
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableIntStateOf
@@ -21,13 +15,13 @@ import androidx.compose.runtime.setValue
 import androidx.compose.runtime.toMutableStateList
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
-import androidx.compose.ui.draw.clip
 import androidx.compose.ui.res.stringResource
 import androidx.compose.ui.unit.DpSize
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.window.DialogProperties
 import eu.kanade.tachiyomi.R
 import tachiyomi.domain.manga.interactor.FetchInterval
+import tachiyomi.presentation.core.components.LabeledCheckbox
 import tachiyomi.presentation.core.components.WheelTextPicker
 
 @Composable
@@ -128,33 +122,16 @@ fun SelectScanlatorsDialog(
                 availableScanlators.forEach { current ->
                     item {
                         val isSelected = selected.contains(current)
-                        val onSelectionChanged = {
-                            when (!isSelected) {
-                                true -> selected.add(current)
-                                false -> selected.remove(current)
-                            }
-                        }
-                        Row(
-                            verticalAlignment = Alignment.CenterVertically,
-                            modifier = Modifier
-                                .clip(MaterialTheme.shapes.small)
-                                .selectable(
-                                    selected = isSelected,
-                                    onClick = { onSelectionChanged() },
-                                )
-                                .minimumInteractiveComponentSize()
-                                .fillMaxWidth(),
-                        ) {
-                            Checkbox(
-                                checked = isSelected,
-                                onCheckedChange = null,
-                            )
-                            Text(
-                                text = current,
-                                style = MaterialTheme.typography.bodyMedium,
-                                modifier = Modifier.padding(start = 24.dp),
-                            )
-                        }
+                        LabeledCheckbox(
+                            label = current,
+                            checked = isSelected,
+                            onCheckedChange = {
+                                when (it) {
+                                    true -> selected.add(current)
+                                    false -> selected.remove(current)
+                                }
+                            },
+                        )
                     }
                 }
             }
diff --git a/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsAdvancedScreen.kt b/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsAdvancedScreen.kt
index ac55e61ce..1c8eb8a06 100644
--- a/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsAdvancedScreen.kt
+++ b/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsAdvancedScreen.kt
@@ -9,14 +9,8 @@ import android.webkit.WebStorage
 import android.webkit.WebView
 import android.widget.Toast
 import androidx.annotation.StringRes
-import androidx.compose.foundation.clickable
-import androidx.compose.foundation.layout.Row
-import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.lazy.LazyColumn
 import androidx.compose.material3.AlertDialog
-import androidx.compose.material3.Checkbox
-import androidx.compose.material3.MaterialTheme
 import androidx.compose.material3.Text
 import androidx.compose.material3.TextButton
 import androidx.compose.runtime.Composable
@@ -29,12 +23,9 @@ import androidx.compose.runtime.rememberCoroutineScope
 import androidx.compose.runtime.saveable.rememberSaveable
 import androidx.compose.runtime.setValue
 import androidx.compose.runtime.toMutableStateList
-import androidx.compose.ui.Alignment
-import androidx.compose.ui.Modifier
 import androidx.compose.ui.platform.LocalContext
 import androidx.compose.ui.platform.LocalUriHandler
 import androidx.compose.ui.res.stringResource
-import androidx.compose.ui.unit.dp
 import androidx.compose.ui.window.DialogProperties
 import androidx.core.net.toUri
 import androidx.core.text.HtmlCompat
@@ -95,6 +86,7 @@ import tachiyomi.domain.library.service.LibraryPreferences
 import tachiyomi.domain.manga.interactor.GetAllManga
 import tachiyomi.domain.manga.repository.MangaRepository
 import tachiyomi.domain.source.service.SourceManager
+import tachiyomi.presentation.core.components.LabeledCheckbox
 import tachiyomi.presentation.core.util.collectAsState
 import uy.kohesive.injekt.Injekt
 import uy.kohesive.injekt.api.get
@@ -499,29 +491,16 @@ object SettingsAdvancedScreen : SearchableSettings {
                 LazyColumn {
                     options.forEachIndexed { index, option ->
                         item {
-                            val isSelected = index == 0 || selection.contains(option)
-                            val onSelectionChanged = {
-                                when (!isSelected) {
-                                    true -> selection.add(option)
-                                    false -> selection.remove(option)
-                                }
-                            }
-                            Row(
-                                verticalAlignment = Alignment.CenterVertically,
-                                modifier = Modifier
-                                    .fillMaxWidth()
-                                    .clickable { onSelectionChanged() },
-                            ) {
-                                Checkbox(
-                                    checked = isSelected,
-                                    onCheckedChange = { onSelectionChanged() },
-                                )
-                                Text(
-                                    text = option,
-                                    style = MaterialTheme.typography.bodyMedium,
-                                    modifier = Modifier.padding(start = 12.dp),
-                                )
-                            }
+                            LabeledCheckbox(
+                                label = option,
+                                checked = index == 0 || selection.contains(option),
+                                onCheckedChange = {
+                                    when (it) {
+                                        true -> selection.add(option)
+                                        false -> selection.remove(option)
+                                    }
+                                },
+                            )
                         }
                     }
                 }
diff --git a/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsBackupScreen.kt b/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsBackupScreen.kt
index 266398808..d8e517d0a 100644
--- a/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsBackupScreen.kt
+++ b/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsBackupScreen.kt
@@ -8,20 +8,13 @@ import android.widget.Toast
 import androidx.activity.compose.rememberLauncherForActivityResult
 import androidx.activity.result.contract.ActivityResultContracts
 import androidx.annotation.StringRes
-import androidx.compose.foundation.clickable
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.Row
-import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.heightIn
-import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.lazy.rememberLazyListState
 import androidx.compose.foundation.rememberScrollState
 import androidx.compose.foundation.verticalScroll
 import androidx.compose.material3.AlertDialog
-import androidx.compose.material3.Checkbox
 import androidx.compose.material3.HorizontalDivider
-import androidx.compose.material3.MaterialTheme
 import androidx.compose.material3.Text
 import androidx.compose.material3.TextButton
 import androidx.compose.runtime.Composable
@@ -38,7 +31,6 @@ import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.platform.LocalContext
 import androidx.compose.ui.res.stringResource
-import androidx.compose.ui.unit.dp
 import androidx.core.net.toUri
 import com.hippo.unifile.UniFile
 import eu.kanade.presentation.extensions.RequestStoragePermission
@@ -55,6 +47,7 @@ import eu.kanade.tachiyomi.util.system.copyToClipboard
 import eu.kanade.tachiyomi.util.system.toast
 import kotlinx.coroutines.launch
 import tachiyomi.domain.backup.service.BackupPreferences
+import tachiyomi.presentation.core.components.LabeledCheckbox
 import tachiyomi.presentation.core.components.ScrollbarLazyColumn
 import tachiyomi.presentation.core.util.collectAsState
 import tachiyomi.presentation.core.util.isScrolledToEnd
@@ -164,22 +157,23 @@ object SettingsBackupScreen : SearchableSettings {
                     val state = rememberLazyListState()
                     ScrollbarLazyColumn(state = state) {
                         item {
-                            CreateBackupDialogItem(
-                                isSelected = true,
-                                title = stringResource(R.string.manga),
+                            LabeledCheckbox(
+                                label = stringResource(R.string.manga),
+                                checked = true,
+                                onCheckedChange = {},
                             )
                         }
                         choices.forEach { (k, v) ->
                             item {
                                 val isSelected = flags.contains(k)
-                                CreateBackupDialogItem(
-                                    isSelected = isSelected,
-                                    title = stringResource(v),
-                                    modifier = Modifier.clickable {
-                                        if (isSelected) {
-                                            flags.remove(k)
-                                        } else {
+                                LabeledCheckbox(
+                                    label = stringResource(v),
+                                    checked = isSelected,
+                                    onCheckedChange = {
+                                        if (it) {
                                             flags.add(k)
+                                        } else {
+                                            flags.remove(k)
                                         }
                                     },
                                 )
@@ -208,29 +202,6 @@ object SettingsBackupScreen : SearchableSettings {
         )
     }
 
-    @Composable
-    private fun CreateBackupDialogItem(
-        modifier: Modifier = Modifier,
-        isSelected: Boolean,
-        title: String,
-    ) {
-        Row(
-            verticalAlignment = Alignment.CenterVertically,
-            modifier = modifier.fillMaxWidth(),
-        ) {
-            Checkbox(
-                modifier = Modifier.heightIn(min = 48.dp),
-                checked = isSelected,
-                onCheckedChange = null,
-            )
-            Text(
-                text = title,
-                style = MaterialTheme.typography.bodyMedium.merge(),
-                modifier = Modifier.padding(start = 24.dp),
-            )
-        }
-    }
-
     @Composable
     private fun getRestoreBackupPref(): Preference.PreferenceItem.TextPreference {
         val context = LocalContext.current
diff --git a/app/src/main/java/eu/kanade/presentation/more/settings/screen/advanced/ClearDatabaseScreen.kt b/app/src/main/java/eu/kanade/presentation/more/settings/screen/advanced/ClearDatabaseScreen.kt
index 45bcd3863..fa9e126d4 100644
--- a/app/src/main/java/eu/kanade/presentation/more/settings/screen/advanced/ClearDatabaseScreen.kt
+++ b/app/src/main/java/eu/kanade/presentation/more/settings/screen/advanced/ClearDatabaseScreen.kt
@@ -1,7 +1,6 @@
 package eu.kanade.presentation.more.settings.screen.advanced
 
 import androidx.compose.foundation.clickable
-import androidx.compose.foundation.layout.Arrangement
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.Row
 import androidx.compose.foundation.layout.fillMaxSize
@@ -54,6 +53,7 @@ import tachiyomi.data.Database
 import tachiyomi.domain.source.interactor.GetSourcesWithNonLibraryManga
 import tachiyomi.domain.source.model.Source
 import tachiyomi.domain.source.model.SourceWithCount
+import tachiyomi.presentation.core.components.LabeledCheckbox
 import tachiyomi.presentation.core.components.material.Scaffold
 import tachiyomi.presentation.core.screens.EmptyScreen
 import tachiyomi.presentation.core.screens.LoadingScreen
@@ -107,20 +107,11 @@ class ClearDatabaseScreen : Screen() {
                                 // SY <--
                                 Text(text = stringResource(R.string.clear_database_confirmation))
                                 // SY -->
-                                Row(
-                                    Modifier
-                                        .fillMaxWidth()
-                                        .height(56.dp)
-                                        .clickable(onClick = { keepReadManga = !keepReadManga }),
-                                    horizontalArrangement = Arrangement.SpaceBetween,
-                                    verticalAlignment = Alignment.CenterVertically,
-                                ) {
-                                    Text(stringResource(R.string.clear_db_exclude_read))
-                                    Checkbox(
-                                        checked = keepReadManga,
-                                        onCheckedChange = null,
-                                    )
-                                }
+                                LabeledCheckbox(
+                                    label = stringResource(R.string.clear_db_exclude_read),
+                                    checked = keepReadManga,
+                                    onCheckedChange = { keepReadManga = it },
+                                )
                             }
                             // SY <--
                         },
diff --git a/app/src/main/java/eu/kanade/presentation/more/settings/widget/MultiSelectListPreferenceWidget.kt b/app/src/main/java/eu/kanade/presentation/more/settings/widget/MultiSelectListPreferenceWidget.kt
index 74ed60e01..3059be939 100644
--- a/app/src/main/java/eu/kanade/presentation/more/settings/widget/MultiSelectListPreferenceWidget.kt
+++ b/app/src/main/java/eu/kanade/presentation/more/settings/widget/MultiSelectListPreferenceWidget.kt
@@ -1,30 +1,20 @@
 package eu.kanade.presentation.more.settings.widget
 
-import androidx.compose.foundation.layout.Row
-import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.lazy.LazyColumn
-import androidx.compose.foundation.selection.selectable
 import androidx.compose.material3.AlertDialog
-import androidx.compose.material3.Checkbox
-import androidx.compose.material3.MaterialTheme
 import androidx.compose.material3.Text
 import androidx.compose.material3.TextButton
-import androidx.compose.material3.minimumInteractiveComponentSize
 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.runtime.toMutableStateList
-import androidx.compose.ui.Alignment
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.draw.clip
 import androidx.compose.ui.res.stringResource
-import androidx.compose.ui.unit.dp
 import androidx.compose.ui.window.DialogProperties
 import eu.kanade.presentation.more.settings.Preference
 import eu.kanade.tachiyomi.R
+import tachiyomi.presentation.core.components.LabeledCheckbox
 
 @Composable
 fun MultiSelectListPreferenceWidget(
@@ -55,33 +45,17 @@ fun MultiSelectListPreferenceWidget(
                     preference.entries.forEach { current ->
                         item {
                             val isSelected = selected.contains(current.key)
-                            val onSelectionChanged = {
-                                when (!isSelected) {
-                                    true -> selected.add(current.key)
-                                    false -> selected.remove(current.key)
-                                }
-                            }
-                            Row(
-                                verticalAlignment = Alignment.CenterVertically,
-                                modifier = Modifier
-                                    .clip(MaterialTheme.shapes.small)
-                                    .selectable(
-                                        selected = isSelected,
-                                        onClick = { onSelectionChanged() },
-                                    )
-                                    .minimumInteractiveComponentSize()
-                                    .fillMaxWidth(),
-                            ) {
-                                Checkbox(
-                                    checked = isSelected,
-                                    onCheckedChange = null,
-                                )
-                                Text(
-                                    text = current.value,
-                                    style = MaterialTheme.typography.bodyMedium,
-                                    modifier = Modifier.padding(start = 24.dp),
-                                )
-                            }
+                            LabeledCheckbox(
+                                label = current.value,
+                                checked = isSelected,
+                                onCheckedChange = {
+                                    if (it) {
+                                        selected.add(current.key)
+                                    } else {
+                                        selected.remove(current.key)
+                                    }
+                                },
+                            )
                         }
                     }
                 }
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/track/TrackInfoDialog.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/track/TrackInfoDialog.kt
index 1eb97b760..94e6bbe84 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/track/TrackInfoDialog.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/track/TrackInfoDialog.kt
@@ -2,7 +2,6 @@ package eu.kanade.tachiyomi.ui.manga.track
 
 import android.app.Application
 import android.content.Context
-import androidx.compose.foundation.clickable
 import androidx.compose.foundation.layout.Arrangement
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.Row
@@ -13,7 +12,6 @@ import androidx.compose.foundation.layout.windowInsetsPadding
 import androidx.compose.material.icons.Icons
 import androidx.compose.material.icons.filled.Delete
 import androidx.compose.material3.ButtonDefaults
-import androidx.compose.material3.Checkbox
 import androidx.compose.material3.FilledTonalButton
 import androidx.compose.material3.Icon
 import androidx.compose.material3.MaterialTheme
@@ -33,6 +31,7 @@ import androidx.compose.ui.platform.LocalContext
 import androidx.compose.ui.res.stringResource
 import androidx.compose.ui.text.input.TextFieldValue
 import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.unit.dp
 import cafe.adriel.voyager.core.model.ScreenModel
 import cafe.adriel.voyager.core.model.StateScreenModel
 import cafe.adriel.voyager.core.model.coroutineScope
@@ -75,6 +74,7 @@ import tachiyomi.domain.source.service.SourceManager
 import tachiyomi.domain.track.interactor.DeleteTrack
 import tachiyomi.domain.track.interactor.GetTracks
 import tachiyomi.domain.track.model.Track
+import tachiyomi.presentation.core.components.LabeledCheckbox
 import tachiyomi.presentation.core.components.material.AlertDialogContent
 import tachiyomi.presentation.core.components.material.padding
 import uy.kohesive.injekt.Injekt
@@ -94,10 +94,10 @@ data class TrackInfoDialogHomeScreen(
     override fun Content() {
         val navigator = LocalNavigator.currentOrThrow
         val context = LocalContext.current
-        val sm = rememberScreenModel { Model(mangaId, sourceId) }
+        val screenModel = rememberScreenModel { Model(mangaId, sourceId) }
 
         val dateFormat = remember { UiPreferences.dateFormat(Injekt.get<UiPreferences>().dateFormat().get()) }
-        val state by sm.state.collectAsState()
+        val state by screenModel.state.collectAsState()
 
         TrackInfoDialogHome(
             trackItems = state.trackItems,
@@ -146,7 +146,7 @@ data class TrackInfoDialogHomeScreen(
             },
             onNewSearch = {
                 if (it.tracker is EnhancedTracker) {
-                    sm.registerEnhancedTracking(it)
+                    screenModel.registerEnhancedTracking(it)
                 } else {
                     navigator.push(
                         TrackerSearchScreen(
@@ -261,19 +261,19 @@ private data class TrackStatusSelectorScreen(
     @Composable
     override fun Content() {
         val navigator = LocalNavigator.currentOrThrow
-        val sm = rememberScreenModel {
+        val screenModel = rememberScreenModel {
             Model(
                 track = track,
                 tracker = Injekt.get<TrackerManager>().get(serviceId)!!,
             )
         }
-        val state by sm.state.collectAsState()
+        val state by screenModel.state.collectAsState()
         TrackStatusSelector(
             selection = state.selection,
-            onSelectionChange = sm::setSelection,
-            selections = remember { sm.getSelections() },
+            onSelectionChange = screenModel::setSelection,
+            selections = remember { screenModel.getSelections() },
             onConfirm = {
-                sm.setStatus()
+                screenModel.setStatus()
                 navigator.pop()
             },
             onDismissRequest = navigator::pop,
@@ -314,20 +314,20 @@ private data class TrackChapterSelectorScreen(
     @Composable
     override fun Content() {
         val navigator = LocalNavigator.currentOrThrow
-        val sm = rememberScreenModel {
+        val screenModel = rememberScreenModel {
             Model(
                 track = track,
                 tracker = Injekt.get<TrackerManager>().get(serviceId)!!,
             )
         }
-        val state by sm.state.collectAsState()
+        val state by screenModel.state.collectAsState()
 
         TrackChapterSelector(
             selection = state.selection,
-            onSelectionChange = sm::setSelection,
-            range = remember { sm.getRange() },
+            onSelectionChange = screenModel::setSelection,
+            range = remember { screenModel.getRange() },
             onConfirm = {
-                sm.setChapter()
+                screenModel.setChapter()
                 navigator.pop()
             },
             onDismissRequest = navigator::pop,
@@ -373,20 +373,20 @@ private data class TrackScoreSelectorScreen(
     @Composable
     override fun Content() {
         val navigator = LocalNavigator.currentOrThrow
-        val sm = rememberScreenModel {
+        val screenModel = rememberScreenModel {
             Model(
                 track = track,
                 tracker = Injekt.get<TrackerManager>().get(serviceId)!!,
             )
         }
-        val state by sm.state.collectAsState()
+        val state by screenModel.state.collectAsState()
 
         TrackScoreSelector(
             selection = state.selection,
-            onSelectionChange = sm::setSelection,
-            selections = remember { sm.getSelections() },
+            onSelectionChange = screenModel::setSelection,
+            selections = remember { screenModel.getSelections() },
             onConfirm = {
-                sm.setScore()
+                screenModel.setScore()
                 navigator.pop()
             },
             onDismissRequest = navigator::pop,
@@ -484,7 +484,7 @@ private data class TrackDateSelectorScreen(
     @Composable
     override fun Content() {
         val navigator = LocalNavigator.currentOrThrow
-        val sm = rememberScreenModel {
+        val screenModel = rememberScreenModel {
             Model(
                 track = track,
                 tracker = Injekt.get<TrackerManager>().get(serviceId)!!,
@@ -503,13 +503,13 @@ private data class TrackDateSelectorScreen(
             } else {
                 stringResource(R.string.track_finished_reading_date)
             },
-            initialSelectedDateMillis = sm.initialSelection,
+            initialSelectedDateMillis = screenModel.initialSelection,
             selectableDates = selectableDates,
             onConfirm = {
-                sm.setDate(it)
+                screenModel.setDate(it)
                 navigator.pop()
             },
-            onRemove = { sm.confirmRemoveDate(navigator) }.takeIf { canRemove },
+            onRemove = { screenModel.confirmRemoveDate(navigator) }.takeIf { canRemove },
             onDismissRequest = navigator::pop,
         )
     }
@@ -557,7 +557,7 @@ private data class TrackDateRemoverScreen(
     @Composable
     override fun Content() {
         val navigator = LocalNavigator.currentOrThrow
-        val sm = rememberScreenModel {
+        val screenModel = rememberScreenModel {
             Model(
                 track = track,
                 tracker = Injekt.get<TrackerManager>().get(serviceId)!!,
@@ -579,7 +579,7 @@ private data class TrackDateRemoverScreen(
                 )
             },
             text = {
-                val serviceName = sm.getServiceName()
+                val serviceName = screenModel.getServiceName()
                 Text(
                     text = if (start) {
                         stringResource(R.string.track_remove_start_date_conf_text, serviceName)
@@ -598,7 +598,7 @@ private data class TrackDateRemoverScreen(
                     }
                     FilledTonalButton(
                         onClick = {
-                            sm.removeDate()
+                            screenModel.removeDate()
                             navigator.popUntil { it is TrackInfoDialogHomeScreen }
                         },
                         colors = ButtonDefaults.filledTonalButtonColors(
@@ -643,7 +643,7 @@ data class TrackerSearchScreen(
     @Composable
     override fun Content() {
         val navigator = LocalNavigator.currentOrThrow
-        val sm = rememberScreenModel {
+        val screenModel = rememberScreenModel {
             Model(
                 mangaId = mangaId,
                 currentUrl = currentUrl,
@@ -652,18 +652,18 @@ data class TrackerSearchScreen(
             )
         }
 
-        val state by sm.state.collectAsState()
+        val state by screenModel.state.collectAsState()
 
         var textFieldValue by remember { mutableStateOf(TextFieldValue(initialQuery)) }
         TrackerSearch(
             query = textFieldValue,
             onQueryChange = { textFieldValue = it },
-            onDispatchQuery = { sm.trackingSearch(textFieldValue.text) },
+            onDispatchQuery = { screenModel.trackingSearch(textFieldValue.text) },
             queryResult = state.queryResult,
             selected = state.selected,
-            onSelectedChange = sm::updateSelection,
+            onSelectedChange = screenModel::updateSelection,
             onConfirmSelection = {
-                sm.registerTracking(state.selected!!)
+                screenModel.registerTracking(state.selected!!)
                 navigator.pop()
             },
             onDismissRequest = navigator::pop,
@@ -731,14 +731,14 @@ private data class TrackerRemoveScreen(
     @Composable
     override fun Content() {
         val navigator = LocalNavigator.currentOrThrow
-        val sm = rememberScreenModel {
+        val screenModel = rememberScreenModel {
             Model(
                 mangaId = mangaId,
                 track = track,
                 tracker = Injekt.get<TrackerManager>().get(serviceId)!!,
             )
         }
-        val serviceName = sm.getName()
+        val serviceName = screenModel.getName()
         var removeRemoteTrack by remember { mutableStateOf(false) }
         AlertDialogContent(
             modifier = Modifier.windowInsetsPadding(WindowInsets.systemBars),
@@ -755,21 +755,19 @@ private data class TrackerRemoveScreen(
                 )
             },
             text = {
-                Column {
+                Column(
+                    verticalArrangement = Arrangement.spacedBy(8.dp),
+                ) {
                     Text(
                         text = stringResource(R.string.track_delete_text, serviceName),
                     )
-                    if (sm.isDeletable()) {
-                        val onChange = { removeRemoteTrack = !removeRemoteTrack }
-                        Row(
-                            modifier = Modifier
-                                .fillMaxWidth()
-                                .clickable(onClick = onChange),
-                            verticalAlignment = Alignment.CenterVertically,
-                        ) {
-                            Checkbox(checked = removeRemoteTrack, onCheckedChange = { onChange() })
-                            Text(text = stringResource(R.string.track_delete_remote_text, serviceName))
-                        }
+
+                    if (screenModel.isDeletable()) {
+                        LabeledCheckbox(
+                            label = stringResource(R.string.track_delete_remote_text, serviceName),
+                            checked = removeRemoteTrack,
+                            onCheckedChange = { removeRemoteTrack = it },
+                        )
                     }
                 }
             },
@@ -786,8 +784,8 @@ private data class TrackerRemoveScreen(
                     }
                     FilledTonalButton(
                         onClick = {
-                            sm.unregisterTracking(serviceId)
-                            if (removeRemoteTrack) sm.deleteMangaFromService()
+                            screenModel.unregisterTracking(serviceId)
+                            if (removeRemoteTrack) screenModel.deleteMangaFromService()
                             navigator.pop()
                         },
                         colors = ButtonDefaults.filledTonalButtonColors(
diff --git a/presentation-core/src/main/java/tachiyomi/presentation/core/components/LabeledCheckbox.kt b/presentation-core/src/main/java/tachiyomi/presentation/core/components/LabeledCheckbox.kt
new file mode 100644
index 000000000..0a72e4b0b
--- /dev/null
+++ b/presentation-core/src/main/java/tachiyomi/presentation/core/components/LabeledCheckbox.kt
@@ -0,0 +1,44 @@
+package tachiyomi.presentation.core.components
+
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.heightIn
+import androidx.compose.material3.Checkbox
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.semantics.Role
+import androidx.compose.ui.unit.dp
+
+@Composable
+fun LabeledCheckbox(
+    modifier: Modifier = Modifier,
+    label: String,
+    checked: Boolean,
+    onCheckedChange: (Boolean) -> Unit,
+) {
+    Row(
+        modifier = modifier
+            .clip(MaterialTheme.shapes.small)
+            .fillMaxWidth()
+            .heightIn(min = 48.dp)
+            .clickable(
+                role = Role.Checkbox,
+                onClick = { onCheckedChange(!checked) },
+            ),
+        verticalAlignment = Alignment.CenterVertically,
+        horizontalArrangement = Arrangement.spacedBy(8.dp),
+    ) {
+        Checkbox(
+            checked = checked,
+            onCheckedChange = null,
+        )
+
+        Text(text = label)
+    }
+}