Is it possible to instruct Vue to prioritize the inherited class over others?

I have a situation in my component where I need Vue to disregard the existing class and instead use the inherited class, but only if it is of the same type as the inherited class. Let me illustrate with an example:

Consider a button component like this

MyButton.vue

<button class="text-sm font-roboto justify-center text-red-500">
  <slot></slot>
</button>

In my project, I want to use the MyButton component but override the classes justify-center and text-red-500 with my own, like so:

<MyButton class="justify-start text-gray-100">click me</MyButton>

This should result in the following button being rendered:

<button class="text-sm font-roboto justify-center text-red-500 justify-start text-gray-100">
  click me
</button>

The issue arises when HTML prioritizes the class justify-center over justify-start. I wish for Vue to intelligently handle Tailwind classes, recognizing that if it originally had justify-center and now I provide justify-start, it should replace rather than add them both.

This behavior should extend to all Tailwind classes – replacing rather than adding original text-...., font, color, shadow, etc., classes with the new ones.

Therefore, the desired output would be:

<button class="text-sm font-roboto justify-start text-gray-100">
  click me
</button>

Answer №1

After much perseverance, I was able to achieve my goal with the help of an external tool called windtail-fusion

<template>
    <button :class="buttonStyle">
        <slot></slot>
        <i class="text-base text-gray-400 font-normal">
        class="{{ buttonStyle }}"</i>
    </button>
</template>

<script setup lang="ts">
    import { computed, useAttrs } from 'vue'
    import { windtailFusion } from 'windtail-fusion'

    const attrs = useAttrs()

    const buttonStyle = computed(() => {
        return windtailFusion('font-bold text-3xl justify-center text-red-500 ', attrs.class)
    })
</script>

<script lang="ts">
    export default {
        inheritAttrs: false
    }
</script>

Answer №2

From my perspective, you have two choices:

  1. When it comes to alignment, color, and so on, you can set props with the default classname values:
props: {
  alignment: 'start',
  // other props
},

Then link these props to the CSS class and apply them accordingly.

  1. Another option is to utilize vue directives:
Vue.directive('tailwind', {
  bind: function(el, binding, vnode) {
    let currentClasses = el.classList;
    for (let i = 0; i < currentClasses.length; i++) {
      let className = currentClasses[i];
      if (className.startsWith('text-') || className.startsWith('justify-') || className.startsWith('font-')) {
        el.classList.remove(className);
      }
    }
  },
  update: function(el, binding, vnode) {
     let newClasses = binding.value.split(' ');
    for (let i = 0; i < newClasses.length; i++) {
      let className = newClasses[i];
      if (className.startsWith('text-') || className.startsWith('justify-') || className.startsWith('font-')) {
        el.classList.add(className);
      }
    }
  }
});

This directive can now be implemented as follows:

<button v-tailwind="class" class="text-sm font-roboto justify-center text-red-500">
  <slot></slot>
</button>

<MyButton class="justify-start text-gray-100">click me</MyButton>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is there a way to remove the entire row if I dismiss a bootstrap alert?

Hey there! I'm having a little issue with an alert in a row-fluid. Curious to see? Check out my fiddle. So, when I click the "x" button to dismiss the alert, the row is still visible. Any idea how I can make the entire row disappear when I dismiss it? ...

Retrieving information from a form containing a list of numerous values

