{"id":13480564,"url":"https://github.com/alfonsobries/vue-tailwind","last_synced_at":"2025-05-14T14:08:09.816Z","repository":{"id":34907427,"uuid":"177071285","full_name":"alfonsobries/vue-tailwind","owner":"alfonsobries","description":"Vue UI components with configurable classes ready for TailwindCSS","archived":false,"fork":false,"pushed_at":"2023-03-05T09:36:54.000Z","size":4603,"stargazers_count":2167,"open_issues_count":64,"forks_count":135,"subscribers_count":26,"default_branch":"master","last_synced_at":"2025-04-30T02:23:03.634Z","etag":null,"topics":["tailwindcss","typescript","unlimited-variants","variants","vue","vue-tailwind","vuejs"],"latest_commit_sha":null,"homepage":"https://www.vue-tailwind.com/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/alfonsobries.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null},"funding":{"github":"alfonsobries","open_collective":"vue-tailwind","custom":"https://www.buymeacoffee.com/alfonsobries"}},"created_at":"2019-03-22T04:28:15.000Z","updated_at":"2025-04-25T15:55:00.000Z","dependencies_parsed_at":"2023-09-29T02:27:18.062Z","dependency_job_id":"f364f259-a146-4899-9403-194f5aff9e71","html_url":"https://github.com/alfonsobries/vue-tailwind","commit_stats":{"total_commits":929,"total_committers":19,"mean_commits":48.89473684210526,"dds":"0.052744886975242156","last_synced_commit":"7ff9278d66a8b75234fbfedcd6dc1ed1c51f50cf"},"previous_names":[],"tags_count":113,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alfonsobries%2Fvue-tailwind","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alfonsobries%2Fvue-tailwind/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alfonsobries%2Fvue-tailwind/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alfonsobries%2Fvue-tailwind/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alfonsobries","download_url":"https://codeload.github.com/alfonsobries/vue-tailwind/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253153104,"owners_count":21862311,"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":["tailwindcss","typescript","unlimited-variants","variants","vue","vue-tailwind","vuejs"],"created_at":"2024-07-31T17:00:41.400Z","updated_at":"2025-05-14T14:08:09.790Z","avatar_url":"https://github.com/alfonsobries.png","language":"TypeScript","funding_links":["https://github.com/sponsors/alfonsobries","https://opencollective.com/vue-tailwind","https://www.buymeacoffee.com/alfonsobries"],"categories":["UI Libraries, Components \u0026 Templates","TypeScript","Components \u0026 Libraries","Frameworks [🔝](#readme)","Frameworks"],"sub_categories":["Frameworks","Component Collections"],"readme":"# Vue-Tailwind \n\n![CI](https://github.com/alfonsobries/vue-tailwind/workflows/CI/badge.svg)\n\nFor more info, check the official site: [https://vue-tailwind.com/](https://vue-tailwind.com/).\n\n**VueTailwind** is a set of Vue components created to be customized to adapt to your application's unique design.\n\n### Another UI library?\n\nMost component libraries depend on CSS frameworks with an opinionated and limited number of styles defined by the people who maintain those libraries.\n\nThose libraries are great and make our work easy, but hey, we made a beautiful custom design, right?\n\n### So what are the alternatives?\n\nWe can use a framework like [TailwindCss](https://tailwindcss.com) to define our style, but that will end with us writing long CSS classes repeatedly, which could quickly become unmaintainable. Also, create some components like modals, date pickers, etc., is a tricky task, and let's admit it, nobody has time for that, right?\n\n### Best of both worlds\n\nThe **VueTailwind** components are meant to be customized with custom CSS classes that you can define when you install the library.\n\nPlus, most component settings are configurable, so using this library is like having your personal set of components for your particular needs.\n\nAll that means that with this library, you will be able to:\n\n- Define your components look and feel by defining custom default CSS classes.\n- Add unlimited variants for every specific use case.\n- Override the default value of the props according to your needs.\n- Create different versions of one component with different default settings.\n\n## Installation\n\n### 1. Install the dependencies \n\n```console\nnpm install vue-tailwind --save\n``` \n\nOr: \n\n```console\nyarn add vue-tailwind\n``` \n\n## 2. Install TailwindCSS (Optional)\n\nThis library uses TailwindCSS classes by default. Still, it should work with any CSS framework since all the CSS classes are configurable.\n\nTo install TailwindCSS follow his official documentation: [https://tailwindcss.com/docs/installation](https://tailwindcss.com/docs/installation)\n\n#### 2.1 Add the @tailwindcss/forms plugin\n\nThe default theme of this library depends on the `@tailwindcss/forms` plugin. To use it, follow the steps on the plugin source page.\n[https://github.com/tailwindlabs/tailwindcss-forms](https://github.com/tailwindlabs/tailwindcss-forms)\n\n#### 2.1 Add variants for disabled pseudo-class\n\nAlso needed for the default theme and strongly recommended since it adds the ability to use some classes like `disabled:opacity-50 disabled:cursor-not-allowed` to disabled inputs.\n\nSee [https://tailwindcss.com/docs/configuring-variants](https://tailwindcss.com/docs/configuring-variants) on the TailwindCSS docs for more info.\n\nAs a reference, your `tailwind.config.js` may look like this:\n\n```js\nmodule.exports = {\n  variants: {\n    extend: {\n      opacity: ['disabled'],\n      cursor: ['disabled'],\n    },\n  },\n  plugins: [\n    require('@tailwindcss/forms'),\n  ],\n};\n```\n\n## 3. Configure Vue to use vue-tailwind\n\n```js\nimport Vue from 'vue'\nimport VueTailwind from 'vue-tailwind'\n\nconst components = {\n  // ...You need to add the components you need here (explained above)\n}\n\nVue.use(VueTailwind, components)\n```\n\n### 3.1 Import and install the components\n\n```js\nimport Vue from 'vue'\nimport VueTailwind from 'vue-tailwind'\n\nimport {\n  TInput,\n  TTextarea,\n  TSelect,\n  TRadio,\n  TCheckbox,\n  TButton,\n  TInputGroup,\n  TCard,\n  TAlert,\n  TModal,\n  TDropdown,\n  TRichSelect,\n  TPagination,\n  TTag,\n  TRadioGroup,\n  TCheckboxGroup,\n  TTable,\n  TDatepicker,\n  TToggle,\n  TDialog,\n} from 'vue-tailwind/dist/components';\n\nconst settings = {\n  // Use the following syntax\n  // {component-name}: {\n  //   component: {importedComponentObject},\n  //   props: {\n  //     {propToOverride}: {newDefaultValue}\n  //     {propToOverride2}: {newDefaultValue2}\n  //   }\n  // }\n  't-input': {\n    component: TInput,\n    props: {\n      classes: 'border-2 block w-full rounded text-gray-800'\n      // ...More settings\n    }\n  },\n  't-textarea': {\n    component: TTextarea,\n    props: {\n      classes: 'border-2 block w-full rounded text-gray-800'\n      // ...More settings\n    }\n  },\n  // ...Rest of the components\n}\n\nVue.use(VueTailwind, settings)\n```\n\n### 3.2 Alternatively, you can use the v1.0 syntax\n\n```js\nimport Vue from 'vue'\n// Notice that I am using a different path here:\nimport VueTailwind from 'vue-tailwind/dist/full'\n\nconst settings = {\n  TInput: {\n    classes: 'border-2 block w-full rounded text-gray-800',\n    // ...More settings\n  },\n  TButton: {\n    classes: 'rounded-lg border block inline-flex items-center justify-center',\n    // ...More settings\n  },\n  // ...Rest of the components\n}\n\nVue.use(VueTailwind, settings)\n```\n\n### 3.3 Or install only the components you need\n\n```js\nimport Vue from 'vue'\nimport VueTailwind from 'vue-tailwind'\n\nimport TInput from 'vue-tailwind/dist/t-input'\nimport TButton from 'vue-tailwind/dist/t-button'\n\nconst settings = {\n  't-input': {\n    component: TInput,\n    props: {\n      classes: 'block w-full px-3 py-2 text-black placeholder-gray-400 transition duration-100 ease-in-out bg-white border border-gray-300 rounded shadow-sm focus:border-blue-500 focus:ring-2 focus:ring-blue-500 focus:outline-none focus:ring-opacity-50 disabled:opacity-50 disabled:cursor-not-allowed',\n      // ...More settings\n    }\n  },\n  't-button': {\n    component: TButton,\n    props: {\n      classes: 'block px-4 py-2 text-white transition duration-100 ease-in-out bg-blue-500 border border-transparent rounded shadow-sm hover:bg-blue-600 focus:border-blue-500 focus:ring-2 focus:ring-blue-500 focus:outline-none focus:ring-opacity-50  disabled:opacity-50 disabled:cursor-not-allowed',\n      // ...More settings\n    }\n  },\n}\n\nVue.use(VueTailwind, settings)\n```\n\n\u003e *Note*: Using the syntax from point **3.3** is the best way to prevent a big bundle size but only if you import a couple of components. If the number of components you install increases, the recommended way to install them is to use the syntax from the points **3.1** or **3.2** to help the library reuse some code and keep the bundle size at a minimum.\n\n\n[Read more →](https://www.vue-tailwind.com/docs/installation)\n\n## Theming\n\nTo apply a custom theme you should play with the `classes`, `fixedClasses`, and `variants` props.\n\nThe `classes` and `fixedClasses` props usually expects an `string` with a CSS class for single-tag components (inputs, button, etc.) and an `object` for more complex components (modals, datepicker, etc) (see component docs for details).\n\nThe `variants` props expects an object where every key represents the variant name and every value the classes that will be used when that variant is applied.\n\n#### Example for a single-tag component: \n\n```js\nimport Vue from 'vue'\nimport VueTailwind from 'vue-tailwind'\nimport TButton from 'vue-tailwind/dist/t-button'\n\nconst settings = {\n  't-button': {\n    component: TButton,\n    props: {\n      // The fixed classes will never change and will be merged with the `classes` value or the active variant\n      fixedClasses: 'focus:outline-none focus:shadow-outline inline-flex items-center transition ease-in-out duration-150',\n      // Classes used when any variant is active\n      classes: 'text-white bg-blue-600 hover:bg-blue-500 focus:border-blue-700 active:bg-blue-700 text-sm font-medium border border-transparent px-3 py-2 rounded-md',\n      variants: {\n        // A red variant of the button (applied when `\u003ct-button variant=\"error\" /\u003e`)\n        error: 'text-white bg-red-600 hover:bg-red-500 focus:border-red-700 active:bg-red-700 text-sm font-medium border border-transparent px-3 py-2 rounded-md',\n        // A green variant of the button (applied when `\u003ct-button variant=\"success\" /\u003e`)\n        success: 'text-white bg-green-600 hover:bg-green-500 focus:border-green-700 active:bg-green-700 text-sm font-medium border border-transparent px-3 py-2 rounded-md',\n        // ...unlimited variants\n      }\n      // ...More settings\n    }\n  },\n}\n\nVue.use(VueTailwind, settings)\n```\n\n#### Example for a complex component: \n\n```js\nimport Vue from 'vue'\nimport VueTailwind from 'vue-tailwind'\nimport TAlert from 'vue-tailwind/dist/t-alert'\n\nconst settings = {\n  't-alert': {\n    component: TAlert,\n    props: {\n      // The fixed classes will never change and will be merged with the `classes` value or the active variant\n      fixedClasses: {\n        wrapper: 'rounded p-4 flex text-sm border-l-4',\n        body: 'flex-grow',\n        close: 'ml-4 rounded',\n        closeIcon: 'h-5 w-5 fill-current'\n      },\n      classes: {\n        wrapper: 'bg-blue-100 border-blue-500',\n        body: 'text-blue-700',\n        close: 'text-blue-700 hover:text-blue-500 hover:bg-blue-200',\n        closeIcon: 'h-5 w-5 fill-current'\n      },\n      variants: {\n        danger: {\n          wrapper: 'bg-red-100 border-red-500',\n          body: 'text-red-700',\n          close: 'text-red-700 hover:text-red-500 hover:bg-red-200'\n          // Notice that I am not defining the `closeIcon` class since we only\n          // need to write the classes we want to override\n        },\n      }\n    }\n  },\n}\n\nVue.use(VueTailwind, settings)\n```\n\n[Read more →](https://www.vue-tailwind.com/docs/theming)\n\n## Override settings\n\nAll the components on this library have default settings added as component props according to how we understand those settings are most commonly used.\n\nI am aware that in many cases is useful to change the default value, so you don't need to add the prop over and over when needed.\n\n```js\nimport Vue from 'vue'\nimport VueTailwind from 'vue-tailwind'\n\nimport TDatepicker from 'vue-tailwind/dist/t-datepicker'\nimport TButton from 'vue-tailwind/dist/t-button'\nimport TModal from 'vue-tailwind/dist/t-modal'\n\n// Locale to eventually replace the default Datepicker locale\nimport Spanish from 'vue-tailwind/dist/l10n/es'\n\nconst settings = {\n  't-button': {\n    component: TButton,\n    props: {\n      // classes: '...',\n      // variants: '...',\n      // ...\n      // Originally it defaults to `undefined` that means is considered a submit\n      // button if the button is inside a form.\n      type: 'button',\n    }\n  },\n  't-datepicker': {\n    component: TDatepicker,\n    props: {\n      // classes: '...',\n      // variants: '...',\n      // ...\n      // Originally a locale object with English values\n      locale: Spanish,\n    }\n  },\n  't-modal': {\n    component: TModal,\n    props: {\n      // classes: '...',\n      // variants: '...',\n      // ...\n      // Originally `true`\n      escToClose: false,\n    }\n  },\n}\n\nVue.use(VueTailwind, settings)\n```\n\nYou can also use this feature to create different versions of the same component.\n\n```js\nimport Vue from 'vue'\nimport VueTailwind from 'vue-tailwind'\n\nimport TButton from 'vue-tailwind/dist/t-button'\nimport TTag from 'vue-tailwind/dist/t-tag'\n\nconst settings = {\n  // What about one \u003ct-button /\u003e for normal button and a `\u003ct-submit /\u003e` for a submit button\n  't-button': {\n    component: TButton,\n    props: {\n      type: 'button',\n    }\n  },\n  't-submit': {\n    component: TButton,\n    props: {\n      type: 'submit',\n    }\n  },\n  // I love this use case for the TTag component and will let you guess what\n  // is doing: 👇\n  'blog-title': { // Used like \u003cblog-title\u003eTitle of a blog post\u003c/blog-title\u003e\n    component: TTag,\n    props: {\n      tag: 'h1',\n      classes: 'font-semibold text-xl leading-6',\n    }\n  },\n  'blog-subtitle': { // Used like \u003cblog-title\u003esubtitle of a blog post\u003c/blog-title\u003e\n    component: TTag,\n    props: {\n      tag: 'h2',\n      classes: 'font-semibold text-xl leading-6',\n    }\n  },\n  't-link': { // Used like \u003ct-link href=\"\"\u003eOpen site\u003c/t-link\u003e\n    component: TTag,\n    props: {\n      tag: 'a',\n      classes: 'text-blue-500 underline hover:text-blue-600',\n    }\n  }\n}\n\nVue.use(VueTailwind, settings)\n```\n\n[Read more →](https://www.vue-tailwind.com/docs/settings)\n\n## Workflow\n\nOnce your different variants were defined you can use the `variant` prop to define which variant should be applied:\n\n```html\n\u003ct-input variant=\"error\" /\u003e\n```\n\nThe variant prop also accepts an object that takes the first attribute with a _truthy_ value\n\n```html\n\u003ct-input\n  :variant=\"{\n    error: inputIsNotValid,\n    success: inputIsValid,\n  }\"\n/\u003e\n```\n\n[Read more →](https://www.vue-tailwind.com/docs/workflow)\n\n## What's new in version 2.x\n\n- Install only the components you need for smaller bundle size\n- Custom name for components\n- The ability to install the same component multiple times with different default settings and name\n- New default theme\n\n#### Plans for v3.x\n\n- Rebuild with Vue 3\n- Multiple typescript improvements\n- Stronger test coverage\n- Accesibility first\n- New Branding\n\n[Read more →](https://www.vue-tailwind.com/docs/upcoming-changes#plans-for-version-3x)\n\n## Contribute\n\nIs this project helpful for you? Consider sponsoring me [https://github.com/sponsors/alfonsobries](https://github.com/sponsors/alfonsobries).\n\nOf course, any other kind help is welcome, even if you notice some grammar mistakes (English is not my primary language) see [contribute page](https://vue-tailwind.com/contribute) for details.\n\n### Changelog\n\nPlease see [Release notes](https://vue-tailwind.com/docs/release-notes) for more information about what was changed recently.\n\n### Security\n\nIf you discover any security related issues, please email alfonso@vexilo.com instead of using the issue tracker.\n\n## Credits\n\n- [Alfonso Bribiesca](https://github.com/alfonsobries)\n- [All Contributors](https://github.com/alfonsobries/vue-tailwind/contributors)\n\n## License\n\nThe MIT License (MIT). Please see [License File](https://github.com/alfonsobries/vue-tailwind/blob/master/LICENSE) for more information.\n\n_Made with love by [@alfonsobries](https://twitter.com/alfonsobries)_\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falfonsobries%2Fvue-tailwind","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falfonsobries%2Fvue-tailwind","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falfonsobries%2Fvue-tailwind/lists"}