refactor(ui): move Toggle component to Composition API + TS (#3281)

* refactor(frontend): move Toggle component to Composition API + TS

**Toggle.vue**:
- Enable composition API and TS
- Added `disabled` to props
- Remove redundant `checked`
- Replace `modelValue` and `emits` with `defineModel` compiler macro

**Others**:
- Replace emit handling and `model-value` with `v-model` where simple logic was used
  - Not `FeatureFlagSettings.vue` (contained custom code on receiving emit)
  - Not `Mods.vue` (contained custom code on receiving emit)
- Remove redundant `checked` attribute

* fix(app): toggles not updating value
This commit is contained in:
Erb3
2025-02-21 19:43:49 +01:00
committed by GitHub
parent 719b395b7b
commit 195cc9cee0
9 changed files with 35 additions and 110 deletions

View File

@@ -5,7 +5,7 @@ import { handleError } from '@/store/notifications'
import { defineMessages, useVIntl } from '@vintl/vintl'
import { get } from '@/helpers/settings'
import { edit } from '@/helpers/profile'
import type { InstanceSettingsTabProps, AppSettings } from '../../../helpers/types'
import type { AppSettings, InstanceSettingsTabProps } from '../../../helpers/types'
const { formatMessage } = useVIntl()
@@ -114,7 +114,6 @@ const messages = defineMessages({
<Toggle
id="fullscreen"
:model-value="overrideWindowSettings ? fullscreenSetting : globalSettings.force_fullscreen"
:checked="fullscreenSetting"
:disabled="!overrideWindowSettings"
@update:model-value="
(e) => {

View File

@@ -1,8 +1,8 @@
<script setup lang="ts">
import { Toggle, ThemeSelector, TeleportDropdownMenu } from '@modrinth/ui'
import { TeleportDropdownMenu, ThemeSelector, Toggle } from '@modrinth/ui'
import { useTheming } from '@/store/state'
import { get, set } from '@/helpers/settings'
import { watch, ref } from 'vue'
import { ref, watch } from 'vue'
import { getOS } from '@/helpers/utils'
const themeStore = useTheming()
@@ -46,7 +46,6 @@ watch(
<Toggle
id="advanced-rendering"
:model-value="themeStore.advancedRendering"
:checked="themeStore.advancedRendering"
@update:model-value="
(e) => {
themeStore.advancedRendering = e
@@ -61,16 +60,7 @@ watch(
<h2 class="m-0 text-lg font-extrabold text-contrast">Native Decorations</h2>
<p class="m-0 mt-1">Use system window frame (app restart required).</p>
</div>
<Toggle
id="native-decorations"
:model-value="settings.native_decorations"
:checked="settings.native_decorations"
@update:model-value="
(e) => {
settings.native_decorations = e
}
"
/>
<Toggle id="native-decorations" v-model="settings.native_decorations" />
</div>
<div class="mt-4 flex items-center justify-between">
@@ -78,16 +68,7 @@ watch(
<h2 class="m-0 text-lg font-extrabold text-contrast">Minimize launcher</h2>
<p class="m-0 mt-1">Minimize the launcher when a Minecraft process starts.</p>
</div>
<Toggle
id="minimize-launcher"
:model-value="settings.hide_on_process_start"
:checked="settings.hide_on_process_start"
@update:model-value="
(e) => {
settings.hide_on_process_start = e
}
"
/>
<Toggle id="minimize-launcher" v-model="settings.hide_on_process_start" />
</div>
<div class="mt-4 flex items-center justify-between">
@@ -111,7 +92,6 @@ watch(
<Toggle
id="toggle-sidebar"
:model-value="settings.toggle_sidebar"
:checked="settings.toggle_sidebar"
@update:model-value="
(e) => {
settings.toggle_sidebar = e

View File

@@ -57,16 +57,7 @@ watch(
</p>
</div>
<Toggle
id="fullscreen"
:model-value="settings.force_fullscreen"
:checked="settings.force_fullscreen"
@update:model-value="
(e) => {
settings.force_fullscreen = e
}
"
/>
<Toggle id="fullscreen" v-model="settings.force_fullscreen" />
</div>
<div class="flex items-center justify-between gap-4">

View File

@@ -37,7 +37,6 @@ watch(
<Toggle
id="advanced-rendering"
:model-value="getStoreValue(option)"
:checked="getStoreValue(option)"
@update:model-value="() => setStoreValue(option, !themeStore.featureFlags[option])"
/>
</div>

View File

@@ -30,16 +30,7 @@ watch(
option, you opt out and ads will no longer be shown based on your interests.
</p>
</div>
<Toggle
id="personalized-ads"
:model-value="settings.personalized_ads"
:checked="settings.personalized_ads"
@update:model-value="
(e) => {
settings.personalized_ads = e
}
"
/>
<Toggle id="personalized-ads" v-model="settings.personalized_ads" />
</div>
<div class="mt-4 flex items-center justify-between gap-4">
@@ -51,16 +42,7 @@ watch(
longer be collected.
</p>
</div>
<Toggle
id="opt-out-analytics"
:model-value="settings.telemetry"
:checked="settings.telemetry"
@update:model-value="
(e) => {
settings.telemetry = e
}
"
/>
<Toggle id="opt-out-analytics" v-model="settings.telemetry" />
</div>
<div class="mt-4 flex items-center justify-between gap-4">
@@ -75,10 +57,6 @@ watch(
as those added by mods. (app restart required to take effect)
</p>
</div>
<Toggle
id="disable-discord-rpc"
v-model="settings.discord_rpc"
:checked="settings.discord_rpc"
/>
<Toggle id="disable-discord-rpc" v-model="settings.discord_rpc" />
</div>
</template>

View File

@@ -179,7 +179,6 @@
<Toggle
class="!mx-2"
:model-value="!item.data.disabled"
:checked="!item.data.disabled"
@update:model-value="toggleDisableMod(item.data)"
/>
<ButtonStyled type="transparent" circular>

View File

@@ -40,12 +40,7 @@
</span>
<span> Whether or not the subscription should be unprovisioned on refund. </span>
</label>
<Toggle
id="unprovision"
:model-value="unprovision"
:checked="unprovision"
@update:model-value="() => (unprovision = !unprovision)"
/>
<Toggle id="unprovision" v-model="unprovision" />
</div>
<div class="flex gap-2">
<ButtonStyled color="brand">
@@ -114,7 +109,7 @@
</div>
</template>
<script setup>
import { Badge, NewModal, ButtonStyled, DropdownSelect, Toggle } from "@modrinth/ui";
import { Badge, ButtonStyled, DropdownSelect, NewModal, Toggle } from "@modrinth/ui";
import { formatPrice } from "@modrinth/utils";
import { CheckIcon, XIcon } from "@modrinth/assets";
import { products } from "~/generated/state.json";

View File

@@ -225,7 +225,7 @@
</template>
</div>
<div class="preview">
<Toggle id="preview" v-model="previewMode" :checked="previewMode" />
<Toggle id="preview" v-model="previewMode" />
<label class="label" for="preview"> Preview </label>
</div>
</div>
@@ -263,31 +263,31 @@
</template>
<script setup lang="ts">
import { type Component, computed, ref, onMounted, onBeforeUnmount, toRef, watch } from 'vue'
import { type Component, computed, onBeforeUnmount, onMounted, ref, toRef, watch } from 'vue'
import { Compartment, EditorState } from '@codemirror/state'
import { EditorView, keymap, placeholder as cm_placeholder } from '@codemirror/view'
import { markdown } from '@codemirror/lang-markdown'
import { indentWithTab, historyKeymap, history } from '@codemirror/commands'
import { history, historyKeymap, indentWithTab } from '@codemirror/commands'
import {
AlignLeftIcon,
BoldIcon,
CodeIcon,
Heading1Icon,
Heading2Icon,
Heading3Icon,
BoldIcon,
ImageIcon,
InfoIcon,
ItalicIcon,
ScanEyeIcon,
StrikethroughIcon,
CodeIcon,
LinkIcon,
ListBulletedIcon,
ListOrderedIcon,
TextQuoteIcon,
LinkIcon,
ImageIcon,
YouTubeIcon,
AlignLeftIcon,
PlusIcon,
XIcon,
ScanEyeIcon,
StrikethroughIcon,
TextQuoteIcon,
UploadIcon,
InfoIcon,
XIcon,
YouTubeIcon,
} from '@modrinth/assets'
import { markdownCommands, modrinthMarkdownEditorKeymap } from '@modrinth/utils/codemirror'
import { renderHighlightedString } from '@modrinth/utils/highlight'

View File

@@ -1,35 +1,19 @@
<template>
<input
:id="id"
type="checkbox"
class="switch stylized-toggle"
:id="id"
:disabled="disabled"
:checked="checked"
@change="toggle"
@change="checked = !checked"
/>
</template>
<script>
export default {
props: {
id: {
type: String,
required: true,
},
modelValue: {
type: Boolean,
},
checked: {
type: Boolean,
required: true,
},
},
emits: ['update:modelValue'],
methods: {
toggle() {
if (!this.disabled) {
this.$emit('update:modelValue', !this.modelValue)
}
},
},
}
<script setup lang="ts">
defineProps<{
id?: string
disabled?: boolean
}>()
const checked = defineModel<boolean>()
</script>