Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/locales/en/main.json
Original file line number Diff line number Diff line change
Expand Up @@ -2074,6 +2074,8 @@
"incrementDesc": "Adds 1 to the value number",
"decrement": "Decrement Value",
"decrementDesc": "Subtracts 1 from the value number",
"fixed": "Fixed Value",
"fixedDesc": "Leaves value unchanged",
"editSettings": "Edit control settings"
}
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
<script setup lang="ts">
import Button from 'primevue/button'
import Popover from 'primevue/popover'
import ToggleSwitch from 'primevue/toggleswitch'
import RadioButton from 'primevue/radiobutton'
import { computed, ref } from 'vue'

import { useSettingStore } from '@/platform/settings/settingStore'
import { useDialogService } from '@/services/dialogService'

import { NumberControlMode } from '../composables/useStepperControl'

Expand All @@ -19,7 +17,6 @@ type ControlOption = {

const popover = ref()
const settingStore = useSettingStore()
const dialogService = useDialogService()

const toggle = (event: Event) => {
popover.value.toggle(event)
Expand All @@ -40,10 +37,10 @@ const controlOptions: ControlOption[] = [
] as ControlOption[])
: []),
{
mode: NumberControlMode.RANDOMIZE,
icon: 'icon-[lucide--shuffle]',
title: 'randomize',
description: 'randomizeDesc'
mode: NumberControlMode.FIXED,
icon: 'icon-[lucide--pencil-off]',
title: 'fixed',
description: 'fixedDesc'
},
{
mode: NumberControlMode.INCREMENT,
Expand All @@ -56,34 +53,20 @@ const controlOptions: ControlOption[] = [
text: '-1',
title: 'decrement',
description: 'decrementDesc'
},
{
mode: NumberControlMode.RANDOMIZE,
icon: 'icon-[lucide--shuffle]',
title: 'randomize',
description: 'randomizeDesc'
}
]

const widgetControlMode = computed(() =>
settingStore.get('Comfy.WidgetControlMode')
)

const props = defineProps<{
controlMode: NumberControlMode
}>()

const emit = defineEmits<{
'update:controlMode': [mode: NumberControlMode]
}>()

const handleToggle = (mode: NumberControlMode) => {
if (props.controlMode === mode) return
emit('update:controlMode', mode)
}

const isActive = (mode: NumberControlMode) => {
return props.controlMode === mode
}

const handleEditSettings = () => {
popover.value.hide()
dialogService.showSettingsDialog()
}
const controlMode = defineModel<NumberControlMode>()
</script>

<template>
Expand Down Expand Up @@ -147,30 +130,14 @@ const handleEditSettings = () => {
</div>
</div>

<ToggleSwitch
:model-value="isActive(option.mode)"
<RadioButton
v-model="controlMode"
class="flex-shrink-0"
@update:model-value="
(v) =>
v
? handleToggle(option.mode)
: handleToggle(NumberControlMode.FIXED)
"
:input-id="option.mode"
:value="option.mode"
/>
Comment on lines +133 to 138
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Consider accessibility improvements for RadioButton labels.

The RadioButton uses :input-id="option.mode" but there's no explicit <label> element with a matching for attribute. While the descriptive text is adjacent, screen readers may not properly associate the label with the radio button.

Consider wrapping the RadioButton and its descriptive content in a <label> element or adding an explicit label reference for better accessibility.

Example improvement:

-        <div
-          v-for="option in controlOptions"
-          :key="option.mode"
-          class="flex items-center justify-between py-2 gap-7"
-        >
+        <label
+          v-for="option in controlOptions"
+          :key="option.mode"
+          :for="option.mode"
+          class="flex items-center justify-between py-2 gap-7 cursor-pointer"
+        >
           <div class="flex items-center gap-2 flex-1 min-w-0">
             <!-- icon and text content -->
           </div>
           <RadioButton
             v-model="controlMode"
             class="flex-shrink-0"
             :input-id="option.mode"
             :value="option.mode"
           />
-        </div>
+        </label>

This would improve keyboard navigation and screen reader support by making the entire option clickable and properly associating the label with the input.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In src/renderer/extensions/vueNodes/widgets/components/NumberControlPopover.vue
around lines 141 to 146, the RadioButton uses :input-id="option.mode" but the
descriptive text is not tied to the input, which hurts screen reader and
keyboard accessibility; fix by associating the label with the radio input —
either wrap the RadioButton and its descriptive content in a <label> so the
whole option is clickable, or render an explicit <label :for="option.mode"> that
contains the descriptive text and references the same input id; ensure
option.mode values produce unique, valid ids and preserve existing v-model
behavior and focus/keyboard handling.

</div>
</div>
<div class="border-t border-border-subtle"></div>
<Button
class="w-full bg-secondary-background hover:bg-secondary-background-hover border-0 rounded-lg p-2 text-sm"
@click="handleEditSettings"
>
<div class="flex items-center justify-center gap-1">
<i class="pi pi-cog text-xs text-muted-foreground" />
<span class="font-normal text-base-foreground">{{
$t('widgets.numberControl.editSettings')
}}</span>
</div>
</Button>
</div>
</Popover>
</template>
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ const buttonTooltip = computed(() => {
<span class="pi pi-minus text-sm" />
</template>
</InputNumber>
<div class="absolute top-5 right-8 h-4 w-7 -translate-y-4/5">
<div class="absolute top-5 right-8 h-4 w-7 -translate-y-4/5 flex">
<slot />
</div>
</WidgetLayoutField>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
<script setup lang="ts">
import Button from 'primevue/button'
import { defineAsyncComponent, ref } from 'vue'
import { defineAsyncComponent, ref, watch } from 'vue'

import type { SimplifiedWidget } from '@/types/simplifiedWidget'

import type { NumberControlMode } from '../composables/useStepperControl'
import { useStepperControl } from '../composables/useStepperControl'
import WidgetInputNumberInput from './WidgetInputNumberInput.vue'

Expand Down Expand Up @@ -32,10 +31,7 @@ const { controlMode, controlButtonIcon } = useStepperControl(
props.widget.controlWidget!.value
)

const setControlMode = (mode: NumberControlMode) => {
controlMode.value = mode
props.widget.controlWidget!.update(mode)
}
watch(controlMode, props.widget.controlWidget!.update)

const togglePopover = (event: Event) => {
popover.value.toggle(event)
Expand All @@ -58,10 +54,6 @@ const togglePopover = (event: Event) => {
<i :class="`${controlButtonIcon} text-blue-100 text-xs`" />
</Button>
</WidgetInputNumberInput>
<NumberControlPopover
ref="popover"
:control-mode
@update:control-mode="setControlMode"
/>
<NumberControlPopover ref="popover" v-model="controlMode" />
</div>
</template>