Skip to content
ts
import Textarea from "@ui/Textarea.vue"

Textarea

Textareas are input blocks that enable users to write formatted text (format: Markdown). These blocks are used throughout the Funkwhale interface for entering item descriptions, moderation notes, and custom notifications.

ts
const { charLimit = Infinity, placeholder = '', initialLines: minLines = 3, ...props } = defineProps<{
  label?: string,
  placeholder?: string,
  charLimit?: number,
  initialLines?: number | string,
  autofocus?: true,
  required?: true
}>()
ts
const model = defineModel<string>({ required: true })

Create a textarea and attach its input to a value using a v-model of type string (required):

ts
const text = ref("# Funk\nwhale");
template
<Textarea v-model="text" />

Add a label

template
<Spacer size="16" />
<Textarea>
  <template #label>
    About my music <span style="color:red; float:right;">*required</span>
  </template>
</Textarea>

If you just have a string, we have a convenience prop, so instead you can write:

template
<Spacer size="16" />
<Textarea v-model="text" label="About my music" />

Note that the label text sits atop of the upper end of the component. This way, you can define the distance between baselines (the vertical rhythm) with spacers or gaps.

Add a placeholder

template
<Textarea
  v-model="text"
  placeholder="Describe this track here…"
/>

Limit the number of characters

You can set the maximum length (in characters) that a user can enter in a textarea by passing a charLimit prop.

template
<Textarea v-model="text" :charLimit="20" />

Caveats

  • You can still set the model longer than allowed by changing it via a script or another Textarea
  • A line break counts as one character, which may confuse users
  • The character counting algorithm has not been tested on non-Latin based languages
  • Make sure to inform the user beforehand so they know what error to expect (A11y).

Set the initial height

Specify the number of lines with the initial-lines prop (the default is 5):

template
<Textarea v-model="text" initial-lines="1" />

Autofocus

If you add the autofocus attribute, the text input field will receive focus as soon as it is rendered on the page. Make sure to only add this prop to a single component per page!

Require this form to be filled before submitting

The required attribute prevents the submit button of this form.

Make sure to also add an indicator such as the text "required" or a star to prevent confusion.

See mdn on the required attribute if you want to know more.

Additional attributes

Any prop that is not declared in the Props type will be added to the <textarea> element directly. See mdn on textarea attributes here. Examples: autocomplete, cols, minlength, readonly, wrap, disabled etc.

Add custom toolbar items

By default, there are text formatting buttons and a 'preview' toggle button in the toolbar. You can add custom content there by adding them into the default slot. They will be drawn before the preview button.

template
<Textarea v-model="text">
  <Button ghost low-height min-content
    v-if="text !== ''"
    icon="bi-arrow-counterclockwise"
    @click.prevent="reset()">Reset</Button>
</Textarea>

Using this component

A11y Checklist

Accessible textarea

vue
<Textarea
  v-model="text"
  label="Your message"
/>

Guide: Creating accessible forms

See the complete Form example code

Test this component in isolation against WCAG2 criteria