Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

A Vue 3 text input component, that let's you style text with Regex and UnoCSS in real time

License

Notifications You must be signed in to change notification settings

Rettend/vue-text-styler

Open more actions menu

Repository files navigation

vue-text-styler

Netlify Status

Demo

📦 Install

npm i vue-text-styler
yarn add vue-text-styler
pnpm i vue-text-styler
// main.ts
import TextStyler from 'vue-text-styler'

// for global registration
app.component(TextStyler)

🧰 Props

Name Type Default Description
text string A string representing the text to be displayed in the component.
special Record<string, string | string[] | RegExp | RegExp[]> An object that contains key-value pairs. The keys represent the classes that will be applied to the text that matches the value. The value can be a string or an array of strings representing the text that will be matched.
line? 'single' | 'multiple' 'multiple' By default, the component acts like a textarea (though you have to use Shift+Enter). Set this prop to 'single' to force it to display the text in a single line. You propably also want to add @keydown.enter.prevent or e.preventDefault().
track? string | string[] A string or an array of strings from the values of special that will be tracked. If set, the component will emit the strings that were matched.
readonly? boolean false A boolean value indicating whether the component is read-only or not. If set to true, the component will be read-only.

📜 Events

Name Type Description
update:text string Emitted when the text changes.
tracked string[] Emitted when the text matches any of the values of track.

🚀 Usage

Simple example:

<script setup lang="ts">
import { ref } from 'vue'

const text = ref('text1 and text2 are here')

const special = {
  'text-red-600 font-bold': ['text1', 'text2'],
  'underline': 'here',
}
</script>

<template>
  <TextStyler
    v-model:text="text"
    :special="special"
    p-3 bg-gray-100 rounded-xl
  />
</template>

A bit more complex example, where your text is an external object:

<script setup lang="ts">
import { computed, reactive, ref } from 'vue'

const text = ref('I\'m a large red circle.')

const object = reactive({
  color: 'red',
  shape: 'circle',
  size: 'large',
})

const special = computed(() => {
  return {
    'text-red-5 font-bold': object.color,
    'text-blue-5 font-bold': object.shape,
    'text-green-5 font-bold': object.size,
  }
})
</script>

<template>
  <TextStyler
    v-model:text="text"
    :special="special"
    p-3 bg-gray-100 rounded-xl
  />
</template>

A ridiculously complex example, where your text is an external array of objects for some unbeknownst reason:

<script setup lang="ts">
import { computed, reactive, ref } from 'vue'

const text = ref('I\'m John and I\'m 20 years old.\nAnd I\'m Jane and I\'m 21 years old.')

const object = reactive([
  {
    name: 'Jane',
    age: 21,
  },
  {
    name: 'John',
    age: 20,
  },
],
)

const keyNames = {
  name: 'text-green-5 font-bold',
  age: 'text-blue-5 font-bold',
}

const special = computed(() => {
  return {
    ...object.reduce((acc, prop) => {
      // loop over the properties of prop
      for (const key in prop) {
        // use the property value as the key name
        const value = prop[key as keyof typeof prop]
        // use the key name from the keyNames object
        const keyName = keyNames[key as keyof typeof keyNames]
        // check if the key name already exists in the accumulator object
        if (acc[keyName]) {
          // append the new value to the existing array
          acc[keyName].push(value.toString())
        }
        else {
          // create a new array with the first value
          acc[keyName] = [value.toString()]
        }
      }
      return acc
    }, {} as Record<string, string[]>),
  }
})
</script>

<template>
  <TextStyler
    v-model:text="text"
    :special="special"
    p-3 bg-gray-100 rounded-xl
  />
</template>

Note: find more examples in the demo playground

⚠️ Limitations

  • Don't use in Nuclear reactor code, as it uses innerHTML with user-provided content, see more: Vue Security. It might be the case that despite Vue escaping js, and we using html sanitization, it is still vulnerable to attacks. I tried most of these and they didn't work though, so idk.
  • Korean keyboard is broken. The component uses innerHTML on every character so this breaks the Korean input completely. I also tested the Chinese input and that's sometimes a little weird too, so other keyboard layouts may have issues as well.

License

MIT

About

A Vue 3 text input component, that let's you style text with Regex and UnoCSS in real time

Topics

Resources

License

Stars

Watchers

Forks

Sponsor this project

 
Morty Proxy This is a proxified and sanitized view of the page, visit original site.