Thank you all for taking the time to review my code. Unfortunately, I couldn't solve the issue until I went through more code and redid everything. Eventually, I found the solution using PHP for the form: Here's my HTML form (some descriptions a ...

Issue with displaying or loading Google font in NextJS website

After carefully following the provided documentation, I created a _document.js file with the specified code: import Document, { Html, Head, Main, NextScript } from 'next/document' class MyDocument extends Document { static async getInitialProp ...

Having trouble with Vue 3 Composition API's Provide/Inject feature in Single File Components?

I am currently developing a VueJS 3 library using the Composition API. I have implemented Provide/Inject as outlined in the documentation. However, I am encountering an issue where the property in the child component remains undefined, leading to the follo ...

"Unraveling the Mystery: In Javascript Vue, what is the secret behind the origin of the variable 'e' found in the function

Where does the mysterious variable e in onFileChange(e) come from? In the code snippet below, we see a variable e being used in onFileChange(e). However, this variable is not declared or imported anywhere in the code. How is it possible for this to be val ...

Vue.js encountered a problem with chokidar stating: "Error: EBUSY: resource busy or locked, lstat 'C:hiberfil.sys'"

Description Whenever I execute the command npm run serve, I encounter the following error: ERROR Failed to compile with 1 error 15:34:19 This dependency was not found: * ... in ./node_ ...

Tips for keeping a div element at the top of the page

I am looking to have a div stick to the top of the page when someone scrolls down When the page is scrolled, the green div with class stickdiv should automatically stick to the top var left = document.getElementsByClassName("stickdiv"); for( var i = 0; ...

Obtaining font resources within a Vue application on a WordPress page template

When it comes to posting a question, I usually refrain from doing so unless I truly cannot find an answer. Unfortunately, that seems to be the case now. I am currently managing a project where a Vue app is being deployed within a page of a WordPress site. ...

The styled components can create identical CSS classes with varying conditions

Below are the CSS styles I am currently using: import styled, { css } from "styled-components"; const H4 = css` font-family: "Futura"; font-style: normal; font-weight: 500; font-size: 20px; line-height: 140%; color: #3a786a ...

Looking for a way to limit the number of characters allowed per line in a textarea using jQuery

I have the following HTML textarea: <textarea name="splitRepComments" cols="20" rows="3" ></textarea> I have implemented a maxlength restriction using jQuery with the following function: var max = 100; $('#splitRepComments').bind(" ...

Ways to animate a main element independently of its counterpart's animation

I want to create an animation for a parent element without affecting the child's animation. My HTML & CSS structure is set up as follows: .parent{ background-image: url('https://pm1.narvii.com/6195/421ddbf8c9a2fb1715ef833f869164dc1be ...

Artwork expanding incorrectly on HTML canvas

I'm encountering an issue while attempting to draw on an HTML canvas. I've specified 50 circles and multiple lines within a canvas of size 1000x1000 px, but not all circles are appearing as expected. My assumption is that the elements are being ...

The most sophisticated method for creating a 2x2 grid of divs

I have developed a quiz application similar to Buzzfeed with four answer options for each question. The layout on mobile devices is satisfactory, displayed in a 2x2 grid. However, when viewing the app on desktop screens, the answers appear horizontally in ...

Adjusting image width using jQuery

I have been experimenting with creating a Webgl hover effect for an image. The effect works well, but now I am trying to specify a width for the image within jQuery. new hoverEffect({ parent: document.querySelector('.ticket'), intensity1: 0. ...

Adjust Vuetify v-alert property dynamically

Hey there, I'm facing an issue trying to change the type of a v-alert component within a method. Here's the snippet of my code: <v-alert type="{{alertType}}"> I'm a success alert. </v-alert> I attempted to bin ...

Accessing JavaScript results in PHP

Hello everyone! I am working on creating a dropdown menu for selecting time using JavaScript to get the computer's current time. My goal is to have an output that automatically selects the option in the dropdown if it matches the computer's time. ...

changing the css transformation into zoom and positioning

My goal is to incorporate pinch zoom and panning using hardware-accelerated CSS properties like transform: translate3d() scale3d(). After completing the gesture, I reset the transform and switch to CSS zoom along with absolute positioning. This method ensu ...

Listening for position changes using jQuery events

It is essential to be able to track the relative position of elements, especially when dealing with dynamic layout issues. Unfortunately, there are no built-in options in CSS to listen for changes in position() or offset() attributes. Reason: Changes in a ...

Can you provide tips on leveraging CSS as a prop for a Vuetify v-tab component?

Currently, I am in the process of updating my website to simplify color palette swapping. We are still experimenting with different colors that work well together. Our stack includes Vue and Vuetify, with SCSS generating our primary CSS file. Most of our c ...

What is the best way to implement page navigation within Nuxt?

Is there a way to efficiently paginate and display comments from this particular API? Should we retrieve the entire object and use slice() for pagination, or is there a specific method for fetching comments in chunks for a single page? Furthermore, how c ...