Fix padding, color, and move to reka-ui popover (#8164)
- Fixes some options, like decrement, being off center - Fixes button being very hard to see on light themes - Moves the popover to use our fancy new reka-ui Popover component instead of primvue - Since the display control is no longer in the ValueControlPopover, loading is now actually async Most changed lines in `ValueControlPopover` are just indentation. | Before | After | | ------ | ----- | | <img width="360" alt="before" src="https://github.com/user-attachments/assets/5867d70c-a606-4092-a5f8-dd18ecda5b6f" /> | <img width="360" alt="after" src="https://github.com/user-attachments/assets/7bbaf036-77da-4c98-acb0-4b142e4a4761" />| ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-8164-Fix-padding-color-and-move-to-reka-ui-popover-2ed6d73d3650817ea314f04699f1387f) by [Unito](https://www.unito.io) --------- Co-authored-by: github-actions <github-actions@github.com>
|
Before Width: | Height: | Size: 111 KiB After Width: | Height: | Size: 111 KiB |
|
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 55 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 59 KiB |
|
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 58 KiB |
|
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 58 KiB |
|
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 60 KiB |
|
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 60 KiB |
|
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 60 KiB |
|
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 57 KiB |
|
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 59 KiB |
|
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 62 KiB |
|
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 61 KiB |
|
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 63 KiB |
|
Before Width: | Height: | Size: 95 KiB After Width: | Height: | Size: 95 KiB |
|
Before Width: | Height: | Size: 106 KiB After Width: | Height: | Size: 106 KiB |
|
Before Width: | Height: | Size: 106 KiB After Width: | Height: | Size: 105 KiB |
|
Before Width: | Height: | Size: 137 KiB After Width: | Height: | Size: 137 KiB |
|
Before Width: | Height: | Size: 138 KiB After Width: | Height: | Size: 138 KiB |
|
Before Width: | Height: | Size: 105 KiB After Width: | Height: | Size: 105 KiB |
@@ -1,7 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import Popover from 'primevue/popover'
|
||||
import RadioButton from 'primevue/radiobutton'
|
||||
import { computed, ref } from 'vue'
|
||||
import { computed } from 'vue'
|
||||
|
||||
import { useSettingStore } from '@/platform/settings/settingStore'
|
||||
import type { ControlOptions } from '@/types/simplifiedWidget'
|
||||
@@ -14,14 +13,8 @@ type ControlOption = {
|
||||
title: string
|
||||
}
|
||||
|
||||
const popover = ref()
|
||||
const settingStore = useSettingStore()
|
||||
|
||||
const toggle = (event: Event) => {
|
||||
popover.value.toggle(event)
|
||||
}
|
||||
defineExpose({ toggle })
|
||||
|
||||
const controlOptions: ControlOption[] = [
|
||||
{
|
||||
mode: 'fixed',
|
||||
@@ -57,70 +50,63 @@ const controlMode = defineModel<ControlOptions>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Popover
|
||||
ref="popover"
|
||||
class="bg-interface-panel-surface border border-interface-stroke rounded-lg"
|
||||
>
|
||||
<div class="w-113 max-w-md p-4 space-y-4">
|
||||
<div class="text-sm text-muted-foreground leading-tight">
|
||||
{{ $t('widgets.valueControl.header.prefix') }}
|
||||
<span class="text-base-foreground font-medium">
|
||||
{{
|
||||
widgetControlMode === 'before'
|
||||
? $t('widgets.valueControl.header.before')
|
||||
: $t('widgets.valueControl.header.after')
|
||||
}}
|
||||
</span>
|
||||
{{ $t('widgets.valueControl.header.postfix') }}
|
||||
</div>
|
||||
<div class="w-113 max-w-md p-4 space-y-4">
|
||||
<div class="text-sm text-muted-foreground leading-tight">
|
||||
{{ $t('widgets.valueControl.header.prefix') }}
|
||||
<span class="text-base-foreground font-medium">
|
||||
{{
|
||||
widgetControlMode === 'before'
|
||||
? $t('widgets.valueControl.header.before')
|
||||
: $t('widgets.valueControl.header.after')
|
||||
}}
|
||||
</span>
|
||||
{{ $t('widgets.valueControl.header.postfix') }}
|
||||
</div>
|
||||
|
||||
<div class="space-y-2">
|
||||
<div
|
||||
v-for="option in controlOptions"
|
||||
:key="option.mode"
|
||||
class="flex items-center justify-between py-2 gap-7"
|
||||
>
|
||||
<div class="flex items-center gap-2 flex-1 min-w-0">
|
||||
<div
|
||||
class="flex items-center justify-center w-8 h-8 rounded-lg flex-shrink-0 bg-secondary-background border border-border-subtle"
|
||||
<div class="space-y-2">
|
||||
<div
|
||||
v-for="option in controlOptions"
|
||||
:key="option.mode"
|
||||
class="flex items-center justify-between py-2 gap-7"
|
||||
>
|
||||
<div class="flex items-center gap-2 flex-1 min-w-0">
|
||||
<div
|
||||
class="flex items-center justify-center w-8 h-8 rounded-lg flex-shrink-0 bg-secondary-background border border-border-subtle"
|
||||
>
|
||||
<i
|
||||
v-if="option.icon"
|
||||
:class="option.icon"
|
||||
class="text-base text-base-foreground"
|
||||
/>
|
||||
<span
|
||||
v-if="option.text"
|
||||
class="text-xs font-normal text-base-foreground"
|
||||
>
|
||||
<i
|
||||
v-if="option.icon"
|
||||
:class="option.icon"
|
||||
class="text-base text-base-foreground"
|
||||
/>
|
||||
<span
|
||||
v-if="option.text"
|
||||
class="text-xs font-normal text-base-foreground"
|
||||
>
|
||||
{{ option.text }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-0.5 min-w-0 flex-1">
|
||||
<div
|
||||
class="text-sm font-normal text-base-foreground leading-tight"
|
||||
>
|
||||
<span>
|
||||
{{ $t(`widgets.valueControl.${option.title}`) }}
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="text-sm font-normal text-muted-foreground leading-tight"
|
||||
>
|
||||
{{ $t(`widgets.valueControl.${option.description}`) }}
|
||||
</div>
|
||||
</div>
|
||||
{{ option.text }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<RadioButton
|
||||
v-model="controlMode"
|
||||
class="flex-shrink-0"
|
||||
:input-id="option.mode"
|
||||
:value="option.mode"
|
||||
/>
|
||||
<div class="flex flex-col gap-0.5 min-w-0 flex-1">
|
||||
<div class="text-sm font-normal text-base-foreground leading-tight">
|
||||
<span>
|
||||
{{ $t(`widgets.valueControl.${option.title}`) }}
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="text-sm font-normal text-muted-foreground leading-tight"
|
||||
>
|
||||
{{ $t(`widgets.valueControl.${option.description}`) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<RadioButton
|
||||
v-model="controlMode"
|
||||
class="flex-shrink-0"
|
||||
:input-id="option.mode"
|
||||
:value="option.mode"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</Popover>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -3,6 +3,7 @@ import { onClickOutside } from '@vueuse/core'
|
||||
import { computed, ref, useTemplateRef } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import Button from '@/components/ui/button/Button.vue'
|
||||
import { evaluateInput } from '@/lib/litegraph/src/utils/widget'
|
||||
import type { SimplifiedWidget } from '@/types/simplifiedWidget'
|
||||
import { cn } from '@/utils/tailwindUtil'
|
||||
@@ -65,7 +66,6 @@ function updateValue(e: UIEvent) {
|
||||
textEdit.value = false
|
||||
}
|
||||
|
||||
const sharedButtonClass = 'w-8 bg-transparent border-0 text-sm text-smoke-700'
|
||||
const canDecrement = computed(
|
||||
() =>
|
||||
modelValue.value > filteredProps.value.min &&
|
||||
@@ -205,16 +205,17 @@ const sliderWidth = computed(() => {
|
||||
class="bg-primary-background/15 absolute left-0 bottom-0 h-full rounded-lg pointer-events-none"
|
||||
:style="{ width: `${sliderWidth}%` }"
|
||||
/>
|
||||
<button
|
||||
<Button
|
||||
v-if="!buttonsDisabled"
|
||||
data-testid="decrement"
|
||||
:class="
|
||||
cn(sharedButtonClass, 'pi pi-minus', !canDecrement && 'opacity-60')
|
||||
"
|
||||
class="h-full w-8 rounded-r-none hover:bg-base-foreground/20 disabled:opacity-30"
|
||||
variant="muted-textonly"
|
||||
:disabled="!canDecrement"
|
||||
tabindex="-1"
|
||||
@click="modelValue -= stepValue"
|
||||
/>
|
||||
>
|
||||
<i class="pi pi-minus" />
|
||||
</Button>
|
||||
<div class="relative min-w-[4ch] flex-1 py-1.5 my-0.25">
|
||||
<input
|
||||
ref="inputField"
|
||||
@@ -262,16 +263,17 @@ const sliderWidth = computed(() => {
|
||||
</div>
|
||||
|
||||
<slot />
|
||||
<button
|
||||
<Button
|
||||
v-if="!buttonsDisabled"
|
||||
data-testid="increment"
|
||||
:class="
|
||||
cn(sharedButtonClass, 'pi pi-plus', !canIncrement && 'opacity-60')
|
||||
"
|
||||
class="h-full w-8 rounded-l-none hover:bg-base-foreground/20 disabled:opacity-30"
|
||||
variant="muted-textonly"
|
||||
:disabled="!canIncrement"
|
||||
tabindex="-1"
|
||||
@click="modelValue += stepValue"
|
||||
/>
|
||||
>
|
||||
<i class="pi pi-plus" />
|
||||
</Button>
|
||||
</div>
|
||||
</WidgetLayoutField>
|
||||
</template>
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
import { computed, defineAsyncComponent, ref, watch } from 'vue'
|
||||
import type { Component } from 'vue'
|
||||
|
||||
import Popover from '@/components/ui/Popover.vue'
|
||||
import Button from '@/components/ui/button/Button.vue'
|
||||
import type {
|
||||
SimplifiedControlWidget,
|
||||
@@ -19,8 +20,6 @@ const props = defineProps<{
|
||||
|
||||
const modelValue = defineModel<T>()
|
||||
|
||||
const popover = ref()
|
||||
|
||||
const controlModel = ref(props.widget.controlWidget.value)
|
||||
|
||||
const controlButtonIcon = computed(() => {
|
||||
@@ -37,24 +36,24 @@ const controlButtonIcon = computed(() => {
|
||||
})
|
||||
|
||||
watch(controlModel, props.widget.controlWidget.update)
|
||||
|
||||
const togglePopover = (event: Event) => {
|
||||
popover.value.toggle(event)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="relative grid grid-cols-subgrid">
|
||||
<component :is="component" v-bind="$attrs" v-model="modelValue" :widget>
|
||||
<Button
|
||||
variant="textonly"
|
||||
size="sm"
|
||||
class="h-4 w-7 self-center rounded-xl bg-blue-100/30 p-0"
|
||||
@click.stop.prevent="togglePopover"
|
||||
>
|
||||
<i :class="`${controlButtonIcon} text-blue-100 text-xs size-3.5`" />
|
||||
</Button>
|
||||
<Popover>
|
||||
<template #button>
|
||||
<Button
|
||||
variant="textonly"
|
||||
size="sm"
|
||||
class="h-4 w-7 p-0 self-center rounded-xl bg-primary-background/30 hover:bg-primary-background-hover/30"
|
||||
>
|
||||
<i
|
||||
:class="`${controlButtonIcon} text-primary-background text-xs w-full`"
|
||||
/>
|
||||
</Button>
|
||||
</template>
|
||||
<ValueControlPopover v-model="controlModel" />
|
||||
</Popover>
|
||||
</component>
|
||||
<ValueControlPopover ref="popover" v-model="controlModel" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||