├── .gitignore
├── README.md
├── package-lock.json
├── package.json
├── rollup.config.js
└── src
├── DataTable.svelte
├── icons
├── ArrowDown.svelte
└── ArrowUp.svelte
└── index.js
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist/
4 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Responsive DataTable with svelte and tailwindcss
2 |
3 | Responsive data-table built with svelte and tailwindcss
4 |
5 | ## Installation
6 | ```bash
7 | $npm i @fouita/data-table -D
8 | ```
9 |
10 | ## Simple usage
11 |
12 | To fill out the table you can add a simple json data and a head attribute to specify what to display.
13 |
14 | 
15 |
16 | ```html
17 |
57 |
58 |
59 |
60 | ```
61 |
62 | The above example does not show the attribute address because it's not included in the head. You can add a list of selection and update the head list dynamically if you want.
63 |
64 | By adding `hover` we tell the table to change the background of the row when hovering.
65 |
66 | ## Stripped
67 |
68 | by adding a `stripped` prop the table becames like the following
69 |
70 | 
71 |
72 | ```html
73 |
74 | ```
75 |
76 | ## Customizing Header
77 |
78 | We can customize the alignement of text, the background/text color of all/some columns.
79 |
80 | By adding `_class` attribute inside the head we can change the style easily
81 |
82 | 
83 |
84 | ```javascript
85 | const head= {
86 | first_name: 'First Name',
87 | last_name: 'Last Name',
88 | email: 'Email',
89 | phone: 'Phone',
90 | company: 'Company',
91 | _class: 'bg-red-200 text-red-700'
92 | }
93 | ```
94 |
95 | To update the entire column we can attribute `_class` to the specific head property like the following
96 |
97 | 
98 |
99 | ```javascript
100 | const head= {
101 | first_name: 'First Name',
102 | last_name: 'Last Name',
103 | email: 'Email',
104 | phone: {value: 'Phone', _class: 'text-right bg-blue-200 text-blue-900'},
105 | company: {value: 'Company', _class: 'text-left'},
106 | _class: 'bg-red-200 text-red-700'
107 | }
108 | ```
109 |
110 | This will override the global head class style.
111 |
112 |
113 | ## Customizing rows/cells
114 |
115 | We can customize rows and cells by also adding `_class` attribute inside the data
116 |
117 | 
118 |
119 | ```javascript
120 | const data = [
121 | // ...
122 | {
123 | "first_name": "Arlene",
124 | "last_name": "Cooley",
125 | "company": "XUMONK",
126 | "email": "arlene.cooley@xumonk.us",
127 | "phone": "+1 (926) 459-2880",
128 | "address": "659 Dupont Street, Lynn, West Virginia, 7173",
129 | _class: 'bg-green-200 font-bold text-red-700 text-center'
130 | },
131 | // ...
132 | ]
133 | ```
134 |
135 | It goes the same for specific cells like the follwing
136 |
137 | 
138 |
139 | ```javascript
140 | const data = [
141 | // ...
142 | {
143 | "first_name": "Arlene",
144 | "last_name": "Cooley",
145 | "company": "XUMONK",
146 | "email": "arlene.cooley@xumonk.us",
147 | "phone": {
148 | value: "+1 (926) 459-2880",
149 | _class: 'text-white bg-green-600 p-5 border-2 border-red-600 text-center'
150 | },
151 | "address": "659 Dupont Street, Lynn, West Virginia, 7173",
152 | _class: 'bg-green-200 font-bold text-red-700 text-center'
153 | },
154 | // ...
155 | ]
156 | ```
157 |
158 | ## Sort, Search and Pagination
159 |
160 | To keep things simple, the sorting and pagination functions are custom depending on how you are planning to use the DataTable (with preloaded data or you prefer doing server request).
161 |
162 | this is an example on how to use them.
163 |
164 | ### Data Sorting
165 |
166 | 
167 |
168 | ```html
169 |
219 |
220 |
221 |
222 | ```
223 |
224 | ### Data search
225 |
226 | For the search we can add an input that filter the data rows and return a filtred list, no big deal!
227 |
228 | 
229 |
230 | We can create a `Search.svelte` component like the following
231 |
232 | ```html
233 |
237 |
238 |
239 |
240 |
241 |
242 |
245 |
246 |
247 | ```
248 |
249 | And then use it with the search function, we can use [Fuse](https://fusejs.io) for simple search
250 |
251 | ```html
252 |
301 |
302 |
303 |
304 | ```
305 |
306 | ### Pagination
307 |
308 | for the pagination you can checkout [Fouita Pagination](https://github.com/fouita/svelte-tw-pagination) and update the data each time you navigate (it's very simple!)
309 |
310 |
311 |
312 | ## About
313 |
314 | [Fouita : UI framework for svelte + tailwind components](https://fouita.com)
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@fouita/data-table",
3 | "version": "0.0.1",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "@rollup/plugin-node-resolve": {
8 | "version": "9.0.0",
9 | "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-9.0.0.tgz",
10 | "integrity": "sha512-gPz+utFHLRrd41WMP13Jq5mqqzHL3OXrfj3/MkSyB6UBIcuNt9j60GCbarzMzdf1VHFpOxfQh/ez7wyadLMqkg==",
11 | "dev": true,
12 | "requires": {
13 | "@rollup/pluginutils": "^3.1.0",
14 | "@types/resolve": "1.17.1",
15 | "builtin-modules": "^3.1.0",
16 | "deepmerge": "^4.2.2",
17 | "is-module": "^1.0.0",
18 | "resolve": "^1.17.0"
19 | }
20 | },
21 | "@rollup/pluginutils": {
22 | "version": "3.1.0",
23 | "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz",
24 | "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==",
25 | "dev": true,
26 | "requires": {
27 | "@types/estree": "0.0.39",
28 | "estree-walker": "^1.0.1",
29 | "picomatch": "^2.2.2"
30 | }
31 | },
32 | "@types/estree": {
33 | "version": "0.0.39",
34 | "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz",
35 | "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==",
36 | "dev": true
37 | },
38 | "@types/node": {
39 | "version": "14.10.1",
40 | "resolved": "https://registry.npmjs.org/@types/node/-/node-14.10.1.tgz",
41 | "integrity": "sha512-aYNbO+FZ/3KGeQCEkNhHFRIzBOUgc7QvcVNKXbfnhDkSfwUv91JsQQa10rDgKSTSLkXZ1UIyPe4FJJNVgw1xWQ==",
42 | "dev": true
43 | },
44 | "@types/resolve": {
45 | "version": "1.17.1",
46 | "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz",
47 | "integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==",
48 | "dev": true,
49 | "requires": {
50 | "@types/node": "*"
51 | }
52 | },
53 | "builtin-modules": {
54 | "version": "3.1.0",
55 | "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.1.0.tgz",
56 | "integrity": "sha512-k0KL0aWZuBt2lrxrcASWDfwOLMnodeQjodT/1SxEQAXsHANgo6ZC/VEaSEHCXt7aSTZ4/4H5LKa+tBXmW7Vtvw==",
57 | "dev": true
58 | },
59 | "deepmerge": {
60 | "version": "4.2.2",
61 | "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz",
62 | "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==",
63 | "dev": true
64 | },
65 | "estree-walker": {
66 | "version": "1.0.1",
67 | "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz",
68 | "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==",
69 | "dev": true
70 | },
71 | "fsevents": {
72 | "version": "2.1.3",
73 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz",
74 | "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==",
75 | "dev": true,
76 | "optional": true
77 | },
78 | "is-module": {
79 | "version": "1.0.0",
80 | "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz",
81 | "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=",
82 | "dev": true
83 | },
84 | "path-parse": {
85 | "version": "1.0.6",
86 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
87 | "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
88 | "dev": true
89 | },
90 | "picomatch": {
91 | "version": "2.2.2",
92 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz",
93 | "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==",
94 | "dev": true
95 | },
96 | "require-relative": {
97 | "version": "0.8.7",
98 | "resolved": "https://registry.npmjs.org/require-relative/-/require-relative-0.8.7.tgz",
99 | "integrity": "sha1-eZlTn8ngR6N5KPoZb44VY9q9Nt4=",
100 | "dev": true
101 | },
102 | "resolve": {
103 | "version": "1.17.0",
104 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz",
105 | "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==",
106 | "dev": true,
107 | "requires": {
108 | "path-parse": "^1.0.6"
109 | }
110 | },
111 | "rollup": {
112 | "version": "2.26.11",
113 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.26.11.tgz",
114 | "integrity": "sha512-xyfxxhsE6hW57xhfL1I+ixH8l2bdoIMaAecdQiWF3N7IgJEMu99JG+daBiSZQjnBpzFxa0/xZm+3pbCdAQehHw==",
115 | "dev": true,
116 | "requires": {
117 | "fsevents": "~2.1.2"
118 | }
119 | },
120 | "rollup-plugin-svelte": {
121 | "version": "6.0.1",
122 | "resolved": "https://registry.npmjs.org/rollup-plugin-svelte/-/rollup-plugin-svelte-6.0.1.tgz",
123 | "integrity": "sha512-kS9/JZMBNgpKTqVKlwV8mhmGwxu8NiNf6+n5ZzdZ8yDp3+ADqjf8Au+JNEpoOn6kLlh1hLS2Gsa76k9RP57HDQ==",
124 | "dev": true,
125 | "requires": {
126 | "require-relative": "^0.8.7",
127 | "rollup-pluginutils": "^2.8.2",
128 | "sourcemap-codec": "^1.4.8"
129 | }
130 | },
131 | "rollup-pluginutils": {
132 | "version": "2.8.2",
133 | "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz",
134 | "integrity": "sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==",
135 | "dev": true,
136 | "requires": {
137 | "estree-walker": "^0.6.1"
138 | },
139 | "dependencies": {
140 | "estree-walker": {
141 | "version": "0.6.1",
142 | "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz",
143 | "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==",
144 | "dev": true
145 | }
146 | }
147 | },
148 | "sourcemap-codec": {
149 | "version": "1.4.8",
150 | "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz",
151 | "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==",
152 | "dev": true
153 | },
154 | "svelte": {
155 | "version": "3.25.0",
156 | "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.25.0.tgz",
157 | "integrity": "sha512-CUfq+YTC5Q0tBg7Q9X/QxNutdEYp7ogdbcTZF3mrowOlp3+OF1ZexHwI0Io2VqFSDxht7TlA2lTIQC4RnhR1MQ==",
158 | "dev": true
159 | }
160 | }
161 | }
162 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@fouita/data-table",
3 | "svelte": "src/index.js",
4 | "module": "dist/index.mjs",
5 | "main": "dist/index.js",
6 | "scripts": {
7 | "build": "rollup -c",
8 | "prepublishOnly": "npm run build"
9 | },
10 | "devDependencies": {
11 | "@rollup/plugin-node-resolve": "^9.0.0",
12 | "rollup": "^2.0.0",
13 | "rollup-plugin-svelte": "^6.0.0",
14 | "svelte": "^3.0.0"
15 | },
16 | "keywords": [
17 | "svelte",
18 | "tailwindcss",
19 | "data-table",
20 | "fouita"
21 | ],
22 | "files": [
23 | "src",
24 | "dist"
25 | ],
26 | "description": "Responsive data-table built with svelte and tailwindcss",
27 | "version": "0.0.2",
28 | "repository": {
29 | "type": "git",
30 | "url": "git+https://github.com/fouita/svelte-tw-data-table.git"
31 | },
32 | "author": "fouita",
33 | "license": "MIT",
34 | "bugs": {
35 | "url": "https://github.com/fouita/svelte-tw-data-table/issues"
36 | },
37 | "homepage": "https://github.com/fouita/svelte-tw-data-table#readme"
38 | }
39 |
--------------------------------------------------------------------------------
/rollup.config.js:
--------------------------------------------------------------------------------
1 | import svelte from 'rollup-plugin-svelte';
2 | import resolve from '@rollup/plugin-node-resolve';
3 | import pkg from './package.json';
4 |
5 | const name = pkg.name
6 | .replace(/^(@\S+\/)?(svelte-)?(\S+)/, '$3')
7 | .replace(/^\w/, m => m.toUpperCase())
8 | .replace(/-\w/g, m => m[1].toUpperCase());
9 |
10 | export default {
11 | input: 'src/index.js',
12 | output: [
13 | { file: pkg.module, 'format': 'es' },
14 | { file: pkg.main, 'format': 'umd', name }
15 | ],
16 | plugins: [
17 | svelte(),
18 | resolve()
19 | ]
20 | };
21 |
--------------------------------------------------------------------------------
/src/DataTable.svelte:
--------------------------------------------------------------------------------
1 |
104 |
105 |
106 |
130 |
131 |
132 | {#each rows as row, i}
133 |
137 | {#each keys(head) as h}
138 |
139 | {#if isCmp(row[h])}
140 |
141 | {:else}{val(row[h])}{/if}
142 | |
143 | {/each}
144 |
145 |
146 | {#each keys(head) as h}
147 |
150 |
153 | {val(head[h])}
154 | |
155 |
156 | {#if isCmp(row[h])}
157 |
158 | {:else}{val(row[h])}{/if}
159 | |
160 |
161 | {/each}
162 |
163 | {/each}
164 |
165 |
166 |
--------------------------------------------------------------------------------
/src/icons/ArrowDown.svelte:
--------------------------------------------------------------------------------
1 |
5 |
6 |
22 |
--------------------------------------------------------------------------------
/src/icons/ArrowUp.svelte:
--------------------------------------------------------------------------------
1 |
5 |
6 |
22 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | export { default as default } from './DataTable.svelte';
2 |
--------------------------------------------------------------------------------