{"id":13810525,"url":"https://github.com/lukasborawski/vue-use-variant","last_synced_at":"2025-07-19T11:02:58.362Z","repository":{"id":60470230,"uuid":"408995982","full_name":"lukasborawski/vue-use-variant","owner":"lukasborawski","description":"Vue.js CSS class variant resolver. Presented as a handy composable.","archived":false,"fork":false,"pushed_at":"2023-06-09T22:29:45.000Z","size":269,"stargazers_count":35,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"develop","last_synced_at":"2025-03-30T15:51:09.336Z","etag":null,"topics":["composable","css","styles","tailwind","vue","vue3","vuejs"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/vue-use-variant","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"isc","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lukasborawski.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["lukasborawski"],"buymeacoffee":["lukasborawski"]}},"created_at":"2021-09-21T22:51:05.000Z","updated_at":"2024-04-04T19:34:26.000Z","dependencies_parsed_at":"2024-06-21T02:13:03.810Z","dependency_job_id":"464e590e-4e16-4fa6-9b45-e8f4a6e7a3ab","html_url":"https://github.com/lukasborawski/vue-use-variant","commit_stats":{"total_commits":23,"total_committers":1,"mean_commits":23.0,"dds":0.0,"last_synced_commit":"f8c9633d29855031a53d74ab112f4e03052accdf"},"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lukasborawski%2Fvue-use-variant","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lukasborawski%2Fvue-use-variant/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lukasborawski%2Fvue-use-variant/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lukasborawski%2Fvue-use-variant/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lukasborawski","download_url":"https://codeload.github.com/lukasborawski/vue-use-variant/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249500217,"owners_count":21282368,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["composable","css","styles","tailwind","vue","vue3","vuejs"],"created_at":"2024-08-04T02:00:57.841Z","updated_at":"2025-04-18T13:33:39.631Z","avatar_url":"https://github.com/lukasborawski.png","language":"TypeScript","funding_links":["https://github.com/sponsors/lukasborawski","lukasborawski","https://www.buymeacoffee.com/lukas.borawski"],"categories":["TypeScript"],"sub_categories":[],"readme":"## Vue Use Variant\n\n\u003ca href=\"https://badge.fury.io/js/vue-use-variant\"\u003e\u003cimg src=\"https://d25lcipzij17d.cloudfront.net/badge.svg?id=js\u0026r=r\u0026type=6e\u0026v=0.1.1\u0026x2=0\" alt=\"npm version\" height=\"18\"\u003e\u003c/a\u003e\n\u003ca href=\"https://badge.fury.io/js/vue-use-variant\"\u003e\u003cimg src=\"https://img.shields.io/bundlephobia/min/vue-use-variant\" alt=\"npm version\" height=\"18\"\u003e\u003c/a\u003e\n\u003ca href=\"https://badge.fury.io/js/vue-use-variant\"\u003e\u003cimg src=\"https://img.shields.io/npm/dm/vue-use-variant\" alt=\"npm version\" height=\"18\"\u003e\u003c/a\u003e\n\u003ca href=\"https://badge.fury.io/js/vue-use-variant\"\u003e\u003cimg src=\"https://img.shields.io/npm/l/vue-use-variant\" alt=\"npm version\" height=\"18\"\u003e\u003c/a\u003e\n\nSimple composable for **Vue.js*** to handle long and ugly CSS class chaining.\n\nRead the story behind this package [here](https://itnext.io/tailwind-class-madness-never-again-75ec6ebfd3a0).\n\n**you can use it with any other framework as well*\n\n### Install\n\n---\n\nInstall the package:\n\n```bash\n$ npm i vue-use-variant --save\n# or\n$ yarn add vue-use-variant\n```\n\n### Motivation\n\n---\n\nWe all know that systems like [Tailwind](https://tailwindcss.com) are awesome, but we also know that defining styles by using utility classes can be hard ... Let's say you are using Tailwind and you want to style some button with provided classes. Probably the definition will look something like this:\n\n```vue\n\u003cbutton\n  class=\"\n    p-2 \n    bg-blue \n    rounded\n    text-md \n    border-0\n    font-bold \n    text-white \n    hover:bg-black \n    hover:text-gray\n    hover:opacity-80\n    hover:transition-all \n  \"\n  type=\"button\"\u003eSubmit\u003c/button\u003e\n```\n\n... and this is just a button. Imagine whole markup for even tiny component. \nReadability of it will be - easy talking - not so great. So what **problems** we're facing here:\n\n- very long class definition\n- poor readability\n- lack of scalability\n- hard to maintain\n\n### Usage\n\n---\n\nTo resolve these problems you can try `useVariant` composable.\n\nFirst define some variants. You can crate regular JSON object for it or use Vue `Ref`.\n\n```javascript\nimport { ref } from 'vue'\n\nexport const buttonVariants = {\n  button: 'font-bold rounded border-0 bg-blue hover:opacity-80',\n  buttonPrimary: 'p-4 text-lg',\n  buttonSecondary: 'p-2 text-md',\n}\n\n// or use with Vue Ref (Composition API)\nexport const buttonVariantsRef = ref(buttonVariants)\n```\n\nNow let's see how we can use it with some real component example.\n\n```vue\n\u003ctemplate\u003e\n  \u003cbutton :class=\"buttonVariant\" type=\"button\" /\u003e\n\u003c/template\u003e\n\n\u003cscript lang=\"ts\"\u003e\nimport { defineComponent, ref } from 'vue'\nimport { buttonVariants, buttonVariantsRef } from './variants.ts'\nimport { useVariant, UseVariant } from 'vue-use-variant'\n\nexport default defineComponent({\n  name: 'Button',\n  setup() {\n    const { defineVariant } = useVariant() as UseVariant\n\n    return {\n      buttonVariant: defineVariant(\n        ref({\n          button: true,\n          buttonPrimary: true,\n        }),\n        buttonVariantsRef,\n      ),\n    }\n  },\n})\n\u003c/script\u003e\n```\n\nAs a result your button will get this set of classes:\n\n```vue\nfont-bold rounded border-0 bg-blue hover:opacity-80 p-4 text-lg\n```\n\n---\n\nYou can also use it with **props**.\n\n```vue\n\u003cscript lang=\"ts\"\u003e\nimport { buttonVariantsRef } from './variants.ts'\n\nexport default defineComponent({\n  name: 'Button',\n  props: {\n    button: {\n      type: Boolean,\n      default: true,\n    },\n    buttonVariant: {\n      type: String,\n      default: 'buttonPrimary',\n    },\n  },\n  setup() {\n    const { defineVariant } = useVariant() as UseVariant\n\n    return {\n      buttonVariant: defineVariant({ ...props }, buttonVariantsRef),\n    }\n  },\n})\n\u003c/script\u003e\n```\n\nUse as an Array.\n\n```vue\n\u003cscript lang=\"ts\"\u003e\nimport { buttonVariantsRef } from './variants.ts'\n\nexport default defineComponent({\n  name: 'Button',\n  setup() {\n    const { defineVariant } = useVariant() as UseVariant\n\n    return {\n      buttonVariant: defineVariant(['button', 'buttonPrimary'], buttonVariantsRef),\n    }\n  },\n})\n\u003c/script\u003e\n```\n\nUse straight without variant definitions.\n\n```vue\n\u003cscript lang=\"ts\"\u003e\nexport default defineComponent({\n  name: 'Button',\n  setup() {\n    const { defineVariant } = useVariant() as UseVariant\n\n    return {\n      buttonVariant: defineVariant({ shadow: 'shadow' }),\n    }\n  },\n})\n\u003c/script\u003e\n```\n\nFinally, you can define your variants as composable argument.\n\n```vue\n\u003cscript lang=\"ts\"\u003e\nimport { buttonVariantsRef } from './variants.ts'\n\nexport default defineComponent({\n  name: 'Button',\n  setup() {\n    const { defineVariant } = useVariant(buttonVariantsRef) as UseVariant\n\n    return {\n      buttonVariant: defineVariant({ buttonPrimary: true }),\n    }\n  },\n})\n\u003c/script\u003e\n```\n\nOf course, you can **combine and mix** variants and use them as a global variations for \nyour base, global and reusable components. It's super easy and convenient. You can\nof course use it with any **other UI System** like for example Boostrap or Vuetify.\nAnd maybe it was built for vue you can use it for any o**ther frameworks** like React.\n\n--- \n\n### Demo\n\nWant to check or test it in action? Check out the simple app in the `demo` folder.\n\n---\n\n**API Reference**: Check out the [types](src/types.ts) for API definitions.\n\n**Contribution**: Please add Pull Request to introduce some changes or fixes.\n\n**Support**: Want to support? [Buy me a coffee](https://www.buymeacoffee.com/lukas.borawski).\n\n\u003ca href=\"https://www.buymeacoffee.com/lukas.borawski\" target=\"__blank\"\u003e\u003cimg src=\"https://cdn.buymeacoffee.com/buttons/v2/default-blue.png\" alt=\"Buy Me a Coffee\"\u003e\u003c/a\u003e\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flukasborawski%2Fvue-use-variant","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flukasborawski%2Fvue-use-variant","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flukasborawski%2Fvue-use-variant/lists"}