Feat: add floating label to textarea (#7121)

## Summary

Adds the label/name of the widget as a floating label.

## Screenshots

<img width="543" height="469" alt="image"
src="https://github.com/user-attachments/assets/99d70e0b-f7b7-4b62-bf15-a2db8437c886"
/>


<!-- Add screenshots or video recording to help explain your changes -->

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7121-Feat-add-floating-label-to-textarea-2be6d73d3650819c958efa893e0e304a)
by [Unito](https://www.unito.io)

---------

Co-authored-by: github-actions <github-actions@github.com>
This commit is contained in:
Alexander Brown
2025-12-02 19:34:41 -08:00
committed by GitHub
parent 2f87acf9aa
commit 2bf45f23dc
18 changed files with 25 additions and 18 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 130 KiB

After

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 112 KiB

After

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 123 KiB

After

Width:  |  Height:  |  Size: 123 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 KiB

After

Width:  |  Height:  |  Size: 123 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 150 KiB

After

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 142 KiB

After

Width:  |  Height:  |  Size: 143 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 KiB

After

Width:  |  Height:  |  Size: 123 KiB

View File

@@ -179,8 +179,8 @@ describe('WidgetTextarea Value Binding', () => {
const widget = createMockWidget('test')
const wrapper = mountComponent(widget, 'test')
const textarea = wrapper.find('textarea')
expect(textarea.attributes('placeholder')).toBe('test_textarea')
const textareaLabel = wrapper.find('label')
expect(textareaLabel.text()).toBe('test_textarea')
})
it('uses provided placeholder when specified', () => {

View File

@@ -1,24 +1,28 @@
<template>
<Textarea
v-model="modelValue"
v-bind="filteredProps"
:class="cn(WidgetInputBaseClass, 'relative size-full text-xs resize-none')"
:placeholder="placeholder || widget.name || ''"
:aria-label="widget.name"
:readonly="widget.options?.read_only"
:disabled="widget.options?.read_only"
fluid
data-capture-wheel="true"
@pointerdown.capture.stop
@pointermove.capture.stop
@pointerup.capture.stop
@contextmenu.capture.stop
/>
<FloatLabel variant="in">
<Textarea
v-bind="filteredProps"
:id
v-model="modelValue"
:class="cn(WidgetInputBaseClass, 'size-full text-xs resize-none')"
:placeholder
:readonly="widget.options?.read_only"
:disabled="widget.options?.read_only"
fluid
data-capture-wheel="true"
@pointerdown.capture.stop
@pointermove.capture.stop
@pointerup.capture.stop
@contextmenu.capture.stop
/>
<label :for="id">{{ displayName }}</label>
</FloatLabel>
</template>
<script setup lang="ts">
import FloatLabel from 'primevue/floatlabel'
import Textarea from 'primevue/textarea'
import { computed } from 'vue'
import { computed, useId } from 'vue'
import type { SimplifiedWidget } from '@/types/simplifiedWidget'
import { cn } from '@/utils/tailwindUtil'
@@ -39,4 +43,7 @@ const modelValue = defineModel<string>({ default: '' })
const filteredProps = computed(() =>
filterWidgetProps(widget.options, INPUT_EXCLUDED_PROPS)
)
const displayName = computed(() => widget.label || widget.name)
const id = useId()
</script>