How to use dynamic tailwind classes with JS switch statement and pass them correctly in Vue?

As shown in the MDN docs: https://developer.mozilla.org/en-US/docs/web/javascript/reference/statements/export#using_named_exports


Here is the whole github codebase.

utils/test.js

const getStatusColour = (orderStatus) => {
  let statusColour=""
  switch (orderStatus) {
    case 'new':
      statusColour="bg-green-100 text-green-900"
      break
    case 'preparing':
      statusColour="bg-yellow-400 text-yellow-900"
      break
    case 'ready':
      statusColour="bg-blue-200 text-blue-800"
      break
    case 'delivered':
      statusColour="bg-green-300 text-green-800"
      break
    case 'failed':
      statusColour="bg-red-400 text-red-900"
      break
    default:
      statusColour="bg-gray-100 text-gray-800"
  }
  return statusColour
}

export { getStatusColour }

App.vue

<template>
  <div>
    <div :class="getStatusColour(order.status)">
      This div do have the correct: `bg-green-100 text-green-900` on it
    </div>
  </div>
</template>

<script>
import { getStatusColour } from './utils/test'

export default {
  data() {
    return {
      order: {
        status: 'new',
      },
    }
  },
  methods: {
    getStatusColour,
  },
}
</script>

Here is a github repo to show that your code is working great so far: https://github.com/kissu/so-compute-exported-function


How I do personally handle this kind of flow

callToAction.vue

<button
  class="flex items-center w-auto p-4 text-center ..."
  :class="[
    callToAction.types[color][variant],
    { 'opacity-50 cursor-not-allowed shadow-none': disabled },
  ]"
>
  Nice flexible button
</button>

<script>
export default {
props: {
  color: {
    type: String,
    default: 'primary',
  },
  variant: {
    type: String,
    default: 'enabled',
  },
  disabled: {
    type: Boolean,
    default: false,
  },
},

data() {
  return {
    callToAction: {
      types: {
        primary: {
          enabled: 'disabled:bg-primary-500 hover:bg-primary-700 bg-primary-500 text-primary-500',
          outlined: 'hover:bg-primary-a12 text-primary-500',
          reversed: 'text-primary-500',
        },
        secondary: {
          enabled: 'disabled:bg-secondary-500 hover:bg-secondary-700 bg-secondary-500 text-secondary-500',
          outlined: 'hover:bg-secondary-a12 text-secondary-500',
          reversed: 'text-secondary-500',
        },
        tertiary: {
          enabled: 'disabled:bg-tertiary-500 hover:bg-tertiary-700 bg-tertiary-500 text-tertiary-500',
          outlined: 'hover:bg-tertiary-a12 text-tertiary-500',
          reversed: 'text-tertiary-500',
        },
        bluegray: {
          enabled: 'disabled:bg-bluegray-500 hover:bg-bluegray-700 bg-bluegray-500 text-bluegray-500',
          outlined: 'hover:bg-bluegray-a12 text-bluegray-500',
          reversed: 'text-bluegray-500',
        },
        error: {
          enabled: 'disabled:bg-error-500 hover:bg-error-700 bg-error-500 text-error-500',
          outlined: 'hover:bg-error-a12 text-error-500',
          reversed: 'text-error-500',
        },
      },
    },
  }
}
</script>

Then, call it in other pages/components with something like:

<call-to-action color="tertiary" variant="reversed"></call-to-action>

Or let the defaults do it’s job with color="primary", variant="enabled" and so on…

PS: adding validators to props could be nice, will be more friendly for the other developers working on the project, figuring out all the possible values that can be passed.

Leave a Comment