fix: route every toggle switch in the SPA through one new component, for one correct geometry

This commit is contained in:
Florian Sylvain committed 2026-10-19 04:06:34 +02:00
1 parent 340a0ad461
commit 23e88190d9
8 files changed
+37 -34

No files matched your search

+20
View File
@@ -0,0 +1,20 @@
<script setup lang="ts">
import { computed } from 'vue'
type Slots = 'root' | 'container' | 'wrapper' | 'label' | 'description'
const props = defineProps<{
ui?: Partial<Record<Slots, string>>
}>()
const ui = computed(() => ({
...props.ui,
container: ['h-4.5', props.ui?.container].filter(Boolean).join(' '),
base: 'relative h-4.5 w-8 before:absolute before:-inset-3.5 data-[disabled]:opacity-40 sm:before:hidden',
thumb: 'size-3.5 data-[state=checked]:translate-x-3.5',
}))
</script>
<template>
<USwitch :ui="ui" />
</template>
+2 -4
View File
@@ -1,4 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import AppSwitch from '@/components/AppSwitch.vue'
import { t } from '@/i18n' import { t } from '@/i18n'
import ArticleStatusBadge from '@/components/ArticleStatusBadge.vue' import ArticleStatusBadge from '@/components/ArticleStatusBadge.vue'
@@ -55,14 +56,11 @@ const previewOn = defineModel<boolean>('preview', { required: true })
<SaveStatus :state="state" :saved-at="savedAt" @retry="emit('retry')" /> <SaveStatus :state="state" :saved-at="savedAt" @retry="emit('retry')" />
<span class="ml-auto font-mono text-xs text-muted lg:hidden">{{ countText }}</span> <span class="ml-auto font-mono text-xs text-muted lg:hidden">{{ countText }}</span>
<div class="hidden items-center gap-3 lg:flex"> <div class="hidden items-center gap-3 lg:flex">
<USwitch <AppSwitch
v-model="previewOn" v-model="previewOn"
:label="t('Preview')" :label="t('Preview')"
:ui="{ :ui="{
root: 'items-center gap-2', root: 'items-center gap-2',
container: 'h-auto',
base: 'h-4.5 w-8 p-0.5',
thumb: 'size-3.5 bg-default data-[state=checked]:translate-x-2.5',
wrapper: 'ms-0', wrapper: 'ms-0',
label: 'text-sm font-normal text-toned', label: 'text-sm font-normal text-toned',
}" }"
+2 -4
View File
@@ -1,4 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import AppSwitch from '@/components/AppSwitch.vue'
import { t } from '@/i18n' import { t } from '@/i18n'
import type { MessageKey } from '@/i18n/messages' import type { MessageKey } from '@/i18n/messages'
@@ -226,14 +227,11 @@ function onCancel() {
class="w-full min-w-0" class="w-full min-w-0"
/> />
</UFormField> </UFormField>
<USwitch <AppSwitch
v-model="newTabValue" v-model="newTabValue"
:label="t('Open in new tab')" :label="t('Open in new tab')"
:ui="{ :ui="{
root: 'min-h-11 items-center gap-3 md:min-h-10', root: 'min-h-11 items-center gap-3 md:min-h-10',
container: 'h-auto',
base: 'h-4.5 w-8 p-0.5',
thumb: 'size-3.5 bg-default data-[state=checked]:translate-x-2.5',
wrapper: 'ms-0', wrapper: 'ms-0',
label: 'text-base font-medium text-highlighted', label: 'text-base font-medium text-highlighted',
}" }"
+2 -2
View File
@@ -1,4 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import AppSwitch from '@/components/AppSwitch.vue'
import { t } from '@/i18n' import { t } from '@/i18n'
import { computed, nextTick, ref, watch } from 'vue' import { computed, nextTick, ref, watch } from 'vue'
@@ -286,11 +287,10 @@ function reviewDuplicates() {
</span> </span>
</div> </div>
<div class="flex h-11 w-11 shrink-0 items-center justify-center md:h-6 md:w-9"> <div class="flex h-11 w-11 shrink-0 items-center justify-center md:h-6 md:w-9">
<USwitch <AppSwitch
:model-value="switchChecked" :model-value="switchChecked"
:disabled="controlsDisabled" :disabled="controlsDisabled"
aria-labelledby="auto-purge-label" aria-labelledby="auto-purge-label"
:ui="{ base: 'data-[disabled]:opacity-40' }"
@update:model-value="toggle" @update:model-value="toggle"
/> />
</div> </div>
+3 -3
View File
@@ -1,4 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import AppSwitch from '@/components/AppSwitch.vue'
import { t } from '@/i18n' import { t } from '@/i18n'
import { computed, nextTick, ref } from 'vue' import { computed, nextTick, ref } from 'vue'
@@ -439,7 +440,7 @@ function submit() {
@leave="canonicalBlocked" @leave="canonicalBlocked"
/> />
<USwitch <AppSwitch
:model-value="seo.noindex" :model-value="seo.noindex"
:label="t('Hide from search engines')" :label="t('Hide from search engines')"
:description=" :description="
@@ -447,8 +448,7 @@ function submit() {
" "
:ui="{ :ui="{
root: 'items-start gap-3', root: 'items-start gap-3',
base: 'mt-0.5 h-4.5 w-8', container: 'mt-0.5',
thumb: 'size-3.5',
label: 'font-medium text-highlighted', label: 'font-medium text-highlighted',
description: 'text-xs/4.5 text-pretty text-muted', description: 'text-xs/4.5 text-pretty text-muted',
}" }"
+3 -3
View File
@@ -1,4 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import AppSwitch from '@/components/AppSwitch.vue'
import { t } from '@/i18n' import { t } from '@/i18n'
import { computed, reactive, ref } from 'vue' import { computed, reactive, ref } from 'vue'
@@ -544,15 +545,14 @@ async function submit() {
/> />
</DirectoryField> </DirectoryField>
<USwitch <AppSwitch
v-model="values.makeDefault" v-model="values.makeDefault"
:disabled="isCurrentDefault" :disabled="isCurrentDefault"
:label="switchLabel" :label="switchLabel"
:description="switchHelp" :description="switchHelp"
:ui="{ :ui="{
root: 'items-start gap-3', root: 'items-start gap-3',
base: 'mt-0.5 h-4.5 w-8', container: 'mt-0.5',
thumb: 'size-3.5',
label: 'font-medium text-highlighted', label: 'font-medium text-highlighted',
description: 'text-xs/4.5 text-pretty text-muted', description: 'text-xs/4.5 text-pretty text-muted',
}" }"
@@ -1,4 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import AppSwitch from '@/components/AppSwitch.vue'
import { t } from '@/i18n' import { t } from '@/i18n'
import { computed } from 'vue' import { computed } from 'vue'
@@ -360,15 +361,10 @@ function setFormat(value: unknown) {
}}</span> }}</span>
</div> </div>
<div class="pt-0.5"> <div class="pt-0.5">
<USwitch <AppSwitch
v-model="values.generateOnUpload" v-model="values.generateOnUpload"
:disabled="disabled" :disabled="disabled"
aria-labelledby="generate-on-upload-label" aria-labelledby="generate-on-upload-label"
:ui="{
container: 'h-4.5',
base: 'relative h-4.5 w-8 before:absolute before:-inset-3.5 disabled:opacity-40 sm:before:hidden',
thumb: 'size-3.5 data-[state=checked]:translate-x-3.5',
}"
/> />
</div> </div>
</div> </div>
@@ -382,15 +378,10 @@ function setFormat(value: unknown) {
}}</span> }}</span>
</div> </div>
<div class="pt-0.5"> <div class="pt-0.5">
<USwitch <AppSwitch
v-model="values.enabled" v-model="values.enabled"
:disabled="disabled" :disabled="disabled"
aria-labelledby="variant-enabled-label" aria-labelledby="variant-enabled-label"
:ui="{
container: 'h-4.5',
base: 'relative h-4.5 w-8 before:absolute before:-inset-3.5 disabled:opacity-40 sm:before:hidden',
thumb: 'size-3.5 data-[state=checked]:translate-x-3.5',
}"
/> />
</div> </div>
</div> </div>
@@ -1,4 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import AppSwitch from '@/components/AppSwitch.vue'
import { t } from '@/i18n' import { t } from '@/i18n'
import { computed } from 'vue' import { computed } from 'vue'
@@ -36,15 +37,10 @@ const tone = computed(() => {
<template> <template>
<div class="flex items-center gap-2 whitespace-nowrap" :class="tone"> <div class="flex items-center gap-2 whitespace-nowrap" :class="tone">
<USwitch <AppSwitch
:model-value="enabled" :model-value="enabled"
:disabled="locked" :disabled="locked"
:aria-label="t('Enable variant {0}', [name])" :aria-label="t('Enable variant {0}', [name])"
:ui="{
container: 'h-4.5',
base: 'relative h-4.5 w-8 before:absolute before:-inset-3.5 data-[disabled]:opacity-40 sm:before:hidden',
thumb: 'size-3.5 data-[state=checked]:translate-x-3.5',
}"
@update:model-value="emit('toggle', $event)" @update:model-value="emit('toggle', $event)"
/> />
<span class="flex items-center gap-1"> <span class="flex items-center gap-1">