Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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,7 +1,7 @@
<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'
Expand Down Expand Up @@ -56,29 +56,20 @@ const controlOptions: ControlOption[] = [
text: '-1',
title: 'decrement',
description: 'decrementDesc'
},
{
mode: NumberControlMode.FIXED,
icon: 'icon-[lucide--pencil-off]',
title: 'fixed',
description: 'fixedDesc'
}
]

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 controlMode = defineModel<NumberControlMode>()

const handleEditSettings = () => {
popover.value.hide()
Expand Down Expand Up @@ -147,15 +138,11 @@ 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>
Expand Down
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>