├── .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 | ![DataTable foutia](https://cdn.fouita.com/assets/pics/template/data-table/data-table-simple.jpg) 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 | ![DataTable foutia](https://cdn.fouita.com/assets/pics/template/data-table/data-table-stripped.jpg) 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 | ![DataTable foutia](https://cdn.fouita.com/assets/pics/template/data-table/data-table-red.jpg) 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 | ![DataTable foutia](https://cdn.fouita.com/assets/pics/template/data-table/data-table-red-blue.jpg) 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 | ![DataTable foutia](https://cdn.fouita.com/assets/pics/template/data-table/data-table-row.jpg) 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 | ![DataTable foutia](https://cdn.fouita.com/assets/pics/template/data-table/data-table-cells.jpg) 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 | ![DataTable foutia](https://cdn.fouita.com/assets/pics/template/data-table/data-table-sort.jpg) 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 | ![DataTable foutia](https://cdn.fouita.com/assets/pics/template/data-table/data-table-search.jpg) 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 | 109 | 110 | {#each keys(head) as h} 111 | 127 | {/each} 128 | 129 | 130 | 131 | 132 | {#each rows as row, i} 133 | 137 | {#each keys(head) as h} 138 | 143 | {/each} 144 | 145 | 146 | {#each keys(head) as h} 147 | 150 | 155 | 160 | 161 | {/each} 162 | 163 | {/each} 164 | 165 |
153 | {val(head[h])} 154 | 156 | {#if isCmp(row[h])} 157 | 158 | {:else}{val(row[h])}{/if} 159 |
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 | --------------------------------------------------------------------------------