├── .eslintrc.js ├── .gitignore ├── LICENSE ├── README.md ├── assets ├── tvdatatable.jpg ├── tvpagination.jpg ├── tvtable_busy_state.jpg ├── tvtable_checkbox.jpg └── tvtable_row_details.jpg ├── dev ├── App.vue ├── TableShow.vue ├── css │ └── app.css ├── main.js └── router.ts ├── index.html ├── package-lock.json ├── package.json ├── postcss.config.js ├── rollup.config.js ├── src ├── components │ ├── TTable.vue │ ├── TTbody.vue │ ├── TTd.vue │ ├── TTh.vue │ ├── TThead.vue │ ├── TTr.vue │ ├── TVPagination.vue │ └── TVTable.vue ├── css │ └── app.css └── index.js ├── tailwind.config.js ├── test └── base.spec.js ├── vite.config.ts └── vitest.config.ts /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: [ 3 | "eslint:recommended", 4 | 'plugin:vue/vue3-recommended', 5 | ], 6 | rules: { 7 | "indent": [ 8 | "error", 9 | 4, 10 | ], 11 | "vue/html-indent": 'off', 12 | "vue/max-attributes-per-line": 'off', 13 | "vue/html-self-closing": 'off', 14 | "no-unused-vars": 'off', 15 | } 16 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Michele L. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Tailwind Vue Data Table 2 | 3 | ![](https://img.shields.io/badge/Vue3-318534?logo=vuedotjs&logoColor=white&style=flat-square) 4 | ![](https://img.shields.io/badge/Tailwind-6899C7?logo=tailwindcss&logoColor=white&style=flat-square) 5 | 6 | Simple DataTable with slots, class and style modification for tr and td, sortable by columns (only graphics with click event). 7 | 8 | Contains the TVPaginator component that can be disabled via prop or used in stand-alone mode. 9 | 10 | Total Downloads 11 | Latest Version 12 | License 13 | 14 |
15 | 16 | #### [*__Documentation__* ](https://bitthecat.github.io/tailwind-vue-data-table.html) 17 | 18 |
19 | 20 | ### Install 21 | ``` 22 | npm i @bitthecat/tailwind-vue-data-table 23 | ``` 24 | 25 | Add this code inside **tailwind.config.*** to compile the css library 26 | 27 | ``` js 28 | content: [ 29 | ... 30 | './node_modules/@bitthecat/tailwind-vue-data-table/dist/*.js', 31 | ], 32 | ``` 33 | 34 | ### Use in Vue 35 | ``` js 36 | import { TVTable } from '@bitthecat/tailwind-vue-data-table' 37 | ``` 38 | 39 | ### Import default css 40 | ``` css 41 | import "@bitthecat/tailwind-vue-data-table/dist/library.css" 42 | ``` 43 | 44 |
45 | 46 | This project is licensed under the MIT license. See [LICENSE](LICENSE). -------------------------------------------------------------------------------- /assets/tvdatatable.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BitTheCat/tailwind-vue-data-table/3a56b2002014d1df9fdcaa82e96cc9a8744a6dac/assets/tvdatatable.jpg -------------------------------------------------------------------------------- /assets/tvpagination.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BitTheCat/tailwind-vue-data-table/3a56b2002014d1df9fdcaa82e96cc9a8744a6dac/assets/tvpagination.jpg -------------------------------------------------------------------------------- /assets/tvtable_busy_state.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BitTheCat/tailwind-vue-data-table/3a56b2002014d1df9fdcaa82e96cc9a8744a6dac/assets/tvtable_busy_state.jpg -------------------------------------------------------------------------------- /assets/tvtable_checkbox.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BitTheCat/tailwind-vue-data-table/3a56b2002014d1df9fdcaa82e96cc9a8744a6dac/assets/tvtable_checkbox.jpg -------------------------------------------------------------------------------- /assets/tvtable_row_details.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BitTheCat/tailwind-vue-data-table/3a56b2002014d1df9fdcaa82e96cc9a8744a6dac/assets/tvtable_row_details.jpg -------------------------------------------------------------------------------- /dev/App.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | -------------------------------------------------------------------------------- /dev/TableShow.vue: -------------------------------------------------------------------------------- 1 | 126 | 127 | -------------------------------------------------------------------------------- /dev/css/app.css: -------------------------------------------------------------------------------- 1 | @import "tailwindcss/base"; 2 | @import "tailwindcss/components"; 3 | @import "tailwindcss/utilities"; 4 | 5 | @import "../../src/css/app.css" -------------------------------------------------------------------------------- /dev/main.js: -------------------------------------------------------------------------------- 1 | import './css/app.css'; 2 | import { createApp } from 'vue'; 3 | 4 | import App from './App.vue'; 5 | 6 | import router from './router'; 7 | 8 | const app = createApp(App); 9 | 10 | app.use(router); 11 | 12 | app.mount('#app'); -------------------------------------------------------------------------------- /dev/router.ts: -------------------------------------------------------------------------------- 1 | import { createRouter, createWebHistory } from 'vue-router'; 2 | 3 | import TableShow from './TableShow.vue' 4 | 5 | const routes = [ 6 | { path: '/', component: TableShow }, 7 | ]; 8 | 9 | const router = createRouter({ 10 | history: createWebHistory(), 11 | routes, 12 | }); 13 | 14 | export default router; -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Tailwind Vue DataTable 7 | 8 | 9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@bitthecat/tailwind-vue-data-table", 3 | "version": "0.3.0", 4 | "keywords": [ 5 | "tailwindcss", 6 | "customisable", 7 | "css", 8 | "vue", 9 | "datatable", 10 | "table", 11 | "sortable", 12 | "data", 13 | "vue3", 14 | "paginator" 15 | ], 16 | "homepage": "https://github.com/BitTheCat/tailwind-vue-data-table", 17 | "main": "dist/library.js", 18 | "module": "dist/library.mjs", 19 | "files": [ 20 | "dist/*" 21 | ], 22 | "license": "MIT", 23 | "contributors": [ 24 | { 25 | "name": "Michele Lotito", 26 | "url": "https://github.com/bitthecat" 27 | } 28 | ], 29 | "scripts": { 30 | "dev": "vite", 31 | "build": "vite build", 32 | "preview": "vite preview", 33 | "build-package": "rollup -c", 34 | "eslint": "npx eslint \"src/**.{js,vue}\"", 35 | "test": "vitest" 36 | }, 37 | "devDependencies": { 38 | "@tailwindcss/forms": "^0.4.0", 39 | "@vitejs/plugin-vue": "^2.0.1", 40 | "@vue/test-utils": "^2.2.7", 41 | "autoprefixer": "^10.4.0", 42 | "eslint": "^8.24.0", 43 | "eslint-plugin-vue": "^9.5.1", 44 | "jsdom": "^21.0.0", 45 | "rollup": "^2.79.2", 46 | "rollup-plugin-peer-deps-external": "^2.2.4", 47 | "rollup-plugin-vue": "^6.0.0", 48 | "tailwindcss": "^3.0.7", 49 | "vite": "^2.9.18", 50 | "vitest": "^0.27.2", 51 | "vue": "^3.2.6", 52 | "vue-loader": "^16.7.0", 53 | "vue-router": "^4" 54 | }, 55 | "peerDependencies": { 56 | "vue": "^3.2.6" 57 | }, 58 | "dependencies": { 59 | "rollup-plugin-import-css": "^3.1.0" 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import vue from 'rollup-plugin-vue' 2 | import peerDepsExternal from 'rollup-plugin-peer-deps-external' 3 | import css from "rollup-plugin-import-css"; 4 | 5 | export default [ 6 | { 7 | input: './src/index.js', 8 | output: [ 9 | { 10 | format: 'esm', 11 | file: 'dist/library.mjs' 12 | }, 13 | { 14 | format: 'cjs', 15 | file: 'dist/library.js' 16 | } 17 | ], 18 | plugins: [ 19 | vue(), peerDepsExternal(), css() 20 | ] 21 | } 22 | ] -------------------------------------------------------------------------------- /src/components/TTable.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | -------------------------------------------------------------------------------- /src/components/TTbody.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | -------------------------------------------------------------------------------- /src/components/TTd.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | -------------------------------------------------------------------------------- /src/components/TTh.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | -------------------------------------------------------------------------------- /src/components/TThead.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | -------------------------------------------------------------------------------- /src/components/TTr.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | -------------------------------------------------------------------------------- /src/components/TVPagination.vue: -------------------------------------------------------------------------------- 1 | 68 | 69 | -------------------------------------------------------------------------------- /src/components/TVTable.vue: -------------------------------------------------------------------------------- 1 | 149 | 150 | -------------------------------------------------------------------------------- /src/css/app.css: -------------------------------------------------------------------------------- 1 | .tv-table { 2 | @apply overflow-hidden min-w-full 3 | } 4 | 5 | .tv-thead { 6 | @apply bg-gray-300 text-xs border divide-x divide-y 7 | } 8 | 9 | .tv-th { 10 | @apply px-2 py-1.5 11 | } 12 | 13 | .tv-tbody { 14 | @apply border bg-gray-100 15 | } 16 | 17 | .tv-tr { 18 | /* */ 19 | } 20 | 21 | .tv-td { 22 | @apply px-2 py-3.5 align-top table-cell last:border-b-0 text-2xl md:text-sm 23 | } 24 | 25 | .tv-tfoot { 26 | @apply text-xs bg-gray-300 border divide-x divide-y 27 | } 28 | 29 | .tv-summary-size { 30 | @apply text-lg md:text-sm 31 | } 32 | 33 | .tv-paginator-size { 34 | @apply w-6 h-6 md:w-4 md:h-4 35 | } 36 | 37 | .tv-paginator-text { 38 | @apply text-lg md:text-sm 39 | } 40 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import TVTable from'./components/TVTable.vue' 2 | import TVPagination from'./components/TVPagination.vue' 3 | import './css/app.css'; 4 | 5 | export { TVTable, TVPagination } -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | content: [ 3 | './index.html', 4 | './dev/**/*.{html,js,vue,ts}', 5 | './src/**/*.{html,js,vue,ts}', 6 | ], 7 | } -------------------------------------------------------------------------------- /test/base.spec.js: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest' 2 | 3 | import { mount } from "@vue/test-utils"; 4 | import TVTable from "../src/components/TVTable.vue" 5 | 6 | describe("Base Test", async() => { 7 | 8 | it("should render with no field set text", () => { 9 | 10 | const wrapper = mount(TVTable); 11 | 12 | expect(wrapper.find('.tv-td').text()).toBe('No fields set') 13 | }); 14 | 15 | it("should render with no data to display", () => { 16 | 17 | const wrapper = mount(TVTable, { 18 | props: { 19 | fields: [ 20 | { 21 | label: 'id', 22 | key: 'id', 23 | }, 24 | ] 25 | } 26 | }); 27 | 28 | expect(wrapper.find('.tv-td').text()).toBe('No data to display') 29 | }); 30 | 31 | it("should render with some data", () => { 32 | 33 | const wrapper = mount(TVTable, { 34 | props: { 35 | items: [ 36 | { 37 | id: 1 38 | }, 39 | ], 40 | fields: [ 41 | { 42 | label: 'id', 43 | key: 'id', 44 | }, 45 | ] 46 | } 47 | }); 48 | 49 | expect(wrapper.find('.tv-th').text()).toBe('id') 50 | expect(wrapper.find('.tv-td').text()).toBe('1') 51 | }); 52 | 53 | }); -------------------------------------------------------------------------------- /vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import vue from '@vitejs/plugin-vue' 3 | 4 | export default defineConfig({ 5 | plugins: [ 6 | vue() 7 | ], 8 | build: { 9 | minify: false, 10 | sourcemap: true, 11 | } 12 | }) -------------------------------------------------------------------------------- /vitest.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vitest/config' 2 | import vue from '@vitejs/plugin-vue' 3 | 4 | export default defineConfig({ 5 | plugins: [ 6 | vue() 7 | ], 8 | test: { 9 | globals: true, 10 | environment: "jsdom", 11 | }, 12 | }) --------------------------------------------------------------------------------