Easy @mention, #hashtag and URL highlight for Vue 2.x
You can install via npm or yarn:
npm install --save vue-highlights
yarn add vue-highlights
And then import the component in your app:
import Vue from 'vue'
import VueHighlights, { autoLink, autoHighlight } from 'vue-highlights'
// Install component
Vue.component(VueHighlights.name, VueHighlights)
You can check a demo here: pggalaviz.github.io/vue-highlights
Let's create our first component:
<template>
<vue-highlights
v-model="text"
:extractUrlsWithoutProtocol="true"
caretColor="#ccc"
placeholder="My custom placeholder..."
usernameClass="my-username-class"
hashtagClass="my-hash-class"
urlClass="my-url-class"
/>
</template>
<script>
export default {
name: 'MyComponent',
data () {
return {
text: text
}
}
}
</script>
As you can see, the component accepts some props:
Prop | Type | Description |
---|---|---|
value | String | The text to highlight (v-model). |
extractUrlsWithoutProtocol | Boolean | As the name says, when active, the compoponet will try to match URLs even when a protocol (http://, https://) is not found. Defaults to true |
caretColor | String | A valid HEX color (eg. #ccc, #ff4545). |
placeholder | String | A placeholder to show when no text is entered. |
usernameClass | String | The CSS class(es) that will be added to a @username match. |
hashtagClass | String | The CSS class(es) that will be added to a #hashtag match. |
urlClass | String | The CSS class(es) that will be added to a URL match. |
The exported component (vue-highlights) renders a text input that highlights all username, hashtag and URL matches. In order to work with this input some CSS classes should be attended, here's an example:
.highlights__content {
position: relative;
}
.highlights__placeholder {
color: #ccc;
position: absolute;
top: 16px;
left: 16px;
z-index: -1;
}
.highlights__body-container {
border-radius: 5px;
border: 1px solid #eaeaea;
padding: 16px;
}
.highlights__body {
min-height: 60px;
}
.highlights {
color: #ff3b8e;
}
With this we should get a working example.
As you can see when we first imported the package, 2 functions are also exported: autoLink and autoHighlight.
Both return a String value which contains our highlighted text. autoLink returns the matches found between anchor tags for links. autoHighlight returns the matches found between span tags for highlight only.
import { autoLink, autoHighlight } from 'vue-highlights'
const text = 'my @username, my #hashtag and myurl.com'
const autoLinked = autoLink(text, {
extractUrlsWithoutProtocol: true, // Defaults to true
targetBlank: true, // Defauls to true, applies only in URLs
usernameClass: 'username-class',
usernameUrlBase: '/users/',
hashtagClass: 'hashtag-class',
hashtagUrlBase: '/myhashtags/',
urlClass: 'url-class'
})
/*
autoLinked:
my <a href="/users/username" title="@username" class="username-class"
data-username="username">@username</a>, my <a href="/myhashtags/hashtag"
title="#hashtag" class="hashtag-class" data-hashtag="hashtag">#hashtag</a>
and <a href="http://myurl.com" target="_blank" class="url-class">myurl.com</a>
*/
const autoHighlighted = autoHighlight(text, {
extractUrlsWithoutProtocol: true, // Defaults to true
usernameClass: 'username-class',
hashtagClass: 'hashtag-class',
urlClass: 'url-class'
})
/*
autoHighlighted:
my <span class="username-class">@username</span>, my <span class="hashtag-class">
#hashtag</span> and <span class="url-class">myurl.com</span>
*/
Now we can render our linked/highlighted text anywhere we like:
<template>
<div class="my-linked-text">
<div v-html="text"></div>
</div>
</template>
<script>
import { autoLink } from 'vue-highlights'
const rawText = 'my @username, my #hashtag and myurl.com'
const autoLinked = autoLink(rawText) // Uses default options
export default {
name: 'MyComponent',
data () {
return {
text: autoLinked
}
}
}
</script>