Skip to content

[Feature Request] Slots for v-textarea and v-text-field #6820

Open
@lukas-tr

Description

@lukas-tr

Problem to solve

This can be used to provide users with a quick way to input data without cluttering the ui. You are able to tag notes using #Important, make links clickable within text fields and highlight special search terms like assigned-to:me in a search inputs.

Proposed solution

Example:

<template>
  <v-text-field v-model="text" :slots="slots">
    <template slot="days" slot-scope="{ match, removeMatch, deleteText }">
      <!-- removeMatch keeps the text but doesn't render the slot in its place (it will match again if the matched text changes (eg appending a "s" to "day")) -->
      <v-chip @click="removeMatch">
        <v-icon left>mdi-calendar-clock</v-icon>
        <!-- match is the return value of RegExp.exec() -->
        {{match[0]}}
        <!-- deleteText removes the matched text -->
        <v-icon right @click.stop="deleteText">mdi-close</v-icon>
      </v-chip>
    </template>
  </v-text-field>
</template>
<script>
export default {
  data() {
    return {
      text: "",
      slots: [
        {
          // this slot will replace matched text with the component provided via slots ...
          match: /\bin\s+(\d+)\sdays?\b/,
          // ... only if this method returns true
          verify(match) {
            return Number(match[1]) < 100;
          },
          // the name of the slot
          name: "days",
          // limits the number of matches; if the user were to input "in 1 day" twice, only the latter occurence will be matched
          limit: 1,
        },
      ],
    };
  },
};
</script>

The result should look like this example from todoist:

vuetify feature 1
vuetify feature 2

removeMatch should work like this :

vuetify feature 4

There is an example with <a :href="match[0]">{{match[0]}}</a> as template:

vuetify feature 5

Another example with a list of available values:

For this to work, an additional method getItems has to be provided. The list itself should be similar to v-combobox.

<script>
export default {
  data() {
    return {
      text: "",
      projects: [
        // value will be inserted upon click, text will be displayed in the list (if no list-item slot is provided)
        { text: "Inbox", value: "#Inbox" },
        { text: "School", value: "#School" },
        { text: "Demo Project", value: "#Demo Project" },
      ],
      slots: [
        {
          match: /\b#([\w\s])+\b/i,
          verify(match) {
            // only render the chip if the project exists
            return !!this.projects.find(
              (project) => project.value === match[1],
            );
          },
          // all items to display in the list, can be customized using the list-item slot
          getItems() {
            return new Promise((resolve) => {
              setTimeout(() => {
                resolve(this.projects);
              }, 500);
            });
          },
          name: "project",
          // no limit
          limit: 0,
        },
      ],
    };
  },
};
</script>

vuetify feature 3

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions