@timlassiter11/yatl 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Timothy Lassiter
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.
package/README.md ADDED
@@ -0,0 +1,136 @@
1
+ # YATL
2
+ **Yet Another Table Library**
3
+
4
+ YATL is a lightweight and customizable JavaScript library for creating dynamic, interactive tables. It provides features like sorting, filtering, searching, and virtual scrolling, making it easy to work with large datasets in a performant way.
5
+
6
+ ## Features
7
+ - **Sorting**: Sort table rows by multiple columns (ascending or descending).
8
+ - **Filtering**: Filter rows based on multiple criteria or custom filter functions.
9
+ - **Searching**: Perform case-insensitive searches across table data with support for tokenization and regular expressions.
10
+ - **Virtual Scrolling**: Efficiently render large datasets with virtual scrolling.
11
+ - **Customizable Columns**: Define column properties like visibility, formatting, and sorting behavior.
12
+ - **Export to CSV**: Export table data to a CSV file.
13
+
14
+ ## Installation
15
+ Include the library in your project by downloading the source files from the [dist](./dist/) folder.
16
+
17
+ ### Using standard script tag
18
+ ```html
19
+ <script src="path/to/datatable.umd.js"></script>
20
+ <script>
21
+ const datatble = new yatl.DataTable("#myTable", {
22
+ ...
23
+ });
24
+ </script>
25
+ ```
26
+
27
+ ### Using ES6 module
28
+ ```javascript
29
+ import { DataTable } from "path/to/datatable.esm.js";
30
+
31
+ const datatable = new DataTable("#myTable", {
32
+ ...
33
+ });
34
+ ```
35
+
36
+ ## Styling
37
+ Some optional styling is included which adds sorting indicators and sticky headers. To use them simply include the stylesheet.
38
+
39
+ ```html
40
+ <link rel="stylesheet" href="path/to/datatable.css">
41
+ ```
42
+
43
+ ## Usage
44
+ ```javascript
45
+ // Initialize the DataTable
46
+ const dataTable = new DataTable("#myTable", {
47
+ columns: [
48
+ { field: "name", title: "First Name", sortable: true, searchable: true },
49
+ // Titles will be created from the field name
50
+ { field: "age", sortable: true },
51
+ { field: "city", searchable: true },
52
+ ],
53
+ data: [
54
+ { name: "Alice", age: 25, city: "New York" },
55
+ { name: "Bob", age: 30, city: "Los Angeles" },
56
+ { name: "Charlie", age: 35, city: "Chicago" },
57
+ ],
58
+ });
59
+
60
+ // Sort by age in ascending order
61
+ dataTable.sort("age", "asc");
62
+
63
+ // Filter rows to only people aged 25
64
+ dataTable.filter({ age: 25 });
65
+
66
+ // Filter rows to only people over 25
67
+ dataTable.filter((row) => row.age > 25);
68
+
69
+ // Search for Bob
70
+ dataTable.search("bob");
71
+
72
+ // Export table data to CSV
73
+ dataTable.export("my-table-data");
74
+
75
+ // Example with large dataset and virtual scrolling
76
+ const largeData = Array.from({ length: 10000 }, (_, i) => ({
77
+ id: i + 1,
78
+ name: `User ${i + 1}`,
79
+ age: Math.floor(Math.random() * 100),
80
+ city: ["New York", "Los Angeles", "Chicago", "Houston"][i % 4],
81
+ }));
82
+
83
+ const dataTable = new DataTable({
84
+ table: document.querySelector("#myTable"),
85
+ columns: [
86
+ { field: "id", title: "ID", sortable: true },
87
+ { field: "name", title: "Name", sortable: true },
88
+ { field: "age", title: "Age", sortable: true },
89
+ { field: "city", title: "City" },
90
+ ],
91
+ data: largeData,
92
+ virtualScroll: 1000, // Enable virtual scrolling if more than 1000 rows
93
+ });
94
+ ```
95
+
96
+ ### Virtual Scroll
97
+ Virtual scrolling is used to render only the rows that are visible (with some extras before and after). This allows the library to support tables with hundreads of thousands of rows without issue. This is done using some magic (*simple math...*) but requires it's parent enforce a height. To do this you can simply add a height to the table.
98
+
99
+ ```html
100
+ <body>
101
+ <table style="height: 500px;"></table>
102
+ </body>
103
+ ```
104
+
105
+ This will result in the following HTML after the table is initialized
106
+ ```html
107
+ <body>
108
+ <div class="dt-scroller" style="overflow: auto; height: 500px;">
109
+ <table></table>
110
+ </div>
111
+ </body>
112
+ ```
113
+
114
+ Most of the time this isn't ideal though and instead we'd like to let the layout work it's magic (*probably also simple math...*). To do this, it's best to wrap the table in an element that can enforce a height.
115
+
116
+ ```html
117
+ <body style="height: 100vh;">
118
+ <div style="display: flex; flex-direction: column; overflow: auto; height: 100%;">
119
+ <div>
120
+ ... Lot's of cool table controls or filters
121
+ </div>
122
+ <table></table>
123
+ <div>
124
+ ... Some boring footer info or something
125
+ </div>
126
+ </div>
127
+ </body>
128
+ ```
129
+
130
+ Since the `dt-scroller` wrapper listens to scroll and resize events, this allows the table to be responsive and update what is rendered as the layout changes.
131
+
132
+ # Known Issues
133
+ There are some limitations to virtual scrolling. For one, rows need to be a uniform height to accurately calculate the table height. Also, there seems to be a maximum element size that once exceeded, the contents are no longer rendered. I've found this to occur with datasets approaching 1 million rows in Chrome and unfortunately I have no workaround for it. If you have that many rows you definitely need some server side pagination and this is probably not the library for you.
134
+
135
+ # Examples
136
+ Examples can be found in the [examples](./examples/) directoy and are also hosted [here](https://timlassiter11.github.io/YATL/index.html) to view live.
@@ -0,0 +1,2 @@
1
+ .data-table{--dt-header-sorter-width: 1ch;--dt-header-resizer-width: 10px;--dt-header-drop-color: rgba(255, 255, 255, .1);position:relative;white-space:nowrap;overflow:auto;width:100%;table-layout:fixed!important}.dt-headers{position:sticky;top:0;z-index:1}.dt-headers th{overflow:hidden;box-sizing:border-box}.dt-headers .dt-header-content{position:relative}.dt-sortable .dt-header-content{cursor:pointer}.dt-header-title-wrapper{display:flex;flex-direction:row;align-items:center;flex-wrap:nowrap;overflow:hidden}.dt-sort-icon{position:relative;width:var(--dt-header-sorter-width);align-self:stretch;padding:0 12px;overflow:hidden;flex-shrink:0}.dt-sort-icon:after{content:"";position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}.dt-sortable.dt-descending .dt-sort-icon:after{content:"\2193"}.dt-sortable.dt-ascending .dt-sort-icon:after{content:"\2191"}.dt-resizer{position:absolute;top:0;right:calc((var(--dt-header-resizer-width) / 2) * -1);height:100%;width:var(--dt-header-resizer-width);cursor:ew-resize;z-index:2}.dt-resizer:after{content:"";position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:1px;height:60%;background-color:currentColor}.dt-headers>tr>th.dt-drag-over,.dt-headers>tr>th:has(.dt-drag-over){background-color:var(--dt-header-drop-color)}.data-table>tbody>tr>td,.dt-header-title{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.dt-empty{text-align:center;pointer-events:none}.dt-scroller{height:100%;overflow:auto}*:has(.data-table:has(.dt-virtual-scroll)){height:100%;min-height:0}
2
+ /*# sourceMappingURL=datatable.css.map */
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/datatable.css"],"sourcesContent":[".data-table {\n --dt-header-sorter-width: 1ch;\n --dt-header-resizer-width: 10px;\n --dt-header-drop-color: rgba(255, 255, 255, 0.1);\n\n position: relative;\n white-space: nowrap;\n overflow: auto;\n width: 100%;\n table-layout: fixed !important;\n}\n\n.dt-headers {\n position: sticky;\n top: 0;\n z-index: 1;\n}\n\n.dt-headers th {\n overflow: hidden;\n box-sizing: border-box;\n\n}\n\n.dt-headers .dt-header-content {\n position: relative;\n}\n\n.dt-sortable .dt-header-content {\n cursor: pointer;\n}\n\n.dt-header-title-wrapper {\n display: flex;\n flex-direction: row;\n align-items: center;\n flex-wrap: nowrap;\n overflow: hidden;;\n}\n\n.dt-sort-icon {\n position: relative;\n width: var(--dt-header-sorter-width);\n align-self: stretch;\n padding: 0 12px;\n overflow: hidden;\n flex-shrink: 0;\n}\n\n.dt-sort-icon::after {\n content: '';\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n}\n\n.dt-sortable.dt-descending .dt-sort-icon::after {\n content: '\\2193';\n}\n\n.dt-sortable.dt-ascending .dt-sort-icon::after {\n content: '\\2191';\n}\n\n.dt-resizer {\n position: absolute;\n top: 0;\n right: calc((var(--dt-header-resizer-width) / 2) * -1);\n height: 100%;\n width: var(--dt-header-resizer-width);\n cursor: ew-resize;\n z-index: 2;\n}\n\n.dt-resizer::after {\n content: '';\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 1px;\n height: 60%;\n background-color: currentColor;\n}\n\n.dt-headers > tr > th.dt-drag-over,\n.dt-headers > tr > th:has(.dt-drag-over) {\n background-color: var(--dt-header-drop-color);\n}\n\n.data-table > tbody > tr > td,\n.dt-header-title {\n text-overflow: ellipsis;\n white-space: nowrap;\n overflow: hidden;\n}\n\n.dt-empty {\n text-align: center;\n pointer-events: none;\n}\n\n.dt-scroller {\n height: 100%;\n overflow: auto;\n}\n\n/* This is a catch all to ensure*/\n*:has( .data-table:has( .dt-virtual-scroll)) {\n height: 100%;\n min-height: 0;\n}"],"mappings":"AAAA,CAAC,WACC,0BAA0B,IAC1B,2BAA2B,KAC3B,wBAAwB,KAAK,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAE5C,SAAU,SACV,YAAa,OACb,SAAU,KACV,MAAO,KACP,aAAc,eAChB,CAEA,CAAC,WACC,SAAU,OACV,IAAK,EACL,QAAS,CACX,CAEA,CANC,WAMW,GACV,SAAU,OACV,WAAY,UAEd,CAEA,CAZC,WAYW,CAAC,kBACX,SAAU,QACZ,CAEA,CAAC,YAAY,CAJA,kBAKX,OAAQ,OACV,CAEA,CAAC,wBACC,QAAS,KACT,eAAgB,IAChB,YAAa,OACb,UAAW,OACX,SAAU,MACZ,CAEA,CAAC,aACC,SAAU,SACV,MAAO,IAAI,0BACX,WAAY,QA3Cd,QA4CW,EAAE,KACX,SAAU,OACV,YAAa,CACf,CAEA,CATC,YASY,OACX,QAAS,GACT,SAAU,SACV,IAAK,IACL,KAAM,IACN,UAAW,UAAU,IAAI,CAAE,KAC7B,CAEA,CA7BC,WA6BW,CAAC,cAAc,CAjB1B,YAiBuC,OACtC,QAAS,OACX,CAEA,CAjCC,WAiCW,CAAC,aAAa,CArBzB,YAqBsC,OACrC,QAAS,OACX,CAEA,CAAC,WACC,SAAU,SACV,IAAK,EACL,MAAO,KAAK,CAAC,IAAI,2BAA2B,EAAE,GAAG,EAAE,IACnD,OAAQ,KACR,MAAO,IAAI,2BACX,OAAQ,UACR,QAAS,CACX,CAEA,CAVC,UAUU,OACT,QAAS,GACT,SAAU,SACV,IAAK,IACL,KAAM,IACN,UAAW,UAAU,IAAI,CAAE,MAC3B,MAAO,IACP,OAAQ,IACR,iBAAkB,YACpB,CAEA,CA1EC,UA0EW,CAAE,EAAG,CAAE,EAAE,CAAC,aACtB,CA3EC,UA2EW,CAAE,EAAG,CAAE,EAAE,KAAK,CADJ,cAEpB,iBAAkB,IAAI,uBACxB,CAEA,CA3FC,UA2FW,CAAE,KAAM,CAAE,EAAG,CAAE,GAC3B,CAAC,gBACC,cAAe,SACf,YAAa,OACb,SAAU,MACZ,CAEA,CAAC,SACC,WAAY,OACZ,eAAgB,IAClB,CAEA,CAAC,YACC,OAAQ,KACR,SAAU,IACZ,CAGA,CAAC,KAAM,CA7GN,UA6GiB,KAAM,CAAC,oBACvB,OAAQ,KACR,WAAY,CACd","names":[]}