├── .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 | 
4 | 
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 |
11 |
12 |
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 |
2 |
3 |
4 | Tailwind Vue DataTable v0.2.9
5 | by BitTheCat
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/dev/TableShow.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
18 |
19 | Overwrite No Item
20 |
21 |
22 |
23 |
24 |
30 |
31 |
32 |
38 |
39 |
40 |
41 | Simple
42 |
43 |
54 |
55 |
56 |
57 | Header1
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 | Footer
67 |
68 |
69 |
70 |
71 |
72 |
73 |
With Props
74 |
90 |
91 |
92 |
93 | Header1
94 | Header2
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 | Footer
103 |
104 |
105 |
106 |
107 | {{ row.item.emoji }} - {{ row.item.username }}
108 |
109 |
110 |
111 | ROW-DETAILS ROW-DETAILS ROW-DETAILS
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 | Selected: {{ selectRow }}
121 | CurrentPage: {{ currentPage }}
122 |
123 |
124 |
125 |
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 |
2 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/components/TTbody.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/components/TTd.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/components/TTh.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/components/TThead.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/components/TTr.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/components/TVPagination.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
16 |
29 |
30 |
31 |
36 | {{ page }}
37 |
38 |
39 |
40 |
53 |
66 |
67 |
68 |
69 |
--------------------------------------------------------------------------------
/src/components/TVTable.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{ getSummary }}
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
22 |
23 |
30 |
31 |
32 | {{ field.label }}
33 |
34 |
35 |
44 |
45 |
46 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 | No fields set
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 | {{ noItemText }}
88 |
89 |
90 |
91 |
92 |
93 |
94 |
100 |
105 |
106 |
107 |
108 |
114 |
120 | {{ getField(item, field.key, '') }}
121 |
122 |
123 |
124 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
139 |
140 |
141 |
142 |
148 |
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 | })
--------------------------------------------------------------------------------