diff --git a/demo/index.html b/demo/index.html
index 3782b1e..3fe16c7 100644
--- a/demo/index.html
+++ b/demo/index.html
@@ -94,13 +94,14 @@
Data Grid
resizable=true to make resizable columns
autosize=true to compute column sizes automatically
sort=true to make sortable columns
- selectable=true to allow row selection
+ selectable=true to allow multi-row selections
+ single-select=true to allow single-row selection - no need to set selectable=true
save-state=true to save grid state
-
diff --git a/dist/data-grid.css b/dist/data-grid.css
index aa3ef25..c8d9428 100644
--- a/dist/data-grid.css
+++ b/dist/data-grid.css
@@ -1,5 +1,5 @@
/**
- * Data Grid Web Component v2.0.12
+ * Data Grid Web Component v2.0.13
* https://github.com/lekoala/data-grid
*/
@keyframes dataGridShow {
@@ -19,6 +19,7 @@ data-grid {
--color-rgb: var(--bs-primary-rgb, 13, 110, 253);
--color: rgb(var(--color-rgb));
--highlight-color: #fffcee;
+ --selected-bgcolor: var(--bs-primary-bg-subtle, #cfe2ff);
--body-background: var(--bs-table-bg, #fff);
--striped-background: rgba(0, 0, 0, 0.05);
--header-background: var(--bs-gray-200, #e9ecef);
@@ -152,6 +153,9 @@ data-grid .dg-expandable.dg-expanded td {
white-space: normal;
word-break: break-all;
}
+data-grid .dg-selectable {
+ font-size: 1em;
+}
data-grid .dg-selectable label {
display: flex;
align-items: center;
@@ -252,7 +256,7 @@ data-grid input[type=checkbox] {
margin: 0;
padding: 0;
}
-data-grid input:not([type=checkbox]),
+data-grid input:not([type=checkbox], [type=radio]),
data-grid select {
background-color: var(--input-background, "#fff");
color: currentColor;
@@ -306,6 +310,9 @@ data-grid tbody td input.dg-editable {
data-grid tbody td input.dg-editable:focus {
box-shadow: inset 0px 0px 0px 1px var(--color);
}
+data-grid tbody tr:has(.dg-selectable [type=radio]:checked) {
+ background-color: var(--selected-bgcolor);
+}
data-grid.dg-empty tbody {
height: 4rem;
position: relative;
@@ -438,6 +445,7 @@ data-grid [aria-sort=descending]:after {
[data-bs-theme=dark] data-grid {
--scroller-color-lightness: 20%;
--highlight-color: #43423e;
+ --selected-bgcolor: var(--bs-primary-bg-subtle, #031633);
--body-background: #212529;
--striped-background: #2c3034;
--header-background: var(--bs-gray-800, #34373b);
diff --git a/dist/data-grid.css.map b/dist/data-grid.css.map
index b0cb99e..0c0d963 100644
--- a/dist/data-grid.css.map
+++ b/dist/data-grid.css.map
@@ -1 +1 @@
-{"version":3,"sources":["../scss/_core.scss","data-grid.css","../scss/_rtl.scss","../scss/_menu.scss","../scss/_actions.scss","../scss/_resizer.scss","../scss/_responsive.scss"],"names":[],"mappings":"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","file":"data-grid.css","sourcesContent":["/**\n * Data Grid Web Component v2.0.12\n * https://github.com/lekoala/data-grid\n */\n\n@keyframes dataGridShow {\n 0% {\n opacity: 1;\n }\n\n 100% {\n opacity: 0.5;\n }\n}\n\ndata-grid {\n --padding: 0.5rem;\n --padding-x: 0.75rem;\n --padding-y: 0.5rem;\n --padding-y-header: 0.75rem;\n --padding-half: calc(var(--padding) / 2);\n --color-rgb: var(--bs-primary-rgb, 13, 110, 253);\n --color: rgb(var(--color-rgb));\n\n --highlight-color: #fffcee;\n --body-background: var(--bs-table-bg, #fff);\n --striped-background: rgba(0, 0, 0, 0.05);\n --header-background: var(--bs-gray-200, #e9ecef);\n --header-color: var(--bs-dark, #212529);\n --input-background: var(--bs-body-bg, #ffffff);\n --input-border-color: var(--bs-border-color, #e9ecef);\n --btn-background: var(--bs-body-bg, #ffffff);\n --btn-color: var(--color);\n --btn-border-color: var(--bs-border-color, #e9ecef);\n --body-bg: var(--bs-body-bg, #212529);\n --body-color: var(--bs-body-color, #212529);\n --icon-scale: 1;\n --border-radius: 0.25rem;\n --row-border-color: #f2f2f2;\n --responsive-width: 60%;\n\n --black: var(--bs-black, #000);\n --white: var(--bs-white, #fff);\n --gray: var(--bs-gray, #6c757d);\n --gray-dark: var(--bs-gray-dark, #343a40);\n --gray-100: var(--bs-gray-100, #f8f9fa);\n --gray-200: var(--bs-gray-200, #e9ecef);\n --gray-300: var(--bs-gray-300, #dee2e6);\n --gray-400: var(--bs-gray-400, #ced4da);\n --gray-500: var(--bs-gray-500, #adb5bd);\n --gray-600: var(--bs-gray-600, #6c757d);\n --gray-700: var(--bs-gray-700, #495057);\n --gray-800: var(--bs-gray-800, #343a40);\n --gray-900: var(--bs-gray-900, #212529);\n\n display: block;\n min-height: 6rem;\n position: relative;\n\n // When used with fixed height, have a nice scrollbar\n & {\n --scroller-color: 0, 0%;\n --scroller-color-lightness: 80%;\n --scroller-hover-factor: 0.8;\n --scroller-thumb: hsl(var(--scroller-color), var(--scroller-color-lightness));\n /* Replicate hover for webkit */\n --scroller-thumb-hover: hsl(var(--scroller-color), calc(var(--scroller-color-lightness) * var(--scroller-hover-factor)));\n --scroller-background: transparent;\n scrollbar-color: var(--scroller-thumb) var(--scroller-background);\n scrollbar-width: thin;\n\n &::-webkit-scrollbar {\n width: 8px;\n height: 8px;\n }\n\n &::-webkit-scrollbar-track {\n background: transparent;\n }\n\n &::-webkit-scrollbar-thumb {\n background: var(--scroller-thumb);\n }\n\n &::-webkit-scrollbar-thumb:hover {\n background: var(--scroller-thumb-hover);\n }\n }\n\n // Hides column header row when it's not populated\n > table {\n &[role=grid] {\n tr.dg-head-columns:is(:empty, :has(>:first-child:not([scope=col]))) {\n display: none;\n }\n }\n }\n\n img {\n border: none;\n height: auto;\n max-width: 100%;\n vertical-align: middle;\n }\n\n [hidden] {\n display: none;\n }\n\n table {\n display: table;\n // Table and column widths are set by the widths of table and col elements\n // or by the width of the first row of cells. Cells in subsequent rows do not affect column widths.\n table-layout: fixed;\n width: 100%;\n max-width: 100%;\n white-space: normal;\n // Background needs to be on the table, not on the component in case the table overflows the component\n background: var(--body-background);\n }\n\n thead,\n tfoot {\n background-color: var(--header-background);\n color: var(--header-color);\n }\n\n &.dg-loading {\n &:not(.dg-initialized) {\n\n thead,\n tfoot {\n background: none;\n }\n }\n\n tbody {\n animation-name: dataGridShow;\n animation-timing-function: ease-in;\n animation-fill-mode: forwards;\n animation-duration: 0.3s; // only triggers after 300ms\n pointer-events: none; // disable clicks while loading\n }\n\n &:not(:has(th)) {\n tfoot {\n display: none;\n }\n }\n }\n\n tr {\n position: relative;\n }\n\n th,\n td {\n empty-cells: show;\n padding: var(--padding-y) var(--padding-x);\n text-align: left;\n\n &[tabindex] {\n outline: none;\n word-break: normal;\n }\n }\n\n th {\n font-weight: bold;\n padding: var(--padding-y-header) var(--padding-x);\n }\n\n // Prevent overflow on headers and cells\n th,\n td {\n position: relative;\n overflow: hidden;\n text-align: left;\n // These two properties keep content on one line\n text-overflow: ellipsis;\n white-space: nowrap;\n\n // Use this to allow content to flow over multiple lines\n &.dg-wrap {\n white-space: normal;\n word-break: break-all;\n }\n }\n\n // Expand on multiple lines on row click\n .dg-expandable {\n cursor: pointer;\n\n &.dg-expanded td {\n white-space: normal;\n word-break: break-all;\n }\n }\n\n .dg-selectable {\n label {\n display: flex;\n align-items: center;\n margin:0;\n }\n }\n\n .dg-clickable-cell {\n margin: 0;\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n // Stick headers\n // https://css-tricks.com/making-tables-with-sticky-header-and-footers-got-a-bit-easier/\n &[sticky] table {\n\n thead,\n tfoot {\n z-index: 2;\n position: sticky;\n margin: 0;\n border: 0;\n }\n\n // Use silly value to prevent sub pixel alignment issue\n thead {\n inset-block-start: -1px;\n }\n\n tfoot {\n inset-block-end: -1px;\n }\n }\n\n // Pagination icons\n .dg-nav-icon,\n .dg-skip-icon {\n width: 22px;\n height: 22px;\n box-sizing: border-box;\n position: absolute;\n display: block;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%) scale(var(--icon-scale, 1));\n\n &:before,\n &:after {\n content: \"\";\n display: block;\n box-sizing: border-box;\n position: absolute;\n }\n }\n\n .dg-nav-icon::before {\n width: 0;\n height: 10px;\n border-top: 5px solid transparent;\n border-bottom: 5px solid transparent;\n border-left: 6px solid;\n top: 6px;\n left: 9px;\n }\n\n .dg-skip-icon {\n &::before {\n width: 3px;\n height: 10px;\n background: currentColor;\n top: 6px;\n left: 14px;\n }\n\n &::after {\n width: 0;\n height: 10px;\n border-top: 5px solid transparent;\n border-bottom: 5px solid transparent;\n border-left: 6px solid;\n top: 6px;\n left: 7px;\n }\n }\n\n .dg-rotate {\n transform: rotate(-180deg);\n }\n\n // Default actions buttons\n button {\n background-color: var(--btn-background);\n border: solid 1px var(--btn-border-color);\n border-radius: var(--border-radius);\n color: var(--body-color);\n height: 2rem;\n margin: 0 0.2rem;\n padding: 0 0.5rem;\n pointer-events: all;\n text-align: center;\n cursor: pointer;\n\n &:hover {\n opacity: 0.7;\n }\n\n &:disabled:hover {\n background-color: inherit;\n border-color: inherit;\n }\n }\n\n // Form elements\n input[type=\"checkbox\"] {\n margin: 0;\n padding: 0;\n }\n\n input:not([type=\"checkbox\"]),\n select {\n background-color: var(--input-background, \"#fff\");\n color: currentColor;\n box-sizing: border-box;\n border: 1px solid var(--input-border-color, \"#f0f0f0\");\n border-radius: var(--border-radius);\n height: 2rem;\n margin: 0 0.2rem;\n padding: 0 var(--padding);\n max-width: none;\n }\n\n input:not([type=\"checkbox\"]),\n select,\n button {\n &:focus {\n box-shadow: 0 0 0 var(--padding-half) rgba(var(--color-rgb), 0.25);\n outline: 0;\n }\n\n &[disabled],\n &:disabled {\n opacity: 0.35;\n pointer-events: none;\n }\n }\n\n // Filters (2nd header row)\n thead tr:nth-child(2) th {\n padding: 0 2px 0 0;\n background-color: transparent;\n\n > * {\n width: 100%;\n border-radius: 0;\n margin: 0;\n }\n\n input {\n &:focus {\n box-shadow: inset 0px 0px 0px 1px var(--color);\n }\n }\n }\n\n // Editable\n tbody td.dg-editable-col {\n padding: 0;\n height: 0; // it needs a height for height 100%\n }\n\n tbody td input.dg-editable {\n width: 100%;\n background: transparent;\n border: 0;\n border-radius: 0;\n margin: 0;\n box-shadow: none;\n height: 100%;\n\n &:focus {\n box-shadow: inset 0px 0px 0px 1px var(--color);\n }\n }\n\n // Empty table or error message (don't use :empty as it would create fouc on load)\n &.dg-empty {\n tbody {\n height: 4rem;\n position: relative;\n\n &:before {\n position: absolute;\n top: 50%;\n left: 50%;\n content: attr(data-empty);\n transform: translate(-50%, -50%);\n opacity: 0.5;\n font-size: 1.5rem;\n text-align: center;\n white-space: nowrap;\n text-overflow: ellipsis;\n overflow: hidden;\n width: 90%;\n }\n }\n\n tr {\n &.dg-fake-row {\n height: 4rem;\n border: none;\n }\n }\n\n &.dg-network-error {\n table {\n color: #842029;\n background-color: #f8d7da;\n border: 1px solid #f5c2c7;\n }\n\n tbody {\n height: auto;\n\n &:before {\n font-size: 1.2rem;\n }\n\n tr:not(.dg-fake-row) {\n display: none;\n }\n }\n }\n }\n\n // Zebra/striped rows\n tbody tr {\n &:nth-child(even) {\n background-color: var(--striped-background);\n }\n\n border-bottom: solid 1px var(--row-border-color);\n\n &:hover {\n background-color: var(--highlight-color) !important;\n }\n\n &:focus {\n background-color: var(--highlight-color) !important;\n border-bottom-color: var(--highlight-color) !important;\n outline: none;\n }\n }\n\n // Meta footer\n tfoot {\n min-width: 280px;\n\n td {\n padding: var(--padding-y-header) var(--padding-x);\n }\n\n .dg-page-nav {\n display: flex;\n align-items: center;\n /*min-width: 160px;*/\n }\n\n .dg-input-page {\n width: 4rem;\n }\n\n .dg-footer {\n display: flex;\n align-items: center;\n flex-direction: row;\n justify-content: space-between;\n }\n\n .dg-pagination {\n display: flex;\n text-align: center;\n\n button {\n // Fix icon inside button\n position: relative;\n width: 2rem;\n }\n }\n\n .dg-meta {\n // Prevent layout from jumping around\n /*min-width: 160px;*/\n text-align: right;\n }\n\n &.dg-footer-compact {\n .dg-meta {\n display: none;\n }\n\n .dg-input-page {\n display: none;\n }\n }\n }\n\n // Pagination in header\n [aria-sort] {\n cursor: pointer;\n padding-right: 1.5rem;\n }\n\n [aria-sort=\"none\"]:after,\n [aria-sort=\"none\"]:before,\n [aria-sort=\"ascending\"]:before,\n [aria-sort=\"descending\"]:after {\n right: 0.5rem;\n top: calc(50% - 0.5rem);\n border: solid transparent;\n content: \" \";\n height: 0;\n width: 0;\n position: absolute;\n border-color: rgba(0, 0, 0, 0);\n border-width: 0.25rem;\n margin-left: -0.25rem;\n }\n\n [aria-sort=\"none\"] {\n &:before {\n border-bottom-color: currentColor;\n opacity: 0.25;\n top: calc(50% - 0.6rem);\n }\n\n &:after {\n border-top-color: currentColor;\n opacity: 0.25;\n bottom: calc(50% - 0.5rem);\n top: auto;\n }\n }\n\n [aria-sort=\"ascending\"]:before {\n border-bottom-color: var(--body-color);\n opacity: 0.75;\n }\n\n [aria-sort=\"descending\"]:after {\n border-top-color: var(--body-color);\n opacity: 0.75;\n bottom: calc(50% - 0.5rem);\n top: auto;\n }\n}\n\n[data-bs-theme=\"dark\"] data-grid {\n --scroller-color-lightness: 20%;\n --highlight-color: #43423e;\n --body-background: #212529;\n --striped-background: #2c3034;\n --header-background: var(--bs-gray-800, #34373b);\n --header-color: var(--bs-light, #e9ecef);\n --body-color: var(--bs-body-color, #494e53);\n --row-border-color: var(--bs-gray-900, #212325);\n}\n\n","/**\n * Data Grid Web Component v2.0.12\n * https://github.com/lekoala/data-grid\n */\n@keyframes dataGridShow {\n 0% {\n opacity: 1;\n }\n 100% {\n opacity: 0.5;\n }\n}\ndata-grid {\n --padding: 0.5rem;\n --padding-x: 0.75rem;\n --padding-y: 0.5rem;\n --padding-y-header: 0.75rem;\n --padding-half: calc(var(--padding) / 2);\n --color-rgb: var(--bs-primary-rgb, 13, 110, 253);\n --color: rgb(var(--color-rgb));\n --highlight-color: #fffcee;\n --body-background: var(--bs-table-bg, #fff);\n --striped-background: rgba(0, 0, 0, 0.05);\n --header-background: var(--bs-gray-200, #e9ecef);\n --header-color: var(--bs-dark, #212529);\n --input-background: var(--bs-body-bg, #ffffff);\n --input-border-color: var(--bs-border-color, #e9ecef);\n --btn-background: var(--bs-body-bg, #ffffff);\n --btn-color: var(--color);\n --btn-border-color: var(--bs-border-color, #e9ecef);\n --body-bg: var(--bs-body-bg, #212529);\n --body-color: var(--bs-body-color, #212529);\n --icon-scale: 1;\n --border-radius: 0.25rem;\n --row-border-color: #f2f2f2;\n --responsive-width: 60%;\n --black: var(--bs-black, #000);\n --white: var(--bs-white, #fff);\n --gray: var(--bs-gray, #6c757d);\n --gray-dark: var(--bs-gray-dark, #343a40);\n --gray-100: var(--bs-gray-100, #f8f9fa);\n --gray-200: var(--bs-gray-200, #e9ecef);\n --gray-300: var(--bs-gray-300, #dee2e6);\n --gray-400: var(--bs-gray-400, #ced4da);\n --gray-500: var(--bs-gray-500, #adb5bd);\n --gray-600: var(--bs-gray-600, #6c757d);\n --gray-700: var(--bs-gray-700, #495057);\n --gray-800: var(--bs-gray-800, #343a40);\n --gray-900: var(--bs-gray-900, #212529);\n display: block;\n min-height: 6rem;\n position: relative;\n}\ndata-grid {\n --scroller-color: 0, 0%;\n --scroller-color-lightness: 80%;\n --scroller-hover-factor: 0.8;\n --scroller-thumb: hsl(var(--scroller-color), var(--scroller-color-lightness));\n /* Replicate hover for webkit */\n --scroller-thumb-hover: hsl(var(--scroller-color), calc(var(--scroller-color-lightness) * var(--scroller-hover-factor)));\n --scroller-background: transparent;\n scrollbar-color: var(--scroller-thumb) var(--scroller-background);\n scrollbar-width: thin;\n}\ndata-grid::-webkit-scrollbar {\n width: 8px;\n height: 8px;\n}\ndata-grid::-webkit-scrollbar-track {\n background: transparent;\n}\ndata-grid::-webkit-scrollbar-thumb {\n background: var(--scroller-thumb);\n}\ndata-grid::-webkit-scrollbar-thumb:hover {\n background: var(--scroller-thumb-hover);\n}\ndata-grid > table[role=grid] tr.dg-head-columns:is(:empty, :has(> :first-child:not([scope=col]))) {\n display: none;\n}\ndata-grid img {\n border: none;\n height: auto;\n max-width: 100%;\n vertical-align: middle;\n}\ndata-grid [hidden] {\n display: none;\n}\ndata-grid table {\n display: table;\n table-layout: fixed;\n width: 100%;\n max-width: 100%;\n white-space: normal;\n background: var(--body-background);\n}\ndata-grid thead,\ndata-grid tfoot {\n background-color: var(--header-background);\n color: var(--header-color);\n}\ndata-grid.dg-loading:not(.dg-initialized) thead,\ndata-grid.dg-loading:not(.dg-initialized) tfoot {\n background: none;\n}\ndata-grid.dg-loading tbody {\n animation-name: dataGridShow;\n animation-timing-function: ease-in;\n animation-fill-mode: forwards;\n animation-duration: 0.3s;\n pointer-events: none;\n}\ndata-grid.dg-loading:not(:has(th)) tfoot {\n display: none;\n}\ndata-grid tr {\n position: relative;\n}\ndata-grid th,\ndata-grid td {\n empty-cells: show;\n padding: var(--padding-y) var(--padding-x);\n text-align: left;\n}\ndata-grid th[tabindex],\ndata-grid td[tabindex] {\n outline: none;\n word-break: normal;\n}\ndata-grid th {\n font-weight: bold;\n padding: var(--padding-y-header) var(--padding-x);\n}\ndata-grid th,\ndata-grid td {\n position: relative;\n overflow: hidden;\n text-align: left;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\ndata-grid th.dg-wrap,\ndata-grid td.dg-wrap {\n white-space: normal;\n word-break: break-all;\n}\ndata-grid .dg-expandable {\n cursor: pointer;\n}\ndata-grid .dg-expandable.dg-expanded td {\n white-space: normal;\n word-break: break-all;\n}\ndata-grid .dg-selectable label {\n display: flex;\n align-items: center;\n margin: 0;\n}\ndata-grid .dg-clickable-cell {\n margin: 0;\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n}\ndata-grid[sticky] table thead,\ndata-grid[sticky] table tfoot {\n z-index: 2;\n position: sticky;\n margin: 0;\n border: 0;\n}\ndata-grid[sticky] table thead {\n inset-block-start: -1px;\n}\ndata-grid[sticky] table tfoot {\n inset-block-end: -1px;\n}\ndata-grid .dg-nav-icon,\ndata-grid .dg-skip-icon {\n width: 22px;\n height: 22px;\n box-sizing: border-box;\n position: absolute;\n display: block;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%) scale(var(--icon-scale, 1));\n}\ndata-grid .dg-nav-icon:before, data-grid .dg-nav-icon:after,\ndata-grid .dg-skip-icon:before,\ndata-grid .dg-skip-icon:after {\n content: \"\";\n display: block;\n box-sizing: border-box;\n position: absolute;\n}\ndata-grid .dg-nav-icon::before {\n width: 0;\n height: 10px;\n border-top: 5px solid transparent;\n border-bottom: 5px solid transparent;\n border-left: 6px solid;\n top: 6px;\n left: 9px;\n}\ndata-grid .dg-skip-icon::before {\n width: 3px;\n height: 10px;\n background: currentColor;\n top: 6px;\n left: 14px;\n}\ndata-grid .dg-skip-icon::after {\n width: 0;\n height: 10px;\n border-top: 5px solid transparent;\n border-bottom: 5px solid transparent;\n border-left: 6px solid;\n top: 6px;\n left: 7px;\n}\ndata-grid .dg-rotate {\n transform: rotate(-180deg);\n}\ndata-grid button {\n background-color: var(--btn-background);\n border: solid 1px var(--btn-border-color);\n border-radius: var(--border-radius);\n color: var(--body-color);\n height: 2rem;\n margin: 0 0.2rem;\n padding: 0 0.5rem;\n pointer-events: all;\n text-align: center;\n cursor: pointer;\n}\ndata-grid button:hover {\n opacity: 0.7;\n}\ndata-grid button:disabled:hover {\n background-color: inherit;\n border-color: inherit;\n}\ndata-grid input[type=checkbox] {\n margin: 0;\n padding: 0;\n}\ndata-grid input:not([type=checkbox]),\ndata-grid select {\n background-color: var(--input-background, \"#fff\");\n color: currentColor;\n box-sizing: border-box;\n border: 1px solid var(--input-border-color, \"#f0f0f0\");\n border-radius: var(--border-radius);\n height: 2rem;\n margin: 0 0.2rem;\n padding: 0 var(--padding);\n max-width: none;\n}\ndata-grid input:not([type=checkbox]):focus,\ndata-grid select:focus,\ndata-grid button:focus {\n box-shadow: 0 0 0 var(--padding-half) rgba(var(--color-rgb), 0.25);\n outline: 0;\n}\ndata-grid input:not([type=checkbox])[disabled], data-grid input:not([type=checkbox]):disabled,\ndata-grid select[disabled],\ndata-grid select:disabled,\ndata-grid button[disabled],\ndata-grid button:disabled {\n opacity: 0.35;\n pointer-events: none;\n}\ndata-grid thead tr:nth-child(2) th {\n padding: 0 2px 0 0;\n background-color: transparent;\n}\ndata-grid thead tr:nth-child(2) th > * {\n width: 100%;\n border-radius: 0;\n margin: 0;\n}\ndata-grid thead tr:nth-child(2) th input:focus {\n box-shadow: inset 0px 0px 0px 1px var(--color);\n}\ndata-grid tbody td.dg-editable-col {\n padding: 0;\n height: 0;\n}\ndata-grid tbody td input.dg-editable {\n width: 100%;\n background: transparent;\n border: 0;\n border-radius: 0;\n margin: 0;\n box-shadow: none;\n height: 100%;\n}\ndata-grid tbody td input.dg-editable:focus {\n box-shadow: inset 0px 0px 0px 1px var(--color);\n}\ndata-grid.dg-empty tbody {\n height: 4rem;\n position: relative;\n}\ndata-grid.dg-empty tbody:before {\n position: absolute;\n top: 50%;\n left: 50%;\n content: attr(data-empty);\n transform: translate(-50%, -50%);\n opacity: 0.5;\n font-size: 1.5rem;\n text-align: center;\n white-space: nowrap;\n text-overflow: ellipsis;\n overflow: hidden;\n width: 90%;\n}\ndata-grid.dg-empty tr.dg-fake-row {\n height: 4rem;\n border: none;\n}\ndata-grid.dg-empty.dg-network-error table {\n color: #842029;\n background-color: #f8d7da;\n border: 1px solid #f5c2c7;\n}\ndata-grid.dg-empty.dg-network-error tbody {\n height: auto;\n}\ndata-grid.dg-empty.dg-network-error tbody:before {\n font-size: 1.2rem;\n}\ndata-grid.dg-empty.dg-network-error tbody tr:not(.dg-fake-row) {\n display: none;\n}\ndata-grid tbody tr {\n border-bottom: solid 1px var(--row-border-color);\n}\ndata-grid tbody tr:nth-child(even) {\n background-color: var(--striped-background);\n}\ndata-grid tbody tr:hover {\n background-color: var(--highlight-color) !important;\n}\ndata-grid tbody tr:focus {\n background-color: var(--highlight-color) !important;\n border-bottom-color: var(--highlight-color) !important;\n outline: none;\n}\ndata-grid tfoot {\n min-width: 280px;\n}\ndata-grid tfoot td {\n padding: var(--padding-y-header) var(--padding-x);\n}\ndata-grid tfoot .dg-page-nav {\n display: flex;\n align-items: center;\n /*min-width: 160px;*/\n}\ndata-grid tfoot .dg-input-page {\n width: 4rem;\n}\ndata-grid tfoot .dg-footer {\n display: flex;\n align-items: center;\n flex-direction: row;\n justify-content: space-between;\n}\ndata-grid tfoot .dg-pagination {\n display: flex;\n text-align: center;\n}\ndata-grid tfoot .dg-pagination button {\n position: relative;\n width: 2rem;\n}\ndata-grid tfoot .dg-meta {\n /*min-width: 160px;*/\n text-align: right;\n}\ndata-grid tfoot.dg-footer-compact .dg-meta {\n display: none;\n}\ndata-grid tfoot.dg-footer-compact .dg-input-page {\n display: none;\n}\ndata-grid [aria-sort] {\n cursor: pointer;\n padding-right: 1.5rem;\n}\ndata-grid [aria-sort=none]:after,\ndata-grid [aria-sort=none]:before,\ndata-grid [aria-sort=ascending]:before,\ndata-grid [aria-sort=descending]:after {\n right: 0.5rem;\n top: calc(50% - 0.5rem);\n border: solid transparent;\n content: \" \";\n height: 0;\n width: 0;\n position: absolute;\n border-color: rgba(0, 0, 0, 0);\n border-width: 0.25rem;\n margin-left: -0.25rem;\n}\ndata-grid [aria-sort=none]:before {\n border-bottom-color: currentColor;\n opacity: 0.25;\n top: calc(50% - 0.6rem);\n}\ndata-grid [aria-sort=none]:after {\n border-top-color: currentColor;\n opacity: 0.25;\n bottom: calc(50% - 0.5rem);\n top: auto;\n}\ndata-grid [aria-sort=ascending]:before {\n border-bottom-color: var(--body-color);\n opacity: 0.75;\n}\ndata-grid [aria-sort=descending]:after {\n border-top-color: var(--body-color);\n opacity: 0.75;\n bottom: calc(50% - 0.5rem);\n top: auto;\n}\n\n[data-bs-theme=dark] data-grid {\n --scroller-color-lightness: 20%;\n --highlight-color: #43423e;\n --body-background: #212529;\n --striped-background: #2c3034;\n --header-background: var(--bs-gray-800, #34373b);\n --header-color: var(--bs-light, #e9ecef);\n --body-color: var(--bs-body-color, #494e53);\n --row-border-color: var(--bs-gray-900, #212325);\n}\n\ndata-grid[dir=rtl] th,\ndata-grid[dir=rtl] td {\n text-align: right;\n}\ndata-grid[dir=rtl] [aria-sort] {\n padding-left: 1rem;\n padding-right: 0.5rem;\n}\ndata-grid[dir=rtl] [aria-sort=none]:after,\ndata-grid[dir=rtl] [aria-sort=none]:before,\ndata-grid[dir=rtl] [aria-sort=ascending]:before,\ndata-grid[dir=rtl] [aria-sort=descending]:after {\n left: 0.75rem;\n right: auto;\n}\ndata-grid[dir=rtl] tfoot .dg-meta {\n text-align: left;\n}\n\ndata-grid .dg-menu {\n position: absolute;\n z-index: 3;\n background: var(--body-bg);\n list-style: none;\n max-width: 150px;\n margin: 0;\n padding: var(--padding);\n box-shadow: 0 0 1rem rgba(0, 0, 0, 0.25);\n border-radius: var(--border-radius);\n}\ndata-grid .dg-menu li {\n margin: 0;\n padding: 0;\n}\ndata-grid .dg-menu label {\n display: flex;\n align-items: center;\n margin-bottom: 0.25em;\n}\ndata-grid .dg-menu input {\n margin-right: 0.5em;\n}\n\ndata-grid .dg-actions {\n text-overflow: initial;\n width: 100px;\n text-align: right;\n white-space: nowrap !important;\n}\ndata-grid .dg-actions button {\n margin: 0;\n}\ndata-grid .dg-actions button + button {\n margin-left: 0.25rem;\n}\ndata-grid .dg-actions .dg-actions-toggle {\n display: none;\n width: calc(100px - var(--padding-x) * 2);\n}\ndata-grid .dg-actions.dg-actions-1 {\n width: 100%;\n}\ndata-grid .dg-actions.dg-actions-2 button {\n width: calc(50% - 0.25rem);\n}\ndata-grid .dg-actions.dg-actions-more button {\n display: none;\n}\ndata-grid .dg-actions.dg-actions-more button.dg-actions-toggle {\n display: inline-block;\n}\ndata-grid .dg-actions.dg-actions-expand {\n position: absolute;\n right: 0;\n display: flex;\n align-items: center;\n justify-content: flex-end;\n width: 100%;\n height: 100%;\n}\ndata-grid .dg-actions.dg-actions-expand.dg-actions-more {\n width: 100%;\n}\ndata-grid .dg-actions.dg-actions-expand.dg-actions-more button {\n display: inline-block;\n}\ndata-grid tr.dg-actionable {\n cursor: pointer;\n}\ndata-grid tr.dg-actionable:hover td {\n background-color: var(--highlight-color);\n}\n\ndata-grid .dg-resizer {\n position: absolute;\n top: 0;\n right: 0;\n width: 6px;\n z-index: 2;\n cursor: col-resize;\n user-select: none;\n}\ndata-grid .dg-resizer:before {\n content: \"\";\n display: block;\n position: absolute;\n top: var(--padding-y-header);\n height: 1.5rem;\n right: 0;\n width: 2px;\n background: var(--body-color);\n opacity: 0.2;\n}\ndata-grid .dg-resizer:hover:before {\n opacity: 0.6;\n}\ndata-grid .dg-resizer.dg-resizer-active {\n border-right: 1px dashed var(--color);\n}\ndata-grid .dg-resizer.dg-resizer-active:before {\n opacity: 0.6;\n}\n\ndata-grid .dg-responsive-toggle {\n padding: 0;\n text-align: center;\n}\ndata-grid .dg-responsive-child-row > td {\n padding: 0;\n}\ndata-grid .dg-responsive-table {\n table-layout: auto;\n border: 0;\n}\ndata-grid .dg-responsive-table td,\ndata-grid .dg-responsive-table th {\n white-space: normal;\n}\ndata-grid .dg-responsive-table th {\n max-width: 40%;\n}\n\n@media only screen and (max-width: 767px) {\n data-grid[responsive] .dg-resizer {\n display: none;\n }\n data-grid[responsive] .dg-meta {\n display: none;\n }\n data-grid[responsive] .dg-input-page {\n display: none;\n }\n data-grid[responsive] table,\n data-grid[responsive] tbody,\n data-grid[responsive] tfoot,\n data-grid[responsive] th,\n data-grid[responsive] td,\n data-grid[responsive] tr:not([hidden]) {\n display: block;\n }\n data-grid[responsive] thead {\n display: flex;\n border-bottom: 2px solid var(--header-background);\n }\n data-grid[responsive] thead > tr {\n flex-grow: 1;\n }\n data-grid[responsive] thead th {\n width: auto;\n }\n data-grid[responsive] tbody tr {\n padding: 0;\n border: 1px solid var(--header-background);\n }\n data-grid[responsive] tbody td {\n border: none;\n border-bottom: 1px solid var(--row-border-color);\n position: relative;\n padding-left: calc(100% - var(--responsive-width) - var(--padding) * 2);\n }\n data-grid[responsive] tbody td:last-child {\n border: 0;\n }\n data-grid[responsive] tbody td:before {\n position: absolute;\n top: 0;\n left: 0;\n padding: var(--padding);\n width: calc(100% - var(--responsive-width) - var(--padding) * 4);\n content: attr(data-name);\n display: block;\n font-weight: bold;\n background-color: var(--header-background);\n }\n data-grid[responsive] tbody td[role=gridcell] {\n padding-left: calc(100% - var(--responsive-width) - var(--padding) * 4 + 0.5rem);\n }\n data-grid[responsive] .dg-selectable {\n height: 28px;\n margin: 2px 1px 2px;\n }\n data-grid[responsive] td.dg-selectable::before, data-grid[responsive] td.dg-actions::before {\n padding: 0;\n }\n data-grid[responsive] td.dg-selectable label {\n padding: 5px;\n }\n data-grid[responsive] td[role=gridcell] {\n min-height: 35px;\n width: auto;\n }\n data-grid[responsive] td[data-name]::before {\n height: 100%;\n }\n data-grid[responsive] td.dg-actions {\n padding-left: inherit;\n width: inherit;\n }\n data-grid[responsive] .dg-actions button {\n width: inherit !important;\n }\n data-grid[responsive] tr.dg-head-columns {\n padding: 0;\n width: calc(100% - var(--responsive-width) - var(--padding) * 4);\n }\n data-grid[responsive] tr.dg-head-columns th[role=\"columnheader button\"] {\n padding: 0.36em 1.3em 0.36em 0.75em;\n }\n data-grid[responsive] tr.dg-head-filters {\n background: transparent;\n vertical-align: top;\n padding: 0;\n width: calc(100% - (100% - var(--responsive-width) - var(--padding) * 4));\n }\n data-grid[responsive] .dg-head-filters th input:not([type=checkbox], [type=radio]) {\n height: 2.25em;\n }\n data-grid[responsive] .dg-head-filters th.dg-selectable {\n background: transparent;\n }\n data-grid[responsive] .dg-head-filters th.dg-selectable label::before {\n content: \"Column Filters\";\n }\n data-grid[responsive] tfoot .dg-page-nav {\n min-width: revert;\n }\n data-grid[data-responsive=true] tfoot .dg-page-nav {\n min-width: revert;\n }\n}\n\n/*# sourceMappingURL=data-grid.css.map */\n","data-grid {\r\n &[dir=\"rtl\"] {\r\n th,\r\n td {\r\n text-align: right;\r\n }\r\n [aria-sort] {\r\n padding-left: 1rem;\r\n padding-right: 0.5rem;\r\n }\r\n [aria-sort=\"none\"]:after,\r\n [aria-sort=\"none\"]:before,\r\n [aria-sort=\"ascending\"]:before,\r\n [aria-sort=\"descending\"]:after {\r\n left: 0.75rem;\r\n right: auto;\r\n }\r\n tfoot .dg-meta {\r\n text-align: left;\r\n }\r\n }\r\n}\r\n","data-grid {\r\n .dg-menu {\r\n position: absolute;\r\n z-index: 3;\r\n background: var(--body-bg);\r\n list-style: none;\r\n max-width: 150px;\r\n margin: 0;\r\n padding: var(--padding);\r\n box-shadow: 0 0 1rem rgba(0, 0, 0, 0.25);\r\n border-radius: var(--border-radius);\r\n\r\n li {\r\n margin: 0;\r\n padding: 0;\r\n }\r\n label {\r\n display: flex;\r\n align-items: center;\r\n margin-bottom: 0.25em;\r\n }\r\n input {\r\n margin-right: 0.5em;\r\n }\r\n }\r\n}\r\n","data-grid {\r\n .dg-actions {\r\n text-overflow: initial;\r\n width: 100px;\r\n text-align: right;\r\n white-space: nowrap !important;\r\n\r\n button {\r\n margin: 0;\r\n\r\n + button {\r\n margin-left: 0.25rem;\r\n }\r\n }\r\n .dg-actions-toggle {\r\n display: none;\r\n width: calc(100px - var(--padding-x) * 2);\r\n }\r\n &.dg-actions-1 {\r\n width: 100%;\r\n }\r\n // This needs icons to work\r\n &.dg-actions-2 button {\r\n width: calc(50% - 0.25rem);\r\n }\r\n &.dg-actions-more button {\r\n display: none;\r\n\r\n &.dg-actions-toggle {\r\n display: inline-block;\r\n }\r\n }\r\n &.dg-actions-expand {\r\n position: absolute;\r\n right: 0;\r\n display: flex;\r\n align-items: center;\r\n justify-content: flex-end;\r\n width: 100%;\r\n height: 100%;\r\n }\r\n &.dg-actions-expand.dg-actions-more {\r\n width: 100%;\r\n\r\n button {\r\n display: inline-block;\r\n }\r\n }\r\n }\r\n tr.dg-actionable {\r\n cursor: pointer;\r\n\r\n &:hover td {\r\n background-color: var(--highlight-color);\r\n }\r\n }\r\n}\r\n","data-grid {\r\n .dg-resizer {\r\n position: absolute;\r\n top: 0;\r\n right: 0;\r\n width: 6px; // clickable zone\r\n z-index: 2;\r\n cursor: col-resize;\r\n user-select: none;\r\n\r\n &:before {\r\n content: \"\";\r\n display: block;\r\n position: absolute;\r\n top: var(--padding-y-header);\r\n height: 1.5rem;\r\n right: 0;\r\n width: 2px;\r\n background: var(--body-color);\r\n opacity: 0.2;\r\n }\r\n &:hover:before {\r\n opacity: 0.6;\r\n }\r\n &.dg-resizer-active {\r\n border-right: 1px dashed var(--color);\r\n\r\n &:before {\r\n opacity: 0.6;\r\n }\r\n }\r\n }\r\n}\r\n","data-grid {\n .dg-responsive-toggle {\n padding: 0;\n text-align: center;\n }\n .dg-responsive-child-row > td {\n padding: 0;\n }\n .dg-responsive-table {\n table-layout: auto;\n border: 0;\n\n td,\n th {\n white-space: normal;\n }\n\n th {\n max-width: 40%;\n }\n }\n}\n\n// CSS Only responsive\n@media only screen and (max-width: 767px) {\n data-grid[responsive] {\n // Doesn't make any sense to resize\n .dg-resizer {\n display: none;\n }\n\n // more compact footer\n .dg-meta {\n display: none;\n }\n .dg-input-page {\n display: none;\n }\n\n // everything as blocks\n table,\n tbody,\n tfoot,\n th,\n td,\n tr:not([hidden]) {\n display: block;\n }\n\n // use flex for thead\n thead {\n display: flex;\n\n > tr {\n flex-grow: 1;\n }\n th {\n width: auto;\n }\n\n border-bottom: 2px solid var(--header-background);\n }\n\n // use pseudo element to display column name\n tbody {\n tr {\n padding: 0;\n border: 1px solid var(--header-background);\n }\n td {\n border: none;\n border-bottom: 1px solid var(--row-border-color);\n position: relative;\n padding-left: calc(100% - var(--responsive-width) - var(--padding) * 2);\n\n &:last-child {\n border: 0;\n }\n &:before {\n position: absolute;\n top: 0;\n left: 0;\n padding: var(--padding);\n width: calc(100% - var(--responsive-width) - var(--padding) * 4);\n content: attr(data-name);\n display: block;\n font-weight: bold;\n background-color: var(--header-background);\n }\n &[role=\"gridcell\"] {\n padding-left: calc(100% - var(--responsive-width) - var(--padding) * 4 + 0.5rem);\n }\n }\n }\n\n // give selectable some room\n .dg-selectable {\n height: 28px;\n margin: 2px 1px 2px;\n }\n\n td {\n &.dg-selectable::before,\n &.dg-actions::before {\n padding: 0;\n }\n &.dg-selectable label {\n padding: 5px;\n }\n &[role=\"gridcell\"] {\n min-height: 35px;\n width: auto;\n }\n &[data-name]::before {\n height: 100%;\n }\n &.dg-actions {\n padding-left: inherit;\n width: inherit;\n }\n }\n .dg-actions button {\n width: inherit !important;\n }\n tr {\n &.dg-head-columns {\n padding: 0;\n width: calc(100% - var(--responsive-width) - var(--padding) * 4);\n\n th[role=\"columnheader button\"] {\n padding: 0.36em 1.3em 0.36em 0.75em;\n }\n }\n &.dg-head-filters {\n background: transparent;\n vertical-align: top;\n padding: 0;\n width: calc(100% - (100% - var(--responsive-width) - var(--padding) * 4));\n }\n }\n .dg-head-filters th input:not([type=\"checkbox\"], [type=\"radio\"]) {\n height: 2.25em;\n }\n .dg-head-filters th.dg-selectable {\n background: transparent;\n }\n .dg-head-filters th.dg-selectable label::before {\n content: \"Column Filters\";\n }\n\n tfoot .dg-page-nav {\n min-width: revert;\n }\n }\n\n data-grid[data-responsive=true] {\n tfoot .dg-page-nav {\n min-width: revert;\n } \n }\n}\n"]}
\ No newline at end of file
+{"version":3,"sources":["../scss/_core.scss","data-grid.css","../scss/_rtl.scss","../scss/_menu.scss","../scss/_actions.scss","../scss/_resizer.scss","../scss/_responsive.scss"],"names":[],"mappings":"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","file":"data-grid.css","sourcesContent":["/**\r\n * Data Grid Web Component v2.0.13\r\n * https://github.com/lekoala/data-grid\r\n */\r\n\r\n@keyframes dataGridShow {\r\n 0% {\r\n opacity: 1;\r\n }\r\n\r\n 100% {\r\n opacity: 0.5;\r\n }\r\n}\r\n\r\ndata-grid {\r\n --padding: 0.5rem;\r\n --padding-x: 0.75rem;\r\n --padding-y: 0.5rem;\r\n --padding-y-header: 0.75rem;\r\n --padding-half: calc(var(--padding) / 2);\r\n --color-rgb: var(--bs-primary-rgb, 13, 110, 253);\r\n --color: rgb(var(--color-rgb));\r\n\r\n --highlight-color: #fffcee;\n --selected-bgcolor: var(--bs-primary-bg-subtle, #cfe2ff);\r\n --body-background: var(--bs-table-bg, #fff);\r\n --striped-background: rgba(0, 0, 0, 0.05);\r\n --header-background: var(--bs-gray-200, #e9ecef);\r\n --header-color: var(--bs-dark, #212529);\r\n --input-background: var(--bs-body-bg, #ffffff);\r\n --input-border-color: var(--bs-border-color, #e9ecef);\r\n --btn-background: var(--bs-body-bg, #ffffff);\r\n --btn-color: var(--color);\r\n --btn-border-color: var(--bs-border-color, #e9ecef);\r\n --body-bg: var(--bs-body-bg, #212529);\r\n --body-color: var(--bs-body-color, #212529);\r\n --icon-scale: 1;\r\n --border-radius: 0.25rem;\r\n --row-border-color: #f2f2f2;\r\n --responsive-width: 60%;\r\n\r\n --black: var(--bs-black, #000);\r\n --white: var(--bs-white, #fff);\r\n --gray: var(--bs-gray, #6c757d);\r\n --gray-dark: var(--bs-gray-dark, #343a40);\r\n --gray-100: var(--bs-gray-100, #f8f9fa);\r\n --gray-200: var(--bs-gray-200, #e9ecef);\r\n --gray-300: var(--bs-gray-300, #dee2e6);\r\n --gray-400: var(--bs-gray-400, #ced4da);\r\n --gray-500: var(--bs-gray-500, #adb5bd);\r\n --gray-600: var(--bs-gray-600, #6c757d);\r\n --gray-700: var(--bs-gray-700, #495057);\r\n --gray-800: var(--bs-gray-800, #343a40);\r\n --gray-900: var(--bs-gray-900, #212529);\r\n\r\n display: block;\r\n min-height: 6rem;\r\n position: relative;\r\n\r\n // When used with fixed height, have a nice scrollbar\r\n & {\r\n --scroller-color: 0, 0%;\r\n --scroller-color-lightness: 80%;\r\n --scroller-hover-factor: 0.8;\r\n --scroller-thumb: hsl(var(--scroller-color), var(--scroller-color-lightness));\r\n /* Replicate hover for webkit */\r\n --scroller-thumb-hover: hsl(var(--scroller-color), calc(var(--scroller-color-lightness) * var(--scroller-hover-factor)));\r\n --scroller-background: transparent;\r\n scrollbar-color: var(--scroller-thumb) var(--scroller-background);\r\n scrollbar-width: thin;\r\n\r\n &::-webkit-scrollbar {\r\n width: 8px;\r\n height: 8px;\r\n }\r\n\r\n &::-webkit-scrollbar-track {\r\n background: transparent;\r\n }\r\n\r\n &::-webkit-scrollbar-thumb {\r\n background: var(--scroller-thumb);\r\n }\r\n\r\n &::-webkit-scrollbar-thumb:hover {\r\n background: var(--scroller-thumb-hover);\r\n }\r\n }\r\n\r\n // Hides column header row when it's not populated\r\n > table {\r\n &[role=grid] {\r\n tr.dg-head-columns:is(:empty, :has(>:first-child:not([scope=col]))) {\r\n display: none;\r\n }\r\n }\r\n }\r\n\r\n img {\r\n border: none;\r\n height: auto;\r\n max-width: 100%;\r\n vertical-align: middle;\r\n }\r\n\r\n [hidden] {\r\n display: none;\r\n }\r\n\r\n table {\r\n display: table;\r\n // Table and column widths are set by the widths of table and col elements\r\n // or by the width of the first row of cells. Cells in subsequent rows do not affect column widths.\r\n table-layout: fixed;\r\n width: 100%;\r\n max-width: 100%;\r\n white-space: normal;\r\n // Background needs to be on the table, not on the component in case the table overflows the component\r\n background: var(--body-background);\r\n }\r\n\r\n thead,\r\n tfoot {\r\n background-color: var(--header-background);\r\n color: var(--header-color);\r\n }\r\n\r\n &.dg-loading {\r\n &:not(.dg-initialized) {\r\n\r\n thead,\r\n tfoot {\r\n background: none;\r\n }\r\n }\r\n\r\n tbody {\r\n animation-name: dataGridShow;\r\n animation-timing-function: ease-in;\r\n animation-fill-mode: forwards;\r\n animation-duration: 0.3s; // only triggers after 300ms\r\n pointer-events: none; // disable clicks while loading\r\n }\r\n\r\n &:not(:has(th)) {\r\n tfoot {\r\n display: none;\r\n }\r\n }\r\n }\r\n\r\n tr {\r\n position: relative;\r\n }\r\n\r\n th,\r\n td {\r\n empty-cells: show;\r\n padding: var(--padding-y) var(--padding-x);\r\n text-align: left;\r\n\r\n &[tabindex] {\r\n outline: none;\r\n word-break: normal;\r\n }\r\n }\r\n\r\n th {\r\n font-weight: bold;\r\n padding: var(--padding-y-header) var(--padding-x);\r\n }\r\n\r\n // Prevent overflow on headers and cells\r\n th,\r\n td {\r\n position: relative;\r\n overflow: hidden;\r\n text-align: left;\r\n // These two properties keep content on one line\r\n text-overflow: ellipsis;\r\n white-space: nowrap;\r\n\r\n // Use this to allow content to flow over multiple lines\r\n &.dg-wrap {\r\n white-space: normal;\r\n word-break: break-all;\r\n }\r\n }\r\n\r\n // Expand on multiple lines on row click\r\n .dg-expandable {\r\n cursor: pointer;\r\n\r\n &.dg-expanded td {\r\n white-space: normal;\r\n word-break: break-all;\r\n }\r\n }\r\n\r\n .dg-selectable {\n font-size: 1em;\r\n label {\r\n display: flex;\r\n align-items: center;\r\n margin:0;\r\n }\r\n }\r\n\r\n .dg-clickable-cell {\r\n margin: 0;\r\n position: absolute;\r\n top: 0;\r\n left: 0;\r\n width: 100%;\r\n height: 100%;\r\n cursor: pointer;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n }\r\n\r\n // Stick headers\r\n // https://css-tricks.com/making-tables-with-sticky-header-and-footers-got-a-bit-easier/\r\n &[sticky] table {\r\n\r\n thead,\r\n tfoot {\r\n z-index: 2;\r\n position: sticky;\r\n margin: 0;\r\n border: 0;\r\n }\r\n\r\n // Use silly value to prevent sub pixel alignment issue\r\n thead {\r\n inset-block-start: -1px;\r\n }\r\n\r\n tfoot {\r\n inset-block-end: -1px;\r\n }\r\n }\r\n\r\n // Pagination icons\r\n .dg-nav-icon,\r\n .dg-skip-icon {\r\n width: 22px;\r\n height: 22px;\r\n box-sizing: border-box;\r\n position: absolute;\r\n display: block;\r\n top: 50%;\r\n left: 50%;\r\n transform: translate(-50%, -50%) scale(var(--icon-scale, 1));\r\n\r\n &:before,\r\n &:after {\r\n content: \"\";\r\n display: block;\r\n box-sizing: border-box;\r\n position: absolute;\r\n }\r\n }\r\n\r\n .dg-nav-icon::before {\r\n width: 0;\r\n height: 10px;\r\n border-top: 5px solid transparent;\r\n border-bottom: 5px solid transparent;\r\n border-left: 6px solid;\r\n top: 6px;\r\n left: 9px;\r\n }\r\n\r\n .dg-skip-icon {\r\n &::before {\r\n width: 3px;\r\n height: 10px;\r\n background: currentColor;\r\n top: 6px;\r\n left: 14px;\r\n }\r\n\r\n &::after {\r\n width: 0;\r\n height: 10px;\r\n border-top: 5px solid transparent;\r\n border-bottom: 5px solid transparent;\r\n border-left: 6px solid;\r\n top: 6px;\r\n left: 7px;\r\n }\r\n }\r\n\r\n .dg-rotate {\r\n transform: rotate(-180deg);\r\n }\r\n\r\n // Default actions buttons\r\n button {\r\n background-color: var(--btn-background);\r\n border: solid 1px var(--btn-border-color);\r\n border-radius: var(--border-radius);\r\n color: var(--body-color);\r\n height: 2rem;\r\n margin: 0 0.2rem;\r\n padding: 0 0.5rem;\r\n pointer-events: all;\r\n text-align: center;\r\n cursor: pointer;\r\n\r\n &:hover {\r\n opacity: 0.7;\r\n }\r\n\r\n &:disabled:hover {\r\n background-color: inherit;\r\n border-color: inherit;\r\n }\r\n }\r\n\r\n // Form elements\r\n input[type=\"checkbox\"] {\r\n margin: 0;\r\n padding: 0;\r\n }\r\n\r\n input:not([type=\"checkbox\"],[type=\"radio\"]),\r\n select {\r\n background-color: var(--input-background, \"#fff\");\r\n color: currentColor;\r\n box-sizing: border-box;\r\n border: 1px solid var(--input-border-color, \"#f0f0f0\");\r\n border-radius: var(--border-radius);\r\n height: 2rem;\r\n margin: 0 0.2rem;\r\n padding: 0 var(--padding);\r\n max-width: none;\r\n }\r\n\r\n input:not([type=\"checkbox\"]),\r\n select,\r\n button {\r\n &:focus {\r\n box-shadow: 0 0 0 var(--padding-half) rgba(var(--color-rgb), 0.25);\r\n outline: 0;\r\n }\r\n\r\n &[disabled],\r\n &:disabled {\r\n opacity: 0.35;\r\n pointer-events: none;\r\n }\r\n }\r\n\r\n // Filters (2nd header row)\r\n thead tr:nth-child(2) th {\r\n padding: 0 2px 0 0;\r\n background-color: transparent;\r\n\r\n > * {\r\n width: 100%;\r\n border-radius: 0;\r\n margin: 0;\r\n }\r\n\r\n input {\r\n &:focus {\r\n box-shadow: inset 0px 0px 0px 1px var(--color);\r\n }\r\n }\r\n }\r\n\n tbody {\n // Editable\r\n td.dg-editable-col {\r\n padding: 0;\r\n height: 0; // it needs a height for height 100%\r\n }\n\n td input.dg-editable {\r\n width: 100%;\r\n background: transparent;\r\n border: 0;\r\n border-radius: 0;\r\n margin: 0;\r\n box-shadow: none;\r\n height: 100%;\r\n\r\n &:focus {\r\n box-shadow: inset 0px 0px 0px 1px var(--color);\r\n }\r\n }\n\n tr:has(.dg-selectable [type=radio]:checked) {\n background-color: var(--selected-bgcolor);\n }\r\n }\r\n\r\n // Empty table or error message (don't use :empty as it would create fouc on load)\r\n &.dg-empty {\r\n tbody {\r\n height: 4rem;\r\n position: relative;\r\n\r\n &:before {\r\n position: absolute;\r\n top: 50%;\r\n left: 50%;\r\n content: attr(data-empty);\r\n transform: translate(-50%, -50%);\r\n opacity: 0.5;\r\n font-size: 1.5rem;\r\n text-align: center;\r\n white-space: nowrap;\r\n text-overflow: ellipsis;\r\n overflow: hidden;\r\n width: 90%;\r\n }\r\n }\r\n\r\n tr {\r\n &.dg-fake-row {\r\n height: 4rem;\r\n border: none;\r\n }\r\n }\r\n\r\n &.dg-network-error {\r\n table {\r\n color: #842029;\r\n background-color: #f8d7da;\r\n border: 1px solid #f5c2c7;\r\n }\r\n\r\n tbody {\r\n height: auto;\r\n\r\n &:before {\r\n font-size: 1.2rem;\r\n }\r\n\r\n tr:not(.dg-fake-row) {\r\n display: none;\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Zebra/striped rows\r\n tbody tr {\r\n &:nth-child(even) {\r\n background-color: var(--striped-background);\r\n }\r\n\r\n border-bottom: solid 1px var(--row-border-color);\r\n\r\n &:hover {\r\n background-color: var(--highlight-color) !important;\r\n }\r\n\r\n &:focus {\r\n background-color: var(--highlight-color) !important;\r\n border-bottom-color: var(--highlight-color) !important;\r\n outline: none;\r\n }\r\n }\r\n\r\n // Meta footer\r\n tfoot {\r\n min-width: 280px;\r\n\r\n td {\r\n padding: var(--padding-y-header) var(--padding-x);\r\n }\r\n\r\n .dg-page-nav {\r\n display: flex;\r\n align-items: center;\r\n /*min-width: 160px;*/\r\n }\r\n\r\n .dg-input-page {\r\n width: 4rem;\r\n }\r\n\r\n .dg-footer {\r\n display: flex;\r\n align-items: center;\r\n flex-direction: row;\r\n justify-content: space-between;\r\n }\r\n\r\n .dg-pagination {\r\n display: flex;\r\n text-align: center;\r\n\r\n button {\r\n // Fix icon inside button\r\n position: relative;\r\n width: 2rem;\r\n }\r\n }\r\n\r\n .dg-meta {\r\n // Prevent layout from jumping around\r\n /*min-width: 160px;*/\r\n text-align: right;\r\n }\r\n\r\n &.dg-footer-compact {\r\n .dg-meta {\r\n display: none;\r\n }\r\n\r\n .dg-input-page {\r\n display: none;\r\n }\r\n }\r\n }\r\n\r\n // Pagination in header\r\n [aria-sort] {\r\n cursor: pointer;\r\n padding-right: 1.5rem;\r\n }\r\n\r\n [aria-sort=\"none\"]:after,\r\n [aria-sort=\"none\"]:before,\r\n [aria-sort=\"ascending\"]:before,\r\n [aria-sort=\"descending\"]:after {\r\n right: 0.5rem;\r\n top: calc(50% - 0.5rem);\r\n border: solid transparent;\r\n content: \" \";\r\n height: 0;\r\n width: 0;\r\n position: absolute;\r\n border-color: rgba(0, 0, 0, 0);\r\n border-width: 0.25rem;\r\n margin-left: -0.25rem;\r\n }\r\n\r\n [aria-sort=\"none\"] {\r\n &:before {\r\n border-bottom-color: currentColor;\r\n opacity: 0.25;\r\n top: calc(50% - 0.6rem);\r\n }\r\n\r\n &:after {\r\n border-top-color: currentColor;\r\n opacity: 0.25;\r\n bottom: calc(50% - 0.5rem);\r\n top: auto;\r\n }\r\n }\r\n\r\n [aria-sort=\"ascending\"]:before {\r\n border-bottom-color: var(--body-color);\r\n opacity: 0.75;\r\n }\r\n\r\n [aria-sort=\"descending\"]:after {\r\n border-top-color: var(--body-color);\r\n opacity: 0.75;\r\n bottom: calc(50% - 0.5rem);\r\n top: auto;\r\n }\r\n}\r\n\r\n[data-bs-theme=\"dark\"] data-grid {\r\n --scroller-color-lightness: 20%;\r\n --highlight-color: #43423e;\r\n --selected-bgcolor: var(--bs-primary-bg-subtle, #031633);\r\n --body-background: #212529;\r\n --striped-background: #2c3034;\r\n --header-background: var(--bs-gray-800, #34373b);\r\n --header-color: var(--bs-light, #e9ecef);\r\n --body-color: var(--bs-body-color, #494e53);\r\n --row-border-color: var(--bs-gray-900, #212325);\r\n}\r\n\r\n","/**\n * Data Grid Web Component v2.0.13\n * https://github.com/lekoala/data-grid\n */\n@keyframes dataGridShow {\n 0% {\n opacity: 1;\n }\n 100% {\n opacity: 0.5;\n }\n}\ndata-grid {\n --padding: 0.5rem;\n --padding-x: 0.75rem;\n --padding-y: 0.5rem;\n --padding-y-header: 0.75rem;\n --padding-half: calc(var(--padding) / 2);\n --color-rgb: var(--bs-primary-rgb, 13, 110, 253);\n --color: rgb(var(--color-rgb));\n --highlight-color: #fffcee;\n --selected-bgcolor: var(--bs-primary-bg-subtle, #cfe2ff);\n --body-background: var(--bs-table-bg, #fff);\n --striped-background: rgba(0, 0, 0, 0.05);\n --header-background: var(--bs-gray-200, #e9ecef);\n --header-color: var(--bs-dark, #212529);\n --input-background: var(--bs-body-bg, #ffffff);\n --input-border-color: var(--bs-border-color, #e9ecef);\n --btn-background: var(--bs-body-bg, #ffffff);\n --btn-color: var(--color);\n --btn-border-color: var(--bs-border-color, #e9ecef);\n --body-bg: var(--bs-body-bg, #212529);\n --body-color: var(--bs-body-color, #212529);\n --icon-scale: 1;\n --border-radius: 0.25rem;\n --row-border-color: #f2f2f2;\n --responsive-width: 60%;\n --black: var(--bs-black, #000);\n --white: var(--bs-white, #fff);\n --gray: var(--bs-gray, #6c757d);\n --gray-dark: var(--bs-gray-dark, #343a40);\n --gray-100: var(--bs-gray-100, #f8f9fa);\n --gray-200: var(--bs-gray-200, #e9ecef);\n --gray-300: var(--bs-gray-300, #dee2e6);\n --gray-400: var(--bs-gray-400, #ced4da);\n --gray-500: var(--bs-gray-500, #adb5bd);\n --gray-600: var(--bs-gray-600, #6c757d);\n --gray-700: var(--bs-gray-700, #495057);\n --gray-800: var(--bs-gray-800, #343a40);\n --gray-900: var(--bs-gray-900, #212529);\n display: block;\n min-height: 6rem;\n position: relative;\n}\ndata-grid {\n --scroller-color: 0, 0%;\n --scroller-color-lightness: 80%;\n --scroller-hover-factor: 0.8;\n --scroller-thumb: hsl(var(--scroller-color), var(--scroller-color-lightness));\n /* Replicate hover for webkit */\n --scroller-thumb-hover: hsl(var(--scroller-color), calc(var(--scroller-color-lightness) * var(--scroller-hover-factor)));\n --scroller-background: transparent;\n scrollbar-color: var(--scroller-thumb) var(--scroller-background);\n scrollbar-width: thin;\n}\ndata-grid::-webkit-scrollbar {\n width: 8px;\n height: 8px;\n}\ndata-grid::-webkit-scrollbar-track {\n background: transparent;\n}\ndata-grid::-webkit-scrollbar-thumb {\n background: var(--scroller-thumb);\n}\ndata-grid::-webkit-scrollbar-thumb:hover {\n background: var(--scroller-thumb-hover);\n}\ndata-grid > table[role=grid] tr.dg-head-columns:is(:empty, :has(> :first-child:not([scope=col]))) {\n display: none;\n}\ndata-grid img {\n border: none;\n height: auto;\n max-width: 100%;\n vertical-align: middle;\n}\ndata-grid [hidden] {\n display: none;\n}\ndata-grid table {\n display: table;\n table-layout: fixed;\n width: 100%;\n max-width: 100%;\n white-space: normal;\n background: var(--body-background);\n}\ndata-grid thead,\ndata-grid tfoot {\n background-color: var(--header-background);\n color: var(--header-color);\n}\ndata-grid.dg-loading:not(.dg-initialized) thead,\ndata-grid.dg-loading:not(.dg-initialized) tfoot {\n background: none;\n}\ndata-grid.dg-loading tbody {\n animation-name: dataGridShow;\n animation-timing-function: ease-in;\n animation-fill-mode: forwards;\n animation-duration: 0.3s;\n pointer-events: none;\n}\ndata-grid.dg-loading:not(:has(th)) tfoot {\n display: none;\n}\ndata-grid tr {\n position: relative;\n}\ndata-grid th,\ndata-grid td {\n empty-cells: show;\n padding: var(--padding-y) var(--padding-x);\n text-align: left;\n}\ndata-grid th[tabindex],\ndata-grid td[tabindex] {\n outline: none;\n word-break: normal;\n}\ndata-grid th {\n font-weight: bold;\n padding: var(--padding-y-header) var(--padding-x);\n}\ndata-grid th,\ndata-grid td {\n position: relative;\n overflow: hidden;\n text-align: left;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\ndata-grid th.dg-wrap,\ndata-grid td.dg-wrap {\n white-space: normal;\n word-break: break-all;\n}\ndata-grid .dg-expandable {\n cursor: pointer;\n}\ndata-grid .dg-expandable.dg-expanded td {\n white-space: normal;\n word-break: break-all;\n}\ndata-grid .dg-selectable {\n font-size: 1em;\n}\ndata-grid .dg-selectable label {\n display: flex;\n align-items: center;\n margin: 0;\n}\ndata-grid .dg-clickable-cell {\n margin: 0;\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n}\ndata-grid[sticky] table thead,\ndata-grid[sticky] table tfoot {\n z-index: 2;\n position: sticky;\n margin: 0;\n border: 0;\n}\ndata-grid[sticky] table thead {\n inset-block-start: -1px;\n}\ndata-grid[sticky] table tfoot {\n inset-block-end: -1px;\n}\ndata-grid .dg-nav-icon,\ndata-grid .dg-skip-icon {\n width: 22px;\n height: 22px;\n box-sizing: border-box;\n position: absolute;\n display: block;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%) scale(var(--icon-scale, 1));\n}\ndata-grid .dg-nav-icon:before, data-grid .dg-nav-icon:after,\ndata-grid .dg-skip-icon:before,\ndata-grid .dg-skip-icon:after {\n content: \"\";\n display: block;\n box-sizing: border-box;\n position: absolute;\n}\ndata-grid .dg-nav-icon::before {\n width: 0;\n height: 10px;\n border-top: 5px solid transparent;\n border-bottom: 5px solid transparent;\n border-left: 6px solid;\n top: 6px;\n left: 9px;\n}\ndata-grid .dg-skip-icon::before {\n width: 3px;\n height: 10px;\n background: currentColor;\n top: 6px;\n left: 14px;\n}\ndata-grid .dg-skip-icon::after {\n width: 0;\n height: 10px;\n border-top: 5px solid transparent;\n border-bottom: 5px solid transparent;\n border-left: 6px solid;\n top: 6px;\n left: 7px;\n}\ndata-grid .dg-rotate {\n transform: rotate(-180deg);\n}\ndata-grid button {\n background-color: var(--btn-background);\n border: solid 1px var(--btn-border-color);\n border-radius: var(--border-radius);\n color: var(--body-color);\n height: 2rem;\n margin: 0 0.2rem;\n padding: 0 0.5rem;\n pointer-events: all;\n text-align: center;\n cursor: pointer;\n}\ndata-grid button:hover {\n opacity: 0.7;\n}\ndata-grid button:disabled:hover {\n background-color: inherit;\n border-color: inherit;\n}\ndata-grid input[type=checkbox] {\n margin: 0;\n padding: 0;\n}\ndata-grid input:not([type=checkbox], [type=radio]),\ndata-grid select {\n background-color: var(--input-background, \"#fff\");\n color: currentColor;\n box-sizing: border-box;\n border: 1px solid var(--input-border-color, \"#f0f0f0\");\n border-radius: var(--border-radius);\n height: 2rem;\n margin: 0 0.2rem;\n padding: 0 var(--padding);\n max-width: none;\n}\ndata-grid input:not([type=checkbox]):focus,\ndata-grid select:focus,\ndata-grid button:focus {\n box-shadow: 0 0 0 var(--padding-half) rgba(var(--color-rgb), 0.25);\n outline: 0;\n}\ndata-grid input:not([type=checkbox])[disabled], data-grid input:not([type=checkbox]):disabled,\ndata-grid select[disabled],\ndata-grid select:disabled,\ndata-grid button[disabled],\ndata-grid button:disabled {\n opacity: 0.35;\n pointer-events: none;\n}\ndata-grid thead tr:nth-child(2) th {\n padding: 0 2px 0 0;\n background-color: transparent;\n}\ndata-grid thead tr:nth-child(2) th > * {\n width: 100%;\n border-radius: 0;\n margin: 0;\n}\ndata-grid thead tr:nth-child(2) th input:focus {\n box-shadow: inset 0px 0px 0px 1px var(--color);\n}\ndata-grid tbody td.dg-editable-col {\n padding: 0;\n height: 0;\n}\ndata-grid tbody td input.dg-editable {\n width: 100%;\n background: transparent;\n border: 0;\n border-radius: 0;\n margin: 0;\n box-shadow: none;\n height: 100%;\n}\ndata-grid tbody td input.dg-editable:focus {\n box-shadow: inset 0px 0px 0px 1px var(--color);\n}\ndata-grid tbody tr:has(.dg-selectable [type=radio]:checked) {\n background-color: var(--selected-bgcolor);\n}\ndata-grid.dg-empty tbody {\n height: 4rem;\n position: relative;\n}\ndata-grid.dg-empty tbody:before {\n position: absolute;\n top: 50%;\n left: 50%;\n content: attr(data-empty);\n transform: translate(-50%, -50%);\n opacity: 0.5;\n font-size: 1.5rem;\n text-align: center;\n white-space: nowrap;\n text-overflow: ellipsis;\n overflow: hidden;\n width: 90%;\n}\ndata-grid.dg-empty tr.dg-fake-row {\n height: 4rem;\n border: none;\n}\ndata-grid.dg-empty.dg-network-error table {\n color: #842029;\n background-color: #f8d7da;\n border: 1px solid #f5c2c7;\n}\ndata-grid.dg-empty.dg-network-error tbody {\n height: auto;\n}\ndata-grid.dg-empty.dg-network-error tbody:before {\n font-size: 1.2rem;\n}\ndata-grid.dg-empty.dg-network-error tbody tr:not(.dg-fake-row) {\n display: none;\n}\ndata-grid tbody tr {\n border-bottom: solid 1px var(--row-border-color);\n}\ndata-grid tbody tr:nth-child(even) {\n background-color: var(--striped-background);\n}\ndata-grid tbody tr:hover {\n background-color: var(--highlight-color) !important;\n}\ndata-grid tbody tr:focus {\n background-color: var(--highlight-color) !important;\n border-bottom-color: var(--highlight-color) !important;\n outline: none;\n}\ndata-grid tfoot {\n min-width: 280px;\n}\ndata-grid tfoot td {\n padding: var(--padding-y-header) var(--padding-x);\n}\ndata-grid tfoot .dg-page-nav {\n display: flex;\n align-items: center;\n /*min-width: 160px;*/\n}\ndata-grid tfoot .dg-input-page {\n width: 4rem;\n}\ndata-grid tfoot .dg-footer {\n display: flex;\n align-items: center;\n flex-direction: row;\n justify-content: space-between;\n}\ndata-grid tfoot .dg-pagination {\n display: flex;\n text-align: center;\n}\ndata-grid tfoot .dg-pagination button {\n position: relative;\n width: 2rem;\n}\ndata-grid tfoot .dg-meta {\n /*min-width: 160px;*/\n text-align: right;\n}\ndata-grid tfoot.dg-footer-compact .dg-meta {\n display: none;\n}\ndata-grid tfoot.dg-footer-compact .dg-input-page {\n display: none;\n}\ndata-grid [aria-sort] {\n cursor: pointer;\n padding-right: 1.5rem;\n}\ndata-grid [aria-sort=none]:after,\ndata-grid [aria-sort=none]:before,\ndata-grid [aria-sort=ascending]:before,\ndata-grid [aria-sort=descending]:after {\n right: 0.5rem;\n top: calc(50% - 0.5rem);\n border: solid transparent;\n content: \" \";\n height: 0;\n width: 0;\n position: absolute;\n border-color: rgba(0, 0, 0, 0);\n border-width: 0.25rem;\n margin-left: -0.25rem;\n}\ndata-grid [aria-sort=none]:before {\n border-bottom-color: currentColor;\n opacity: 0.25;\n top: calc(50% - 0.6rem);\n}\ndata-grid [aria-sort=none]:after {\n border-top-color: currentColor;\n opacity: 0.25;\n bottom: calc(50% - 0.5rem);\n top: auto;\n}\ndata-grid [aria-sort=ascending]:before {\n border-bottom-color: var(--body-color);\n opacity: 0.75;\n}\ndata-grid [aria-sort=descending]:after {\n border-top-color: var(--body-color);\n opacity: 0.75;\n bottom: calc(50% - 0.5rem);\n top: auto;\n}\n\n[data-bs-theme=dark] data-grid {\n --scroller-color-lightness: 20%;\n --highlight-color: #43423e;\n --selected-bgcolor: var(--bs-primary-bg-subtle, #031633);\n --body-background: #212529;\n --striped-background: #2c3034;\n --header-background: var(--bs-gray-800, #34373b);\n --header-color: var(--bs-light, #e9ecef);\n --body-color: var(--bs-body-color, #494e53);\n --row-border-color: var(--bs-gray-900, #212325);\n}\n\ndata-grid[dir=rtl] th,\ndata-grid[dir=rtl] td {\n text-align: right;\n}\ndata-grid[dir=rtl] [aria-sort] {\n padding-left: 1rem;\n padding-right: 0.5rem;\n}\ndata-grid[dir=rtl] [aria-sort=none]:after,\ndata-grid[dir=rtl] [aria-sort=none]:before,\ndata-grid[dir=rtl] [aria-sort=ascending]:before,\ndata-grid[dir=rtl] [aria-sort=descending]:after {\n left: 0.75rem;\n right: auto;\n}\ndata-grid[dir=rtl] tfoot .dg-meta {\n text-align: left;\n}\n\ndata-grid .dg-menu {\n position: absolute;\n z-index: 3;\n background: var(--body-bg);\n list-style: none;\n max-width: 150px;\n margin: 0;\n padding: var(--padding);\n box-shadow: 0 0 1rem rgba(0, 0, 0, 0.25);\n border-radius: var(--border-radius);\n}\ndata-grid .dg-menu li {\n margin: 0;\n padding: 0;\n}\ndata-grid .dg-menu label {\n display: flex;\n align-items: center;\n margin-bottom: 0.25em;\n}\ndata-grid .dg-menu input {\n margin-right: 0.5em;\n}\n\ndata-grid .dg-actions {\n text-overflow: initial;\n width: 100px;\n text-align: right;\n white-space: nowrap !important;\n}\ndata-grid .dg-actions button {\n margin: 0;\n}\ndata-grid .dg-actions button + button {\n margin-left: 0.25rem;\n}\ndata-grid .dg-actions .dg-actions-toggle {\n display: none;\n width: calc(100px - var(--padding-x) * 2);\n}\ndata-grid .dg-actions.dg-actions-1 {\n width: 100%;\n}\ndata-grid .dg-actions.dg-actions-2 button {\n width: calc(50% - 0.25rem);\n}\ndata-grid .dg-actions.dg-actions-more button {\n display: none;\n}\ndata-grid .dg-actions.dg-actions-more button.dg-actions-toggle {\n display: inline-block;\n}\ndata-grid .dg-actions.dg-actions-expand {\n position: absolute;\n right: 0;\n display: flex;\n align-items: center;\n justify-content: flex-end;\n width: 100%;\n height: 100%;\n}\ndata-grid .dg-actions.dg-actions-expand.dg-actions-more {\n width: 100%;\n}\ndata-grid .dg-actions.dg-actions-expand.dg-actions-more button {\n display: inline-block;\n}\ndata-grid tr.dg-actionable {\n cursor: pointer;\n}\ndata-grid tr.dg-actionable:hover td {\n background-color: var(--highlight-color);\n}\n\ndata-grid .dg-resizer {\n position: absolute;\n top: 0;\n right: 0;\n width: 6px;\n z-index: 2;\n cursor: col-resize;\n user-select: none;\n}\ndata-grid .dg-resizer:before {\n content: \"\";\n display: block;\n position: absolute;\n top: var(--padding-y-header);\n height: 1.5rem;\n right: 0;\n width: 2px;\n background: var(--body-color);\n opacity: 0.2;\n}\ndata-grid .dg-resizer:hover:before {\n opacity: 0.6;\n}\ndata-grid .dg-resizer.dg-resizer-active {\n border-right: 1px dashed var(--color);\n}\ndata-grid .dg-resizer.dg-resizer-active:before {\n opacity: 0.6;\n}\n\ndata-grid .dg-responsive-toggle {\n padding: 0;\n text-align: center;\n}\ndata-grid .dg-responsive-child-row > td {\n padding: 0;\n}\ndata-grid .dg-responsive-table {\n table-layout: auto;\n border: 0;\n}\ndata-grid .dg-responsive-table td,\ndata-grid .dg-responsive-table th {\n white-space: normal;\n}\ndata-grid .dg-responsive-table th {\n max-width: 40%;\n}\n\n@media only screen and (max-width: 767px) {\n data-grid[responsive] .dg-resizer {\n display: none;\n }\n data-grid[responsive] .dg-meta {\n display: none;\n }\n data-grid[responsive] .dg-input-page {\n display: none;\n }\n data-grid[responsive] table,\n data-grid[responsive] tbody,\n data-grid[responsive] tfoot,\n data-grid[responsive] th,\n data-grid[responsive] td,\n data-grid[responsive] tr:not([hidden]) {\n display: block;\n }\n data-grid[responsive] thead {\n display: flex;\n border-bottom: 2px solid var(--header-background);\n }\n data-grid[responsive] thead > tr {\n flex-grow: 1;\n }\n data-grid[responsive] thead th {\n width: auto;\n }\n data-grid[responsive] tbody tr {\n padding: 0;\n border: 1px solid var(--header-background);\n }\n data-grid[responsive] tbody td {\n border: none;\n border-bottom: 1px solid var(--row-border-color);\n position: relative;\n padding-left: calc(100% - var(--responsive-width) - var(--padding) * 2);\n }\n data-grid[responsive] tbody td:last-child {\n border: 0;\n }\n data-grid[responsive] tbody td:before {\n position: absolute;\n top: 0;\n left: 0;\n padding: var(--padding);\n width: calc(100% - var(--responsive-width) - var(--padding) * 4);\n content: attr(data-name);\n display: block;\n font-weight: bold;\n background-color: var(--header-background);\n }\n data-grid[responsive] tbody td[role=gridcell] {\n padding-left: calc(100% - var(--responsive-width) - var(--padding) * 4 + 0.5rem);\n }\n data-grid[responsive] .dg-selectable {\n height: 28px;\n margin: 2px 1px 2px;\n }\n data-grid[responsive] td.dg-selectable::before, data-grid[responsive] td.dg-actions::before {\n padding: 0;\n }\n data-grid[responsive] td.dg-selectable label {\n padding: 5px;\n }\n data-grid[responsive] td[role=gridcell] {\n min-height: 35px;\n width: auto;\n }\n data-grid[responsive] td[data-name]::before {\n height: 100%;\n }\n data-grid[responsive] td.dg-actions {\n padding-left: inherit;\n width: inherit;\n }\n data-grid[responsive] .dg-actions button {\n width: inherit !important;\n }\n data-grid[responsive] tr.dg-head-columns {\n padding: 0;\n width: calc(100% - var(--responsive-width) - var(--padding) * 4);\n }\n data-grid[responsive] tr.dg-head-columns th[role=\"columnheader button\"] {\n padding: 0.36em 1.3em 0.36em 0.75em;\n }\n data-grid[responsive] tr.dg-head-filters {\n background: transparent;\n vertical-align: top;\n padding: 0;\n width: calc(100% - (100% - var(--responsive-width) - var(--padding) * 4));\n }\n data-grid[responsive] .dg-head-filters th input:not([type=checkbox], [type=radio]) {\n height: 2.25em;\n }\n data-grid[responsive] .dg-head-filters th.dg-selectable {\n background: transparent;\n }\n data-grid[responsive] .dg-head-filters th.dg-selectable label::before {\n content: \"Column Filters\";\n }\n data-grid[responsive] tfoot .dg-page-nav {\n min-width: revert;\n }\n data-grid[data-responsive=true] tfoot .dg-page-nav {\n min-width: revert;\n }\n}\n\n/*# sourceMappingURL=data-grid.css.map */\n","data-grid {\r\n &[dir=\"rtl\"] {\r\n th,\r\n td {\r\n text-align: right;\r\n }\r\n [aria-sort] {\r\n padding-left: 1rem;\r\n padding-right: 0.5rem;\r\n }\r\n [aria-sort=\"none\"]:after,\r\n [aria-sort=\"none\"]:before,\r\n [aria-sort=\"ascending\"]:before,\r\n [aria-sort=\"descending\"]:after {\r\n left: 0.75rem;\r\n right: auto;\r\n }\r\n tfoot .dg-meta {\r\n text-align: left;\r\n }\r\n }\r\n}\r\n","data-grid {\r\n .dg-menu {\r\n position: absolute;\r\n z-index: 3;\r\n background: var(--body-bg);\r\n list-style: none;\r\n max-width: 150px;\r\n margin: 0;\r\n padding: var(--padding);\r\n box-shadow: 0 0 1rem rgba(0, 0, 0, 0.25);\r\n border-radius: var(--border-radius);\r\n\r\n li {\r\n margin: 0;\r\n padding: 0;\r\n }\r\n label {\r\n display: flex;\r\n align-items: center;\r\n margin-bottom: 0.25em;\r\n }\r\n input {\r\n margin-right: 0.5em;\r\n }\r\n }\r\n}\r\n","data-grid {\r\n .dg-actions {\r\n text-overflow: initial;\r\n width: 100px;\r\n text-align: right;\r\n white-space: nowrap !important;\r\n\r\n button {\r\n margin: 0;\r\n\r\n + button {\r\n margin-left: 0.25rem;\r\n }\r\n }\r\n .dg-actions-toggle {\r\n display: none;\r\n width: calc(100px - var(--padding-x) * 2);\r\n }\r\n &.dg-actions-1 {\r\n width: 100%;\r\n }\r\n // This needs icons to work\r\n &.dg-actions-2 button {\r\n width: calc(50% - 0.25rem);\r\n }\r\n &.dg-actions-more button {\r\n display: none;\r\n\r\n &.dg-actions-toggle {\r\n display: inline-block;\r\n }\r\n }\r\n &.dg-actions-expand {\r\n position: absolute;\r\n right: 0;\r\n display: flex;\r\n align-items: center;\r\n justify-content: flex-end;\r\n width: 100%;\r\n height: 100%;\r\n }\r\n &.dg-actions-expand.dg-actions-more {\r\n width: 100%;\r\n\r\n button {\r\n display: inline-block;\r\n }\r\n }\r\n }\r\n tr.dg-actionable {\r\n cursor: pointer;\r\n\r\n &:hover td {\r\n background-color: var(--highlight-color);\r\n }\r\n }\r\n}\r\n","data-grid {\r\n .dg-resizer {\r\n position: absolute;\r\n top: 0;\r\n right: 0;\r\n width: 6px; // clickable zone\r\n z-index: 2;\r\n cursor: col-resize;\r\n user-select: none;\r\n\r\n &:before {\r\n content: \"\";\r\n display: block;\r\n position: absolute;\r\n top: var(--padding-y-header);\r\n height: 1.5rem;\r\n right: 0;\r\n width: 2px;\r\n background: var(--body-color);\r\n opacity: 0.2;\r\n }\r\n &:hover:before {\r\n opacity: 0.6;\r\n }\r\n &.dg-resizer-active {\r\n border-right: 1px dashed var(--color);\r\n\r\n &:before {\r\n opacity: 0.6;\r\n }\r\n }\r\n }\r\n}\r\n","data-grid {\r\n .dg-responsive-toggle {\r\n padding: 0;\r\n text-align: center;\r\n }\r\n .dg-responsive-child-row > td {\r\n padding: 0;\r\n }\r\n .dg-responsive-table {\r\n table-layout: auto;\r\n border: 0;\r\n\r\n td,\r\n th {\r\n white-space: normal;\r\n }\r\n\r\n th {\r\n max-width: 40%;\r\n }\r\n }\r\n}\r\n\r\n// CSS Only responsive\r\n@media only screen and (max-width: 767px) {\r\n data-grid[responsive] {\r\n // Doesn't make any sense to resize\r\n .dg-resizer {\r\n display: none;\r\n }\r\n\r\n // more compact footer\r\n .dg-meta {\r\n display: none;\r\n }\r\n .dg-input-page {\r\n display: none;\r\n }\r\n\r\n // everything as blocks\r\n table,\r\n tbody,\r\n tfoot,\r\n th,\r\n td,\r\n tr:not([hidden]) {\r\n display: block;\r\n }\r\n\r\n // use flex for thead\r\n thead {\r\n display: flex;\r\n\r\n > tr {\r\n flex-grow: 1;\r\n }\r\n th {\r\n width: auto;\r\n }\r\n\r\n border-bottom: 2px solid var(--header-background);\r\n }\r\n\r\n // use pseudo element to display column name\r\n tbody {\r\n tr {\r\n padding: 0;\r\n border: 1px solid var(--header-background);\r\n }\r\n td {\r\n border: none;\r\n border-bottom: 1px solid var(--row-border-color);\r\n position: relative;\r\n padding-left: calc(100% - var(--responsive-width) - var(--padding) * 2);\r\n\r\n &:last-child {\r\n border: 0;\r\n }\r\n &:before {\r\n position: absolute;\r\n top: 0;\r\n left: 0;\r\n padding: var(--padding);\r\n width: calc(100% - var(--responsive-width) - var(--padding) * 4);\r\n content: attr(data-name);\r\n display: block;\r\n font-weight: bold;\r\n background-color: var(--header-background);\r\n }\r\n &[role=\"gridcell\"] {\r\n padding-left: calc(100% - var(--responsive-width) - var(--padding) * 4 + 0.5rem);\r\n }\r\n }\r\n }\r\n\r\n // give selectable some room\r\n .dg-selectable {\r\n height: 28px;\r\n margin: 2px 1px 2px;\r\n }\r\n\r\n td {\r\n &.dg-selectable::before,\r\n &.dg-actions::before {\r\n padding: 0;\r\n }\r\n &.dg-selectable label {\r\n padding: 5px;\r\n }\r\n &[role=\"gridcell\"] {\r\n min-height: 35px;\r\n width: auto;\r\n }\r\n &[data-name]::before {\r\n height: 100%;\r\n }\r\n &.dg-actions {\r\n padding-left: inherit;\r\n width: inherit;\r\n }\r\n }\r\n .dg-actions button {\r\n width: inherit !important;\r\n }\r\n tr {\r\n &.dg-head-columns {\r\n padding: 0;\r\n width: calc(100% - var(--responsive-width) - var(--padding) * 4);\r\n\r\n th[role=\"columnheader button\"] {\r\n padding: 0.36em 1.3em 0.36em 0.75em;\r\n }\r\n }\r\n &.dg-head-filters {\r\n background: transparent;\r\n vertical-align: top;\r\n padding: 0;\r\n width: calc(100% - (100% - var(--responsive-width) - var(--padding) * 4));\r\n }\r\n }\r\n .dg-head-filters th input:not([type=\"checkbox\"], [type=\"radio\"]) {\r\n height: 2.25em;\r\n }\r\n .dg-head-filters th.dg-selectable {\r\n background: transparent;\r\n }\r\n .dg-head-filters th.dg-selectable label::before {\r\n content: \"Column Filters\";\r\n }\r\n\r\n tfoot .dg-page-nav {\r\n min-width: revert;\r\n }\r\n }\r\n\r\n data-grid[data-responsive=true] {\r\n tfoot .dg-page-nav {\r\n min-width: revert;\r\n } \r\n }\r\n}\r\n"]}
\ No newline at end of file
diff --git a/dist/data-grid.js b/dist/data-grid.js
index d11fec9..5fee78b 100644
--- a/dist/data-grid.js
+++ b/dist/data-grid.js
@@ -1,4 +1,4 @@
-/*** Data Grid Web Component v2.0.12 * https://github.com/lekoala/data-grid ***/
+/*** Data Grid Web Component v2.0.13 * https://github.com/lekoala/data-grid ***/
// src/utils/camelize.js
function camelize(str) {
@@ -19,7 +19,7 @@ function normalizeData(v) {
if (v === Number(v).toString()) {
return Number(v);
}
- if (v && ["[", "{"].includes(v.substring(0, 1))) {
+ if (v && typeof v.substring === "function" && ["[", "{"].includes(v.substring(0, 1))) {
try {
let val = v;
if (val.indexOf('"') === -1) {
@@ -168,7 +168,7 @@ var BaseElement = class extends HTMLElement {
const jsonConfig = this.dataset.config ? JSON.parse(this.dataset.config) : {};
const data = { ...this.dataset };
for (const key in data) {
- if (key === "config") {
+ if (key === "config" || !data.hasOwnProperty(key) || typeof data[key] === "function") {
continue;
}
data[key] = normalizeData(data[key]);
@@ -215,12 +215,12 @@ var BaseElement = class extends HTMLElement {
return;
}
this.setup = true;
- setTimeout(() => {
+ setTimeout(async () => {
this.log("connectedCallback");
const template = document.createElement("template");
template.innerHTML = this.constructor.template();
this.appendChild(template.content.cloneNode(true));
- this._connected();
+ await this._connected();
dispatch(this, "connected");
}, 0);
}
@@ -409,6 +409,7 @@ function applyColumnDefinition(el, column) {
}
var DataGrid = class _DataGrid extends base_element_default {
_filterSelector = "[id^=dg-filter]";
+ _excludedRowElementSelector = "a,button,input,select,textarea";
_excludedKeys = [
37,
39,
@@ -453,6 +454,7 @@ var DataGrid = class _DataGrid extends base_element_default {
this.data = [];
this.originalData;
this.options = this.options || this.defaultOptions;
+ if (this.options.singleSelect) this.options.selectable = true;
this.fireEvents = false;
this.page = this.options.defaultPage || 1;
this.pages = 0;
@@ -526,6 +528,18 @@ var DataGrid = class _DataGrid extends base_element_default {
static setLabels(v) {
labels = Object.assign(labels, v);
}
+ /** Gets the text to be displayed when no data is loaded. */
+ get noData() {
+ return this.options.noData || this.labels.noData;
+ }
+ /**
+ * @param {HTMLTableSectionElement} tbody
+ */
+ #setNoData(tbody) {
+ if (!this.hasDataError && tbody.getAttribute("data-empty") !== this.noData) {
+ tbody.setAttribute("data-empty", this.noData);
+ }
+ }
/**
* @returns {Column}
*/
@@ -553,7 +567,7 @@ var DataGrid = class _DataGrid extends base_element_default {
get defaultOptions() {
return {
id: null,
- url: null,
+ url: "",
perPage: 10,
debug: false,
filter: false,
@@ -583,6 +597,7 @@ var DataGrid = class _DataGrid extends base_element_default {
collapseActions: false,
selectable: false,
selectVisibleOnly: true,
+ singleSelect: false,
defaultPage: 1,
resizable: false,
autosize: true,
@@ -595,7 +610,8 @@ var DataGrid = class _DataGrid extends base_element_default {
filterKeypressDelay: 500,
spinnerClass: "",
saveState: false,
- errorMessage: ""
+ errorMessage: "",
+ noData: ""
};
}
/**
@@ -682,6 +698,7 @@ var DataGrid = class _DataGrid extends base_element_default {
"data-reorder",
"data-menu",
"data-selectable",
+ "data-single-select",
"data-url",
"data-per-page",
"data-responsive"
@@ -718,11 +735,9 @@ var DataGrid = class _DataGrid extends base_element_default {
* @param {Boolean} initOnly
*/
urlChanged(initOnly = false) {
- if (initOnly && !this.isInit) return;
+ if (initOnly && !this.isInit) return this;
this.reconfig();
- this.loadData().then(() => {
- this.configureUi();
- });
+ return this.loadData().then(() => this.configureUi());
}
/**
* Clears columns, re-renders table, and repopulates columns to ensure consistent column widths rendering.
@@ -731,7 +746,7 @@ var DataGrid = class _DataGrid extends base_element_default {
const cols = this.options.columns;
this.options.columns = [];
this.configureUi();
- this.options.columns = cols;
+ return this.options.columns = cols, this;
}
constrainPageValue(v) {
let pv = v;
@@ -744,11 +759,12 @@ var DataGrid = class _DataGrid extends base_element_default {
return pv;
}
fixPage() {
+ if (!this.inputPage) return this;
this.pages = this.totalPages();
this.page = this.constrainPageValue(this.page);
setAttribute(this.inputPage, "max", this.pages);
this.inputPage.value = `${this.page}`;
- this.inputPage.disabled = this.pages < 2;
+ return this.inputPage.disabled = this.pages < 2, this;
}
pageChanged() {
this.reload();
@@ -814,7 +830,7 @@ var DataGrid = class _DataGrid extends base_element_default {
addSelectOption(this.selectPerPage, v, v, v === this.options.perPage);
}
}
- _connected() {
+ async _connected() {
this.table = this.querySelector("table");
this.btnFirst = this.querySelector(".dg-btn-first");
this.btnPrev = this.querySelector(".dg-btn-prev");
@@ -836,24 +852,11 @@ var DataGrid = class _DataGrid extends base_element_default {
this.selectPerPage.toggleAttribute("hidden", this.options.hidePerPage);
this.inputPage.addEventListener("input", this.gotoPage);
for (const plugin of Object.values(this.plugins)) {
- plugin.connected();
+ await plugin.connected();
}
this.dirChanged();
this.perPageValuesChanged();
- setTimeout(() => {
- this.loadData().finally(() => {
- this.configureUi();
- this.sortChanged();
- this.classList.add("dg-initialized");
- this.filterChanged();
- this.reorderChanged();
- this.dirChanged();
- this.perPageValuesChanged();
- this.pageChanged();
- this.fireEvents = true;
- this.log("initialized");
- });
- }, 0);
+ await this.init();
}
_disconnected() {
this.btnFirst?.removeEventListener("click", this.getFirst);
@@ -866,6 +869,20 @@ var DataGrid = class _DataGrid extends base_element_default {
plugin.disconnected();
}
}
+ init() {
+ return this.loadData().finally(() => {
+ this.configureUi();
+ this.sortChanged();
+ this.classList.add("dg-initialized");
+ this.filterChanged();
+ this.reorderChanged();
+ this.dirChanged();
+ this.perPageValuesChanged();
+ this.pageChanged();
+ this.fireEvents = true;
+ this.log("initialized");
+ });
+ }
/**
* @param {string} field
* @returns {Column}
@@ -965,6 +982,7 @@ var DataGrid = class _DataGrid extends base_element_default {
* This should be called after your data has been loaded
*/
configureUi() {
+ if (!this.table) return this;
this.table.style.visibility = "hidden";
this.renderTable();
if (this.options.responsive && this.plugins.ResponsiveGrid) {
@@ -977,7 +995,8 @@ var DataGrid = class _DataGrid extends base_element_default {
this.rowHeight = tr.offsetHeight;
}
}
- this.fixPage();
+ this.#setNoData(this.tbody);
+ return this.fixPage();
}
filterChanged() {
const row = this.querySelector("thead tr.dg-head-filters");
@@ -1055,22 +1074,29 @@ var DataGrid = class _DataGrid extends base_element_default {
this.sortData();
}
/**
- * @param {String} key Return a specific key (eg: id) instead of the whole row
- * @returns {Array}
+ * Get selected rows or specific fields from selected rows.
+ * If no keys are provided, returns the full row objects.
+ * If one key is provided, returns an array of values for that key.
+ * If multiple keys are provided, returns an array of objects with those keys and values.
+ * In single select mode, returns a single object or value.
+ * @param {...String} keys - Field names to select from each row.
+ * @returns {Array|Object} Selected rows, values, or objects depending on selection and keys.
*/
- getSelection(key = null) {
+ getSelection(...keys) {
if (!this.plugins.SelectableRows) {
return [];
}
- return this.plugins.SelectableRows.getSelection(key);
+ return this.plugins.SelectableRows.getSelection(...keys);
}
getData() {
return this.originalData;
}
- clearData() {
- if (this.data.length === 0) {
+ clearData(force = false) {
+ if (!force && this.data.length === 0) {
return;
}
+ this.classList.remove("dg-empty", "dg-network-error");
+ this.tbody?.setAttribute("data-empty", this.noData);
this.data = this.originalData = [];
this.renderBody();
}
@@ -1089,21 +1115,34 @@ var DataGrid = class _DataGrid extends base_element_default {
this.data = this.originalData = data[dataKey];
}
}
- refresh(cb = null) {
+ /**
+ * Clears and reloads data from url.
+ * @param {Function|String} callbackOrUrl
+ * @returns {DataGrid}
+ */
+ refresh(callbackOrUrl = null) {
this.data = this.originalData = [];
- return this.reload(cb);
+ return this.reload(callbackOrUrl);
}
- reload(cb = null) {
+ /**
+ * Reloads data from url.
+ * @param {Function|String} callbackOrUrl
+ * @returns {DataGrid}
+ */
+ reload(callbackOrUrl = null) {
this.log("reload");
+ if (typeof callbackOrUrl === "string") {
+ this.options.url = callbackOrUrl;
+ }
const needRender = !this.originalData?.length;
this.fixPage();
- this.loadData().finally(() => {
+ return this.loadData().finally(() => {
if (this.hasDataError) return;
this.options.server || needRender ? this.renderBody() : this.paginate();
- if (cb) {
- cb();
+ if (typeof callbackOrUrl === "function") {
+ callbackOrUrl();
}
- });
+ }).then(() => this);
}
/**
* @returns {Promise}
@@ -1160,9 +1199,7 @@ var DataGrid = class _DataGrid extends base_element_default {
dispatch(this, "loadDataFailed", err);
}).finally(() => {
flagEmpty();
- if (!this.hasDataError && tbody.getAttribute("data-empty") !== this.labels.noData) {
- tbody.setAttribute("data-empty", this.labels.noData);
- }
+ this.#setNoData(tbody);
this.classList.remove("dg-loading");
setAttribute(this.table, "aria-rowcount", this.data.length);
this.loading = false;
@@ -1282,7 +1319,7 @@ var DataGrid = class _DataGrid extends base_element_default {
const haveClasses = (c) => ["dg-selectable", "dg-actions", "dg-responsive-toggle"].includes(c);
const headers = findAll(this, "thead tr:first-child th");
for (const th of headers) {
- if ([...th.classList].some(haveClasses)) {
+ if ([...th.classList].some(haveClasses) || !th.hasAttribute("aria-sort")) {
continue;
}
if (th !== col) {
@@ -1422,6 +1459,7 @@ var DataGrid = class _DataGrid extends base_element_default {
renderFooter() {
this.log("render footer");
const tfoot = this.tfoot;
+ if (!tfoot) return;
const td = tfoot.querySelector("td");
tfoot.removeAttribute("hidden");
setAttribute(td, "colspan", this.columnsLength(true));
@@ -1441,11 +1479,11 @@ var DataGrid = class _DataGrid extends base_element_default {
tr.setAttribute("role", "row");
tr.setAttribute("aria-rowindex", "1");
tr.setAttribute("class", "dg-head-columns");
- let sampleTh = thead.querySelector("tr.dg-head-columns th");
+ let sampleTh = thead?.querySelector("tr.dg-head-columns th");
this.log("createColumnHeaders - sampleTh", sampleTh);
if (!sampleTh) {
sampleTh = ce("th");
- thead.querySelector("tr").appendChild(sampleTh);
+ thead?.querySelector("tr").appendChild(sampleTh);
}
if (this.options.selectable && this.plugins.SelectableRows) {
this.plugins.SelectableRows.createHeaderCol(tr);
@@ -1512,8 +1550,8 @@ var DataGrid = class _DataGrid extends base_element_default {
if (this.options.actions.length && this.plugins.RowActions) {
this.plugins.RowActions.makeActionHeader(tr);
}
- thead.replaceChild(tr, thead.querySelector("tr.dg-head-columns"));
- if (thead.offsetWidth > availableWidth) {
+ thead?.replaceChild(tr, thead.querySelector("tr.dg-head-columns"));
+ if (thead && thead.offsetWidth > availableWidth) {
this.log(`adjust width to fix size, ${thead.offsetWidth} > ${availableWidth}`);
const scrollbarWidth = this.offsetWidth - this.clientWidth;
let diff = thead.offsetWidth - availableWidth - scrollbarWidth;
@@ -1547,7 +1585,7 @@ var DataGrid = class _DataGrid extends base_element_default {
for (const sortableRow of rowsWithSort) {
sortableRow.addEventListener("click", () => this.sortData(sortableRow));
}
- setAttribute(this.table, "aria-colcount", this.columnsLength(true));
+ this.table && setAttribute(this.table, "aria-colcount", this.columnsLength(true));
}
createColumnFilters(thead) {
let idx = 0;
@@ -1572,7 +1610,7 @@ var DataGrid = class _DataGrid extends base_element_default {
continue;
}
const colIdx = idx + this.startColIndex();
- const relatedTh = thead.querySelector(`tr.dg-head-columns th[aria-colindex="${colIdx}"]`);
+ const relatedTh = thead?.querySelector(`tr.dg-head-columns th[aria-colindex="${colIdx}"]`);
if (!relatedTh) {
console.warn("Related th not found", colIdx);
continue;
@@ -1595,7 +1633,7 @@ var DataGrid = class _DataGrid extends base_element_default {
if (this.options.actions.length && this.plugins.RowActions) {
this.plugins.RowActions.makeActionFilter(tr);
}
- thead.replaceChild(tr, thead.querySelector("tr.dg-head-filters"));
+ thead?.replaceChild(tr, thead.querySelector("tr.dg-head-filters"));
if (typeof this.options.filterKeypressDelay !== "number" || this.options.filterOnEnter)
this.options.filterKeypressDelay = 0;
const filteredRows = findAll(tr, this._filterSelector);
@@ -1665,6 +1703,7 @@ var DataGrid = class _DataGrid extends base_element_default {
if (this.options.expand) {
tr.classList.add("dg-expandable");
on(tr, "click", (ev) => {
+ if (ev.target.matches(this._excludedRowElementSelector)) return;
if (this.plugins.ResponsiveGrid) {
this.plugins.ResponsiveGrid.blockObserver();
}
@@ -1747,8 +1786,8 @@ var DataGrid = class _DataGrid extends base_element_default {
});
tbody.setAttribute("role", "rowgroup");
const prev = this.tbody;
- tbody.setAttribute("data-empty", prev.getAttribute("data-empty"));
- this.table.replaceChild(tbody, prev);
+ prev && tbody.setAttribute("data-empty", prev.getAttribute("data-empty"));
+ this.table?.replaceChild(tbody, prev);
if (this.plugins.FixedHeight) {
this.plugins.FixedHeight.createFakeRow();
}
@@ -1756,7 +1795,7 @@ var DataGrid = class _DataGrid extends base_element_default {
if (this.plugins.SelectableRows) {
this.plugins.SelectableRows.shouldSelectAll(tbody);
}
- this.data.length && this.classList.remove("dg-empty");
+ this.classList.toggle("dg-empty", !this.data.length);
dispatch(this, "bodyRendered");
}
paginate() {
@@ -1765,6 +1804,7 @@ var DataGrid = class _DataGrid extends base_element_default {
const p = this.page || 1;
const tbody = this.tbody;
const tfoot = this.tfoot;
+ if (!tbody || !tfoot) return;
const bodyRows = findAll(tbody, "tr");
this.pages = this.totalPages();
let index;
@@ -2140,32 +2180,46 @@ var SELECTABLE_CLASS = "dg-selectable";
var SELECT_ALL_CLASS = "dg-select-all";
var CHECKBOX_CLASS = "form-check-input";
var SelectableRows = class extends base_plugin_default {
+ #cbSelector = `tbody tr${this.visibleOnly ? ":not([hidden])" : ""} .${SELECTABLE_CLASS} input[type=checkbox]`;
+ #inputSelector = `tbody .${SELECTABLE_CLASS} input`;
disconnected() {
if (this.selectAll) {
this.selectAll.removeEventListener("change", this);
}
}
+ get isSingleSelect() {
+ return this.grid.options.singleSelect;
+ }
+ get visibleOnly() {
+ return this.grid.options.selectVisibleOnly;
+ }
/**
- * @param {String} key Return a specific key (eg: id) instead of the whole row
- * @returns {Array}
+ * Get selected rows or fields.
+ * Returns full rows, a single field's values, or objects with specified fields.
+ * In single select mode, returns a single item.
+ * @param {...string} keys Field names to select.
+ * @returns {Array|Object} Selected data.
*/
- getSelection(key = null) {
+ getSelection(...keys) {
const grid = this.grid;
const selectedData = [];
- const inputs = findAll(grid, `tbody .${SELECTABLE_CLASS} input:checked`);
+ const inputs = findAll(grid, `${this.#inputSelector}:checked`);
for (const checkbox of inputs) {
const idx = Number.parseInt(checkbox.dataset.id);
const item = grid.data[idx - 1];
if (!item) {
console.warn(`Item ${idx} not found`);
+ continue;
}
- if (key) {
- selectedData.push(item[key]);
- } else {
+ if (keys.length === 0) {
selectedData.push(item);
+ } else if (keys.length === 1) {
+ selectedData.push(item[keys[0]]);
+ } else {
+ selectedData.push(Object.fromEntries(keys.map((k) => [k, item[k]])));
}
}
- return selectedData;
+ return this.isSingleSelect ? selectedData[0] ?? {} : selectedData;
}
/**
* Uncheck box if hidden and visible only
@@ -2179,6 +2233,9 @@ var SelectableRows = class extends base_plugin_default {
const inputs = findAll(tbody, `tr[hidden] .${SELECTABLE_CLASS} input`);
for (const input of inputs) {
input.checked = false;
+ if (this.isSingleSelect) {
+ input.dataset.toggled = "false";
+ }
}
this.selectAll.checked = false;
}
@@ -2201,6 +2258,7 @@ var SelectableRows = class extends base_plugin_default {
this.selectAll.classList.add(CHECKBOX_CLASS);
this.selectAll.addEventListener("change", this);
const label = document.createElement("label");
+ label.hidden = this.isSingleSelect;
label.appendChild(this.selectAll);
th.appendChild(label);
th.setAttribute("width", "40");
@@ -2238,13 +2296,17 @@ var SelectableRows = class extends base_plugin_default {
setAttribute(td, "role", "gridcell button");
setAttribute(td, "aria-colindex", this.colIndex());
td.classList.add(SELECTABLE_CLASS);
- const selectOne = document.createElement("input");
- selectOne.dataset.id = tr.getAttribute("aria-rowindex");
- selectOne.type = "checkbox";
- selectOne.classList.add(CHECKBOX_CLASS);
+ const input = document.createElement("input");
+ input.dataset.id = tr.getAttribute("aria-rowindex");
+ input.type = this.isSingleSelect ? "radio" : "checkbox";
+ input.classList.add(CHECKBOX_CLASS);
+ if (this.isSingleSelect) {
+ input.name = "dg-row-select";
+ input.dataset.toggled = "false";
+ }
const label = document.createElement("label");
label.classList.add("dg-clickable-cell");
- label.appendChild(selectOne);
+ label.appendChild(input);
td.appendChild(label);
label.addEventListener("click", this);
tr.appendChild(td);
@@ -2253,36 +2315,33 @@ var SelectableRows = class extends base_plugin_default {
* @param {Event} e
*/
onclick(e) {
- e.stopPropagation();
+ if (!this.isSingleSelect) return e.stopPropagation();
+ const el = e.target, unchecked = el.dataset.toggled !== "true";
+ unchecked && $$(`${this.#cbSelector.replace("checkbox", "radio")}`, this.grid)?.forEach((r) => {
+ if (r.name === el.name && r !== el) r.checked = r.dataset.toggled = false;
+ });
+ el.checked = el.dataset.toggled = unchecked;
+ !unchecked && this.onchange(e);
}
/**
* Handle change event on select all or any select checkbox in the table body
* @param {import("../utils/shortcuts.js").FlexibleEvent} e
*/
onchange(e) {
- const grid = this.grid;
+ const el = e.target, grid = this.grid;
if (hasClass(e.target, SELECT_ALL_CLASS)) {
- const visibleOnly = grid.options.selectVisibleOnly;
- const inputs = findAll(grid, `tbody .${SELECTABLE_CLASS} input`);
- for (const cb of inputs) {
- if (visibleOnly && !cb.offsetWidth) {
- return;
- }
- cb.checked = this.selectAll.checked;
- }
- dispatch(grid, "rowsSelected", {
- selection: this.getSelection()
+ findAll(grid, this.#inputSelector).forEach((cb) => {
+ if (!this.visibleOnly || cb.offsetWidth) cb.checked = this.selectAll.checked;
});
- } else {
- if (!e.target.closest(`.${SELECTABLE_CLASS}`)) {
- return;
- }
- const totalCheckboxes = findAll(grid, `tbody .${SELECTABLE_CLASS} input[type=checkbox]`);
- const totalChecked = totalCheckboxes.filter((n) => n.checked);
- this.selectAll.checked = totalChecked.length === totalCheckboxes.length;
- dispatch(grid, "rowsSelected", {
+ } else if (el.matches(this.#cbSelector)) {
+ if (!el.closest(`.${SELECTABLE_CLASS}`)) return;
+ const totalCheckboxes = findAll(grid, this.#cbSelector);
+ this.selectAll.checked = totalCheckboxes.every((n) => n.checked);
+ }
+ if (el.matches(`.${SELECT_ALL_CLASS},${this.#inputSelector}`)) {
+ dispatch(el, "rowsSelected", {
selection: grid.getSelection()
- });
+ }, true);
}
}
};
@@ -2308,7 +2367,7 @@ var FixedHeight = class extends base_plugin_default {
setAttribute(tr, "hidden", "");
tr.classList.add("dg-fake-row");
tr.tabIndex = 0;
- tbody.appendChild(tr);
+ tbody?.appendChild(tr);
}
get fakeRow() {
return this.grid.querySelector(".dg-fake-row");
@@ -2882,7 +2941,7 @@ var SaveState = class extends base_plugin_default {
this.isScrolled = false;
this.log("Init");
}
- connected() {
+ async connected() {
this.log("connected");
const grid = this.grid;
this.log(grid.options);
@@ -2893,78 +2952,88 @@ var SaveState = class extends base_plugin_default {
this.log("enabled");
const cachedState = this._getState();
if (cachedState) {
- this.log("hide columns");
- for (const col of cachedState.columns) {
- if (col.hidden) {
- const hideCol = grid.options.columns.find((c) => c.field === col.field);
- hideCol.hidden = true;
+ const waitForColumns = async () => {
+ if (!grid.options.server) return;
+ let timeout = 500, start = Date.now(), colAbsent;
+ while ((colAbsent = !grid.options.columns?.length) && Date.now() - start < timeout) {
+ await new Promise((resolve) => requestAnimationFrame(resolve));
}
- }
- this.log("set: meta, pages");
- grid.options.perPage = cachedState.perPage;
- if (grid.options.server) {
- grid.meta = cachedState.meta;
- grid.pages = cachedState.pages;
- grid.page = cachedState.page;
- }
+ colAbsent && this.log("Timeout waiting for columns.");
+ };
+ const restoreState = async () => {
+ await waitForColumns();
+ this.log("hide columns");
+ for (const col of cachedState.columns) {
+ if (col.hidden) {
+ const hideCol = grid.options.columns.find((c) => c.field === col.field);
+ hideCol.hidden = true;
+ }
+ }
+ this.log("set: meta, pages");
+ grid.options.perPage = cachedState.perPage;
+ if (grid.options.server) {
+ grid.meta = cachedState.meta;
+ grid.pages = cachedState.pages;
+ grid.page = cachedState.page;
+ }
+ };
+ await restoreState();
}
this.cachedState = cachedState;
this.log("cachedState", this.cachedState);
- setTimeout(() => {
- const dgLoadData = grid.loadData;
- grid.loadData = function(...args) {
- return dgLoadData.apply(this, args).finally(() => {
- const saveState = this.plugins.SaveState;
- saveState.log("loadData", this.options.columns);
- if (!grid.classList.contains("dg-initialized")) {
- saveState.log("not init, loadData skipped");
- return;
- }
- saveState.log("loadData finished, set param controls", this.options.columns);
- if (saveState.cachedState && !saveState.isFilterSortSet) {
- saveState.log("set sort and filters");
- const sortableHeaders = findAll(grid, "thead tr.dg-head-columns th[aria-sort]");
- for (const el of sortableHeaders) {
- el.setAttribute("aria-sort", "none");
- }
- grid.querySelector(`thead tr.dg-head-columns th[field='${saveState.cachedState.sort}']`)?.setAttribute("aria-sort", saveState.cachedState.sortDir);
- const filters2 = findAll(grid.filterRow, "[id^=dg-filter]");
- saveState.log("filters", filters2);
- for (const el of filters2) {
- el.value = saveState?.cachedState?.filters?.[el.dataset.name] ?? "";
- saveState.log({ name: el.dataset.name, val: el.value, saveState });
- }
- saveState.isFilterSortSet = true;
- }
- const newState = {
- meta: grid.meta,
- pages: grid.pages,
- page: grid.page,
- perPage: grid.options.perPage,
- filters: {},
- columns: grid.options.columns.map((col) => ({ field: col.field, hidden: col.hidden })),
- sort: grid.getSort(),
- sortDir: grid.getSortDir(),
- scrollTo: window.scrollY
- };
- const filters = grid.getFilters();
- saveState.log("filters", filters);
- for (const key of Object.keys(filters)) {
- newState.filters[key] = filters[key] ?? "";
- saveState.log({ key, val: filters[key], newState, filters });
+ const dgLoadData = grid.loadData;
+ grid.loadData = function(...args) {
+ return dgLoadData.apply(this, args).finally(() => {
+ const saveState = this.plugins.SaveState;
+ saveState.log("loadData", this.options.columns);
+ if (!grid.classList.contains("dg-initialized")) {
+ saveState.log("not init, loadData skipped");
+ return;
+ }
+ saveState.log("loadData finished, set param controls", this.options.columns);
+ if (saveState.cachedState && !saveState.isFilterSortSet) {
+ saveState.log("set sort and filters");
+ const sortableHeaders = findAll(grid, "thead tr.dg-head-columns th[aria-sort]");
+ for (const el of sortableHeaders) {
+ el.setAttribute("aria-sort", "none");
}
- saveState.log("store new state", newState);
- saveState._setState(newState);
- if (!grid.options.server && saveState.cachedState && !saveState.isDataLoaded) {
- saveState.isDataLoaded = true;
- grid.filterData();
- grid.page = saveState.cachedState.page;
- grid.pageChanged();
- saveState.log("data loaded");
+ grid.querySelector(`thead tr.dg-head-columns th[field='${saveState.cachedState.sort}']`)?.setAttribute("aria-sort", saveState.cachedState.sortDir);
+ const filters2 = findAll(grid.filterRow, "[id^=dg-filter]");
+ saveState.log("filters", filters2);
+ for (const el of filters2) {
+ el.value = saveState?.cachedState?.filters?.[el.dataset.name] ?? "";
+ saveState.log({ name: el.dataset.name, val: el.value, saveState });
}
- });
- };
- }, 0);
+ saveState.isFilterSortSet = true;
+ }
+ const newState = {
+ meta: grid.meta,
+ pages: grid.pages,
+ page: grid.page,
+ perPage: grid.options.perPage,
+ filters: {},
+ columns: grid.options.columns.map((col) => ({ field: col.field, hidden: col.hidden })),
+ sort: grid.getSort(),
+ sortDir: grid.getSortDir(),
+ scrollTo: window.scrollY
+ };
+ const filters = grid.getFilters();
+ saveState.log("filters", filters);
+ for (const key of Object.keys(filters)) {
+ newState.filters[key] = filters[key] ?? "";
+ saveState.log({ key, val: filters[key], newState, filters });
+ }
+ saveState.log("store new state", newState);
+ saveState._setState(newState);
+ if (!grid.options.server && saveState.cachedState && !saveState.isDataLoaded) {
+ saveState.isDataLoaded = true;
+ grid.filterData();
+ grid.page = saveState.cachedState.page;
+ grid.pageChanged();
+ saveState.log("data loaded");
+ }
+ });
+ };
const updateState = () => {
const saveState = grid.plugins.SaveState;
const state = saveState._getState();
diff --git a/dist/data-grid.js.map b/dist/data-grid.js.map
index 553397b..cea7f0b 100644
--- a/dist/data-grid.js.map
+++ b/dist/data-grid.js.map
@@ -1,7 +1,7 @@
{
"version": 3,
"sources": ["../src/utils/camelize.js", "../src/utils/normalizeData.js", "../src/utils/shortcuts.js", "../src/core/base-element.js", "../src/utils/addSelectOption.js", "../src/utils/appendParamsToUrl.js", "../src/utils/convertArray.js", "../src/utils/elementOffset.js", "../src/utils/interpolate.js", "../src/utils/getTextWidth.js", "../src/utils/randstr.js", "../src/utils/debounce.js", "../src/data-grid.js", "../src/core/base-plugin.js", "../src/plugins/column-resizer.js", "../src/utils/getParentElement.js", "../src/plugins/context-menu.js", "../src/plugins/draggable-headers.js", "../src/plugins/touch-support.js", "../src/plugins/selectable-rows.js", "../src/plugins/fixed-height.js", "../src/plugins/autosize-column.js", "../src/plugins/responsive-grid.js", "../src/plugins/row-actions.js", "../src/plugins/editable-column.js", "../src/plugins/spinner-support.js", "../src/plugins/save-state.js", "../data-grid.js"],
- "sourcesContent": ["/**\n * @param {String} str\n * @returns {String}\n */\nexport default function camelize(str) {\n return str.toLowerCase().replace(/[^a-zA-Z0-9]+(.)/g, (m, chr) => chr.toUpperCase());\n}\n", "/**\n * Parse data attribute and return properly typed data\n * @param {String} v\n * @returns {any}\n */\nexport default function normalizeData(v) {\n // Bool\n if (v === \"true\") {\n return true;\n }\n if (v === \"false\") {\n return false;\n }\n // Null or empty\n if (v === \"\" || v === \"null\") {\n return null;\n }\n // Numeric attributes\n if (v === Number(v).toString()) {\n return Number(v);\n }\n // Only attempt json parsing for array or objects\n if (v && [\"[\", \"{\"].includes(v.substring(0, 1))) {\n try {\n // In case we have only single quoted values, like ['one', 'two', 'three']\n let val = v;\n if (val.indexOf('\"') === -1) {\n val = val.replace(/'/g, '\"');\n }\n return JSON.parse(decodeURIComponent(val));\n } catch {\n console.error(`Failed to parse ${v}`);\n return {};\n }\n }\n return v;\n}\n", "/**\n * @typedef FlexibleHTMLProps\n * @property {boolean} [checked] (HTMLInputElement)\n * @property {string} [value] (HTMLInputElement)\n * @property {number} [rowHeight] (HTMLTableRowElement)\n *\n * A flexible type HTMLElement type that does not require using instanceof all over the place\n * Make sure that your selector is indeed valid\n * Only includes most commons props\n * @typedef {HTMLElement & FlexibleHTMLProps} FlexibleHTMLElement\n */\n\n/**\n * Keep this as reference for easy documentation\n * @typedef {HTMLElement&HTMLInputElement&HTMLTableRowElement} MixedHTMLElement\n */\n\n/**\n * @typedef FlexibleEventProps\n * @property {FlexibleHTMLElement} target\n * @property {FlexibleHTMLElement} currentTarget\n * @property {DataTransfer} [dataTransfer] (DragEvent)\n * @property {number} [clientX] (MouseEvent)\n * @property {number} [clientY] (MouseEvent)\n *\n * @typedef {Event & FlexibleEventProps} FlexibleEvent\n */\n\n/**\n * Keep this as reference for easy documentation\n * @typedef {Event&MouseEvent&InputEvent&DragEvent&FocusEvent&KeyboardEvent&PointerEvent} MixedEvent\n */\n\n/**\n * @callback FlexibleListener\n * @param {FlexibleEvent} event\n */\n\nclass FlexibleEventListenerObject {\n /**\n * @param {FlexibleEvent} e\n */\n handleEvent(e) {}\n}\n\nconst supportedPassiveTypes = [\n \"scroll\",\n \"wheel\",\n \"touchstart\",\n \"touchmove\",\n \"touchenter\",\n \"touchend\",\n \"touchleave\",\n \"mouseout\",\n \"mouseleave\",\n \"mouseup\",\n \"mousedown\",\n \"mousemove\",\n \"mouseenter\",\n \"mousewheel\",\n \"mouseover\",\n];\n\n/**\n * Automatically set passive options based on type\n * @param {string} type\n * @returns {AddEventListenerOptions}\n */\nfunction passiveOpts(type) {\n if (supportedPassiveTypes.includes(type)) {\n return { passive: true };\n }\n return {};\n}\n\n/**\n * @param {Element} el\n * @param {String} name\n * @returns {any}\n */\nexport function getAttribute(el, name) {\n return el.getAttribute(name);\n}\n\n/**\n * @param {Element} el\n * @param {String} name\n * @returns {Boolean}\n */\nexport function hasAttribute(el, name) {\n return el.hasAttribute(name);\n}\n\n/**\n * @param {Element} el\n * @param {String} name\n * @param {any} v\n * @param {Boolean} check Prevent setting if attribute is already there\n */\nexport function setAttribute(el, name, v = \"\", check = false) {\n if (check && hasAttribute(el, name)) return;\n el.setAttribute(name, `${v}`);\n}\n\n/**\n * @param {Element} el\n * @param {String} name\n */\nexport function removeAttribute(el, name) {\n if (hasAttribute(el, name)) {\n el.removeAttribute(name);\n }\n}\n\n/**\n * @param {EventTarget} el\n * @param {String} type\n * @param {EventListenerObject|FlexibleListener} listener\n */\nexport function on(el, type, listener) {\n el.addEventListener(type, listener, passiveOpts(type));\n}\n\n/**\n * @param {EventTarget} el\n * @param {String} type\n * @param {EventListenerObject|FlexibleListener} listener\n */\nexport function off(el, type, listener) {\n el.removeEventListener(type, listener, passiveOpts(type));\n}\n\n/**\n * @param {EventTarget} el\n * @param {String} type\n * @param {EventListenerObject|FlexibleListener} listener\n */\nexport function one(el, type, listener) {\n el.addEventListener(type, listener, {\n once: true,\n });\n}\n\n/**\n * @param {HTMLElement} el\n * @param {String} name\n * @param {any} data\n * @param {Boolean} bubbles\n */\nexport function dispatch(el, name, data = {}, bubbles = false) {\n const opts = {};\n if (bubbles) {\n opts.bubbles = true;\n }\n if (data) {\n opts.detail = data;\n }\n el.dispatchEvent(new CustomEvent(name, opts));\n}\n\n/**\n * @param {Element} el\n * @param {String} name\n * @returns {Boolean}\n */\nexport function hasClass(el, name) {\n return el.classList.contains(name);\n}\n\n/**\n * @param {Element} el\n * @param {String} name\n */\nexport function addClass(el, name) {\n el.classList.add(...name.split(\" \"));\n}\n\n/**\n * @param {Element} el\n * @param {String} name\n */\nexport function removeClass(el, name) {\n el.classList.remove(...name.split(\" \"));\n}\n\n/**\n * @param {Element} el\n * @param {String} name\n */\nexport function toggleClass(el, name) {\n el.classList.toggle(name);\n}\n\n/**\n * @param {String|HTMLElement} selector\n * @param {HTMLElement|Document} base\n * @returns {FlexibleHTMLElement|null}\n */\nexport function $(selector, base = document) {\n if (selector instanceof HTMLElement) {\n return selector;\n }\n return base.querySelector(selector);\n}\n\n/**\n * @param {String} selector\n * @param {Element|Document} base\n * @returns {Array}\n */\nexport function $$(selector, base = document) {\n return Array.from(base.querySelectorAll(selector));\n}\n\n/**\n * Easily retrieve untyped element\n * For actual type, prefer use of el.querySelector\n * @param {HTMLElement} el\n * @param {String|HTMLElement} selector\n * @returns {FlexibleHTMLElement}\n */\nexport function find(el, selector) {\n return $(selector, el);\n}\n\n/**\n * Easily retrieve untyped elements\n * For actual type, prefer use of el.querySelectorAll\n * @param {Element} el\n * @param {String} selector\n * @returns {Array}\n */\nexport function findAll(el, selector) {\n return $$(selector, el);\n}\n\n/**\n * @param {*} el\n * @returns {FlexibleHTMLElement}\n */\nexport function el(el) {\n return el;\n}\n\n/**\n * @template {keyof HTMLElementTagNameMap} K\n * @param {K} tagName\n * @param {HTMLElement} parent\n * @returns {HTMLElementTagNameMap[K]}\n */\nexport function ce(tagName, parent = null) {\n const el = document.createElement(tagName);\n if (parent) {\n parent.appendChild(el);\n }\n return el;\n}\n\n/**\n * @param {HTMLElement} newNode\n * @param {HTMLElement} existingNode\n */\nexport function insertAfter(newNode, existingNode) {\n existingNode.parentNode.insertBefore(newNode, existingNode.nextSibling);\n}\n", "import camelize from \"../utils/camelize.js\";\r\nimport normalizeData from \"../utils/normalizeData.js\";\r\nimport { dispatch, getAttribute, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/** @typedef {import('../data-grid').Options} Options */\r\n\r\n/**\r\n * Base element that does not contain any specific logic\r\n * related to this project but makes HTMLElemnt usable\r\n */\r\nclass BaseElement extends HTMLElement {\r\n /**\r\n * @param {Object} options\r\n */\r\n constructor(options = {}) {\r\n super();\r\n\r\n /** @type {Options} */\r\n this.options = Object.assign({}, this.defaultOptions, this.normalizedDataset, options);\r\n\r\n this.log(\"constructor\");\r\n\r\n this.setup = false;\r\n this.fireEvents = true;\r\n this._ready();\r\n\r\n this.log(\"ready\");\r\n }\r\n\r\n get defaultOptions() {\r\n return {};\r\n }\r\n\r\n /**\r\n * @param {String} opt\r\n * @returns {any}\r\n */\r\n getOption(opt) {\r\n return this.options[opt];\r\n }\r\n\r\n /**\r\n * @param {String} opt\r\n * @param {any} v\r\n */\r\n setOption(opt, v) {\r\n setAttribute(this, `data-${opt}`, v);\r\n }\r\n\r\n /**\r\n * @param {String} opt\r\n */\r\n toggleOption(opt) {\r\n setAttribute(this, `data-${opt}`, !this.getOption(opt));\r\n }\r\n\r\n get normalizedDataset() {\r\n const jsonConfig = this.dataset.config ? JSON.parse(this.dataset.config) : {};\r\n const data = { ...this.dataset };\r\n for (const key in data) {\r\n if (key === \"config\") {\r\n continue;\r\n }\r\n data[key] = normalizeData(data[key]);\r\n }\r\n // Once normalized, merge into json config\r\n Object.assign(data, jsonConfig);\r\n return data;\r\n }\r\n\r\n /**\r\n * @returns {String}\r\n */\r\n static template() {\r\n return \"\";\r\n }\r\n\r\n /**\r\n * This is called at the end of constructor. Extend in subclass if needed.\r\n */\r\n _ready() {}\r\n\r\n /**\r\n * @param {any[]} data\r\n */\r\n log(...data) {\r\n if (this.options.debug) {\r\n console.log(`[${getAttribute(this, \"id\")}] `, ...data);\r\n }\r\n }\r\n\r\n /**\r\n * Handle events within the component\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#handling-events\r\n * @param {Event} event\r\n */\r\n handleEvent(event) {\r\n if (this[`on${event.type}`]) {\r\n this[`on${event.type}`](event);\r\n }\r\n }\r\n\r\n /**\r\n * This is called when connected. Extend in subclass if needed.\r\n */\r\n _connected() {}\r\n\r\n connectedCallback() {\r\n // already connected\r\n if (this.setup) {\r\n return;\r\n }\r\n this.setup = true;\r\n // ensure whenDefined callbacks run first\r\n setTimeout(() => {\r\n this.log(\"connectedCallback\");\r\n\r\n // Append only when labels had the opportunity to be set\r\n // Don't use shadow dom as it makes theming super hard\r\n const template = document.createElement(\"template\");\r\n // @ts-ignore\r\n template.innerHTML = this.constructor.template();\r\n this.appendChild(template.content.cloneNode(true));\r\n\r\n this._connected();\r\n // @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#life-cycle-events\r\n dispatch(this, \"connected\");\r\n }, 0);\r\n }\r\n\r\n /**\r\n * This is called when disconnected. Extend in subclass if needed.\r\n */\r\n _disconnected() {}\r\n\r\n /**\r\n * @link https://nolanlawson.com/2024/12/01/avoiding-unnecessary-cleanup-work-in-disconnectedcallback/\r\n */\r\n disconnectedCallback() {\r\n setTimeout(() => {\r\n if (!this.isConnected && this.setup) {\r\n this.log(\"disconnectedCallback\");\r\n this._disconnected();\r\n // @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#life-cycle-events\r\n dispatch(this, \"disconnected\");\r\n this.setup = false;\r\n }\r\n }, 0);\r\n }\r\n\r\n /**\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#a-props-like-accessor\r\n * @returns {Object}\r\n */\r\n get transformAttributes() {\r\n return {};\r\n }\r\n\r\n /**\r\n * This is only meant to work with data attributes\r\n * This allows us to have properties that reflect automatically in the component\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#reflected-dataset-attributes\r\n * @param {String} attributeName\r\n * @param {String} oldValue\r\n * @param {String} newValue\r\n */\r\n attributeChangedCallback(attributeName, oldValue, newValue) {\r\n // It didn't change\r\n if (oldValue === newValue) {\r\n return;\r\n }\r\n\r\n this.log(`attributeChangedCallback: ${attributeName}`);\r\n\r\n let isOption = false;\r\n const transformer = this.transformAttributes[attributeName] ?? normalizeData;\r\n\r\n let attr = attributeName;\r\n // Data attributes are mapped to options while other attributes are mapped as properties\r\n if (attr.indexOf(\"data-\") === 0) {\r\n attr = attr.slice(5);\r\n isOption = true;\r\n }\r\n attr = camelize(attr);\r\n if (isOption) {\r\n this.options[attr] = transformer(newValue);\r\n } else {\r\n this[attr] = transformer(newValue);\r\n }\r\n\r\n // Fire internal event\r\n if (this.fireEvents && this[`${attr}Changed`]) {\r\n this[`${attr}Changed`]();\r\n }\r\n }\r\n}\r\n\r\nexport default BaseElement;\r\n", "/**\n * @param {HTMLSelectElement} el\n * @param {String} value\n * @param {String} label\n * @param {Boolean} checked\n */\nexport default function addSelectOption(el, value, label, checked = false) {\n const opt = document.createElement(\"option\");\n opt.value = `${value}`;\n if (checked) {\n opt.selected = true;\n }\n opt.label = label;\n el.appendChild(opt);\n}\n", "/**\n * @param {URL} url\n * @param {Object} params\n */\nexport default function appendParamsToUrl(url, params = {}) {\n for (const key of Object.keys(params)) {\n if (Array.isArray(params[key])) {\n for (const k of Object.keys(params[key])) {\n // @ts-ignore\n url.searchParams.append(isNaN(k) ? `${key}[${k}]` : key, params[key][k]);\n }\n } else {\n url.searchParams.append(key, params[key]);\n }\n }\n}\n", "/**\n * Force value as arrays\n * @param {String|Array} v\n * @returns {Array}\n */\nexport default function convertArray(v) {\n if (typeof v === \"string\") {\n if (v[0] === \"[\") {\n // \"['my', 'value']\" would fail as a json\n let bv = v;\n if (bv.indexOf('\"') === -1) {\n bv = bv.replace(/'/g, '\"');\n }\n return JSON.parse(bv);\n }\n\n return v.split(\",\");\n }\n if (!Array.isArray(v)) {\n console.error(\"Invalid array\", v);\n return [];\n }\n return v;\n}\n", "/**\n * @param {HTMLElement} el\n * @returns {Object}\n */\nexport default function elementOffset(el) {\n const rect = el.getBoundingClientRect();\n const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;\n const scrollTop = window.pageYOffset || document.documentElement.scrollTop;\n return { top: rect.top + scrollTop, left: rect.left + scrollLeft };\n}\n", "/**\n * Replace element within {} by their data value\n * @param {String} str\n * @param {Object} data\n * @returns {String}\n */\nexport default function interpolate(str, data) {\n return str.replace(/\\{([^}]+)?\\}/g, ($1, $2) => data[$2]);\n}\n", "let canvas;\n\n/**\n * Uses canvas.measureText to compute and return the width of the given text of given font in pixels.\n * Getting computed styles only works for dom that are added in the dom\n * @see https://stackoverflow.com/questions/118241/calculate-text-width-with-javascript/21015393#21015393\n * @param {String} text The text to be rendered.\n * @param {Element} el Target element (defaults to body)\n * @param {Boolean} withPadding Include padding on element\n * @returns {Number}\n */\nexport default function getTextWidth(text, el = document.body, withPadding = false) {\n const styles = window.getComputedStyle(el || document.createElement(\"div\"));\n const fontWeight = styles.getPropertyValue(\"font-weight\") || \"normal\";\n const fontSize = styles.getPropertyValue(\"font-size\") || \"1rem\";\n const fontFamily = styles.getPropertyValue(\"font-family\") || \"Arial\";\n\n let padding = 0;\n if (withPadding) {\n const paddingLeft = styles.getPropertyValue(\"padding-left\") || \"0\";\n const paddingRight = styles.getPropertyValue(\"padding-right\") || \"0\";\n padding = Number.parseInt(paddingLeft) + Number.parseInt(paddingRight);\n }\n\n // re-use canvas object for better performance\n if (!canvas) {\n canvas = document.createElement(\"canvas\");\n }\n const context = canvas.getContext(\"2d\");\n context.font = `${fontWeight} ${fontSize} ${fontFamily}`;\n const metrics = context.measureText(text);\n return Number.parseInt(metrics.width) + padding;\n}\n", "/**\n * @param {String} prefix\n * @returns {String}\n */\nexport default function randstr(prefix) {\n return Math.random()\n .toString(36)\n .replace(\"0.\", prefix || \"\");\n}\n", "/**\n * Define a function that can be happily passed to addEventListener\n * @typedef {Function & EventListenerOrEventListenerObject} ExtendedFunction\n */\n\n/**\n * @param {Function} handler\n * @param {Number} timeout\n * @returns {ExtendedFunction}\n */\nexport default function debounce(handler, timeout = 300) {\n let timer = null;\n return (...args) => {\n clearTimeout(timer);\n timer = setTimeout(() => {\n timer = null;\n handler(...args);\n }, timeout);\n };\n}\n", "/**\r\n * Data Grid Web component\r\n *\r\n * Credits for inspiration\r\n * @link https://github.com/riverside/zino-grid\r\n */\r\n\r\nimport BaseElement from \"./core/base-element.js\";\r\nimport addSelectOption from \"./utils/addSelectOption.js\";\r\nimport appendParamsToUrl from \"./utils/appendParamsToUrl.js\";\r\nimport camelize from \"./utils/camelize.js\";\r\nimport convertArray from \"./utils/convertArray.js\";\r\nimport elementOffset from \"./utils/elementOffset.js\";\r\nimport interpolate from \"./utils/interpolate.js\";\r\nimport getTextWidth from \"./utils/getTextWidth.js\";\r\nimport randstr from \"./utils/randstr.js\";\r\nimport debounce from \"./utils/debounce.js\";\r\nimport {\r\n $,\r\n $$,\r\n dispatch,\r\n find,\r\n findAll,\r\n hasClass,\r\n removeAttribute,\r\n getAttribute,\r\n setAttribute,\r\n addClass,\r\n toggleClass,\r\n on,\r\n ce,\r\n} from \"./utils/shortcuts.js\";\r\n\r\n/**\r\n * Column definition\r\n * @typedef Column\r\n * @property {String} field - the key in the data\r\n * @property {String} title - the title to display in the header (defaults to \"field\" if not set)\r\n * @property {Number} [width] - the width of the column (auto otherwise)\r\n * @property {String} [class] - class to set on the column (target body or header with th.class or td.class)\r\n * @property {String} [attr] - don't render the column and set a matching attribute on the row with the value of the field\r\n * @property {Boolean} [hidden] - hide the column\r\n * @property {Boolean} [noSort] - allow disabling sort for a given column\r\n * @property {String | Function} [format] - custom data formatting\r\n * @property {String} [defaultFormatValue] - default value to use for formatting\r\n * @property {String} [transform] - custom value transformation\r\n * @property {Boolean} [editable] - replace with input (EditableColumn module)\r\n * @property {String} [editableType] - type of input (EditableColumn module)\r\n * @property {Number} [responsive] - the higher the value, the sooner it will be hidden, disable with 0 (ResponsiveGrid module)\r\n * @property {Boolean} [responsiveHidden] - hidden through responsive module (ResponsiveGrid module)\r\n * @property {String} [filterType] - defines a filter field type (\"text\" or \"select\" - defaults to \"text\")\r\n * @property {Array} [filterList] - defines a custom array to populate a filter select field in the format of [{value: \"\", text: \"\"},...]. When defined, it overrides the default behaviour where the filter select elements are populated by the unique values from the corresponding column records.\r\n * @property {Object} [firstFilterOption] - defines an object for the first option element of the filter select field. defaults to {value: \"\", text: \"\"}\r\n */\r\n\r\n/**\r\n * Row action\r\n * @typedef Action\r\n * @property {String} title - the title of the button\r\n * @property {String} name - the name of the action\r\n * @property {String} class - the class for the button\r\n * @property {String} url - link for the action\r\n * @property {String} html - custom button data\r\n * @property {Boolean} [confirm] - needs confirmation\r\n * @property {Boolean} default - is the default row action\r\n */\r\n\r\n// Import definitions without importing the actual file\r\n/** @typedef {import('./plugins/autosize-column').default} AutosizeColumn */\r\n/** @typedef {import('./plugins/column-resizer').default} ColumnResizer */\r\n/** @typedef {import('./plugins/context-menu').default} ContextMenu */\r\n/** @typedef {import('./plugins/draggable-headers').default} DraggableHeaders */\r\n/** @typedef {import('./plugins/editable-column').default} EditableColumn */\r\n/** @typedef {import('./plugins/fixed-height').default} FixedHeight */\r\n/** @typedef {import('./plugins/responsive-grid').default} ResponsiveGrid */\r\n/** @typedef {import('./plugins/row-actions').default} RowActions */\r\n/** @typedef {import('./plugins/selectable-rows').default} SelectableRows */\r\n/** @typedef {import('./plugins/touch-support').default} TouchSupport */\r\n/** @typedef {import('./plugins/spinner-support').default} SpinnerSupport */\r\n/** @typedef {import('./plugins/save-state').default} SaveState */\r\n\r\n/**\r\n * These plugins are all optional\r\n * @typedef {Object} Plugins\r\n * @property {ColumnResizer} [ColumnResizer] resize handlers in the headers\r\n * @property {ContextMenu} [ContextMenu] menu to show/hide columns\r\n * @property {DraggableHeaders} [DraggableHeaders] draggable headers columns\r\n * @property {EditableColumn} [EditableColumn] draggable headers columns\r\n * @property {TouchSupport} [TouchSupport] touch swipe\r\n * @property {SelectableRows} [SelectableRows] create a column with checkboxes to select rows\r\n * @property {FixedHeight} [FixedHeight] allows having fixed height tables\r\n * @property {AutosizeColumn} [AutosizeColumn] compute ideal width based on column content\r\n * @property {ResponsiveGrid} [ResponsiveGrid] hide/show column on the fly\r\n * @property {RowActions} [RowActions] add action on rows\r\n * @property {SpinnerSupport} [SpinnerSupport] inserts a spinning icon element to indicate grid loading.\r\n * @property {SaveState} [SaveState] stores grid filter, sort, and paging.\r\n */\r\n\r\n/**\r\n * Parameters to pass along or receive from the server\r\n * @typedef ServerParams\r\n * @property {String} serverParams.start\r\n * @property {String} serverParams.length\r\n * @property {String} serverParams.search\r\n * @property {String} serverParams.sort\r\n * @property {String} serverParams.sortDir\r\n * @property {String} serverParams.dataKey\r\n * @property {String} serverParams.metaKey\r\n * @property {String} serverParams.metaTotalKey\r\n * @property {String} serverParams.metaFilteredKey\r\n * @property {String} serverParams.optionsKey\r\n * @property {String} serverParams.paramsKey\r\n */\r\n\r\n/**\r\n * Available data grid options, plugins included\r\n * @typedef Options\r\n * @property {?String} id Custom id for the grid\r\n * @property {?String} url An URL with data to display in JSON format\r\n * @property {Boolean} debug Log actions in DevTools console\r\n * @property {Boolean} filter Allows a filtering functionality\r\n * @property {Boolean} sort Allows a sort by column functionality\r\n * @property {String} defaultSort Default sort field if sorting is enabled\r\n * @property {Boolean} server Is a server side powered grid\r\n * @property {ServerParams} serverParams Describe keys passed to the server backend\r\n * @property {String} dir Dir\r\n * @property {Array} perPageValues Available per page options\r\n * @property {Boolean} hidePerPage Hides the page size select element\r\n * @property {Column[]} columns Available columns\r\n * @property {Number} defaultPage Starting page\r\n * @property {Number} perPage Number of records displayed per page (page size)\r\n * @property {Boolean} expand Allow cell content to spawn over multiple lines\r\n * @property {Action[]} actions Row actions (RowActions module)\r\n * @property {Boolean} collapseActions Group actions (RowActions module)\r\n * @property {Boolean} resizable Make columns resizable (ColumnResizer module)\r\n * @property {Boolean} selectable Allow selecting rows with a checkbox (SelectableRows module)\r\n * @property {Boolean} selectVisibleOnly Select all only selects visible rows (SelectableRows module)\r\n * @property {Boolean} autosize Compute column sizes based on given data (Autosize module)\r\n * @property {Boolean} autoheight Adjust height so that it matches table size (FixedHeight module)\r\n * @property {Boolean} autohidePager auto-hides the pager when number of records falls below the selected page size\r\n * @property {Boolean} menu Right click menu on column headers (ContextMenu module)\r\n * @property {Boolean} reorder Allows a column reordering functionality (DraggableHeaders module)\r\n * @property {Boolean} responsive Change display mode on small screens (ResponsiveGrid module)\r\n * @property {Boolean} responsiveToggle Show toggle column (ResponsiveGrid module)\r\n * @property {Boolean} filterOnEnter Toggles the ability to filter column data by pressing the Enter or Return key\r\n * @property {String} spinnerClass Sets a space-delimited string of css classes for a spinner (use spinner-border css class for bootstrap 5 spinner)\r\n * @property {Number} filterKeypressDelay Sets a keypress delay time in milliseconds before triggering filter operation.\r\n * @property {Boolean} saveState Enable/disable save state plugin (SaveState module)\r\n * @property {?String} errorMessage A generic text to be displayed in footer when error occurs.\r\n */\r\n\r\n/**\r\n * Available labels that can be translated\r\n * @typedef Labels\r\n * @property {String} itemsPerPage\r\n * @property {String} gotoPage\r\n * @property {String} gotoFirstPage\r\n * @property {String} gotoPrevPage\r\n * @property {String} gotoNextPage\r\n * @property {String} gotoLastPage\r\n * @property {String} of\r\n * @property {String} items\r\n * @property {String} resizeColumn\r\n * @property {String} noData\r\n * @property {String} areYouSure\r\n * @property {String} networkError\r\n */\r\n\r\n/**\r\n * List of registered plugins\r\n * @type {Plugins}\r\n */\r\nlet plugins = {};\r\n\r\n/**\r\n * @type {Labels}\r\n */\r\nlet labels = {\r\n itemsPerPage: \"Items per page\",\r\n gotoPage: \"Go to page\",\r\n gotoFirstPage: \"Go to first page\",\r\n gotoPrevPage: \"Go to previous page\",\r\n gotoNextPage: \"Go to next page\",\r\n gotoLastPage: \"Go to last page\",\r\n of: \"of\",\r\n items: \"items\",\r\n resizeColumn: \"Resize column\",\r\n noData: \"No data\",\r\n areYouSure: \"Are you sure?\",\r\n networkError: \"Network response error\",\r\n};\r\n\r\n/**\r\n * Column definition will update some props on the html element\r\n * @param {HTMLElement} el\r\n * @param {Column} column\r\n */\r\nfunction applyColumnDefinition(el, column) {\r\n if (column.width) {\r\n setAttribute(el, \"width\", column.width);\r\n }\r\n if (column.class) {\r\n addClass(el, column.class);\r\n }\r\n if (column.hidden) {\r\n setAttribute(el, \"hidden\", \"\");\r\n if (column.responsiveHidden) {\r\n addClass(el, \"dg-responsive-hidden\");\r\n }\r\n }\r\n}\r\n\r\n/**\r\n */\r\nclass DataGrid extends BaseElement {\r\n _filterSelector = \"[id^=dg-filter]\";\r\n _excludedKeys = [\r\n 37,\r\n 39,\r\n 38,\r\n 40,\r\n 45,\r\n 36,\r\n 35,\r\n 33,\r\n 34,\r\n 27,\r\n 20,\r\n 16,\r\n 17,\r\n 91,\r\n 92,\r\n 18,\r\n 93,\r\n 144,\r\n 231,\r\n \"ArrowLeft\",\r\n \"ArrowRight\",\r\n \"ArrowUp\",\r\n \"ArrowDown\",\r\n \"Insert\",\r\n \"Home\",\r\n \"End\",\r\n \"PageUp\",\r\n \"PageDown\",\r\n \"Escape\",\r\n \"CapsLock\",\r\n \"Shift\",\r\n \"Control\",\r\n \"Meta\",\r\n \"Alt\",\r\n \"ContextMenu\",\r\n \"NumLock\",\r\n \"Unidentified\",\r\n ];\r\n\r\n _ready() {\r\n setAttribute(this, \"id\", this.options.id ?? randstr(\"el-\"), true);\r\n\r\n /**\r\n * The grid displays that data\r\n * @type {Array}\r\n */\r\n this.data = [];\r\n /**\r\n * We store the original data in this\r\n * @type {Array}\r\n */\r\n this.originalData; // declared uninitialized to allow data preloading before fetch.\r\n\r\n // Make the IDE happy\r\n /**\r\n * @type {Options}\r\n */\r\n this.options = this.options || this.defaultOptions;\r\n\r\n // Init values\r\n this.fireEvents = false;\r\n this.page = this.options.defaultPage || 1;\r\n this.pages = 0;\r\n this.meta; // declared uninitialized to allow data preloading before fetch.\r\n /**\r\n * @type {Plugins}\r\n */\r\n this.plugins = {};\r\n // Init plugins\r\n for (const [pluginName, pluginClass] of Object.entries(plugins)) {\r\n // @ts-ignore until we can set typeof import ...\r\n this.plugins[pluginName] = new pluginClass(this);\r\n }\r\n\r\n // Expose options as observed attributes in the dom\r\n // Do it when fireEvents is disabled to avoid firing change callbacks\r\n for (const attr of DataGrid.observedAttributes) {\r\n if (attr.indexOf(\"data-\") === 0) {\r\n setAttribute(this, attr, this.options[camelize(attr.slice(5))]);\r\n }\r\n }\r\n }\r\n\r\n static template() {\r\n return `\r\n\r\n \r\n |
\r\n
\r\n \r\n \r\n \r\n \r\n | \r\n \r\n | \r\n
\r\n \r\n \r\n
\r\n`;\r\n }\r\n\r\n /**\r\n * @returns {Labels}\r\n */\r\n get labels() {\r\n return labels;\r\n }\r\n\r\n /**\r\n * @returns {Labels}\r\n */\r\n static getLabels() {\r\n return labels;\r\n }\r\n\r\n /**\r\n * @param {Object} v\r\n */\r\n static setLabels(v) {\r\n labels = Object.assign(labels, v);\r\n }\r\n\r\n /**\r\n * @returns {Column}\r\n */\r\n get defaultColumn() {\r\n return {\r\n field: \"\",\r\n title: \"\",\r\n width: 0,\r\n class: \"\",\r\n attr: \"\",\r\n hidden: false,\r\n editable: false,\r\n noSort: false,\r\n responsive: 1,\r\n responsiveHidden: false,\r\n format: \"\",\r\n transform: \"\",\r\n filterType: \"text\",\r\n firstFilterOption: { value: \"\", text: \"\" },\r\n };\r\n }\r\n\r\n /**\r\n * @returns {Options}\r\n */\r\n get defaultOptions() {\r\n return {\r\n id: null,\r\n url: null,\r\n perPage: 10,\r\n debug: false,\r\n filter: false,\r\n menu: false,\r\n sort: false,\r\n server: false,\r\n serverParams: {\r\n start: \"start\",\r\n length: \"length\",\r\n search: \"search\",\r\n sort: \"sort\",\r\n sortDir: \"sortDir\",\r\n dataKey: \"data\",\r\n metaKey: \"meta\",\r\n metaTotalKey: \"total\",\r\n metaFilteredKey: \"filtered\",\r\n optionsKey: \"options\",\r\n paramsKey: \"params\",\r\n },\r\n defaultSort: \"\",\r\n reorder: false,\r\n dir: \"ltr\",\r\n perPageValues: [10, 25, 50, 100, 250],\r\n hidePerPage: false,\r\n columns: [],\r\n actions: [],\r\n collapseActions: false,\r\n selectable: false,\r\n selectVisibleOnly: true,\r\n defaultPage: 1,\r\n resizable: false,\r\n autosize: true,\r\n expand: false,\r\n autoheight: true,\r\n autohidePager: false,\r\n responsive: false,\r\n responsiveToggle: true,\r\n filterOnEnter: true,\r\n filterKeypressDelay: 500,\r\n spinnerClass: \"\",\r\n saveState: false,\r\n errorMessage: \"\",\r\n };\r\n }\r\n\r\n /**\r\n * Determines if the grid is initialized.\r\n * @returns {Boolean}\r\n */\r\n get isInit() {\r\n return this.classList.contains(\"dg-initialized\");\r\n }\r\n\r\n /**\r\n * Determines if data load has failed.\r\n * @returns {Boolean}\r\n */\r\n get hasDataError() {\r\n return this.classList.contains(\"dg-network-error\");\r\n }\r\n\r\n /**\r\n * @param {Plugins} list\r\n */\r\n static registerPlugins(list) {\r\n plugins = list;\r\n }\r\n\r\n /**\r\n * @param {String} plugin\r\n */\r\n static unregisterPlugins(plugin = null) {\r\n if (plugin === null) {\r\n plugins = {};\r\n } else {\r\n delete plugins[plugin];\r\n }\r\n }\r\n\r\n /**\r\n * @returns {Plugins}\r\n */\r\n static registeredPlugins() {\r\n return plugins;\r\n }\r\n\r\n /**\r\n * @param {Object|Array} columns\r\n * @returns {Column[]}\r\n */\r\n convertColumns(columns) {\r\n const cols = [];\r\n // Convert key:value objects to actual columns\r\n if (typeof columns === \"object\" && !Array.isArray(columns)) {\r\n for (const key of Object.keys(columns)) {\r\n const col = Object.assign({}, this.defaultColumn);\r\n col.title = columns[key];\r\n col.field = key;\r\n cols.push(col);\r\n }\r\n } else {\r\n for (const item of columns) {\r\n let col = Object.assign({}, this.defaultColumn);\r\n if (typeof item === \"string\") {\r\n col.title = item;\r\n col.field = item;\r\n } else if (typeof item === \"object\") {\r\n col = Object.assign(col, item);\r\n if (!col.field) {\r\n console.error(\"Invalid column definition\", item);\r\n }\r\n if (!col.title) {\r\n col.title = col.field;\r\n }\r\n } else {\r\n console.error(\"Column definition must be a string or an object\");\r\n }\r\n cols.push(col);\r\n }\r\n }\r\n return cols;\r\n }\r\n\r\n /**\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#reflected-dom-attributes\r\n * @returns {Array}\r\n */\r\n static get observedAttributes() {\r\n return [\r\n \"page\",\r\n \"data-filter\",\r\n \"data-sort\",\r\n \"data-debug\",\r\n \"data-reorder\",\r\n \"data-menu\",\r\n \"data-selectable\",\r\n \"data-url\",\r\n \"data-per-page\",\r\n \"data-responsive\",\r\n ];\r\n }\r\n\r\n get transformAttributes() {\r\n return {\r\n columns: (v) => this.convertColumns(convertArray(v)),\r\n actions: (v) => convertArray(v),\r\n defaultPage: (v) => Number.parseInt(v),\r\n perPage: (v) => Number.parseInt(v),\r\n };\r\n }\r\n\r\n /** @returns {HTMLTableSectionElement} */\r\n get thead() {\r\n //@ts-ignore\r\n return $(\"thead\", this);\r\n }\r\n\r\n /** @returns {HTMLTableSectionElement} */\r\n get tbody() {\r\n //@ts-ignore\r\n return $(\"tbody\", this);\r\n }\r\n\r\n /** @returns {HTMLTableSectionElement} */\r\n get tfoot() {\r\n //@ts-ignore\r\n return $(\"tfoot\", this);\r\n }\r\n\r\n get page() {\r\n return Number.parseInt(this.getAttribute(\"page\"));\r\n }\r\n\r\n set page(val) {\r\n setAttribute(this, \"page\", this.constrainPageValue(val));\r\n }\r\n\r\n /**\r\n * Loads data and configures the grid.\r\n * @param {Boolean} initOnly\r\n */\r\n urlChanged(initOnly = false) {\r\n if (initOnly && !this.isInit) return;\r\n this.reconfig();\r\n this.loadData().then(() => {\r\n this.configureUi();\r\n });\r\n }\r\n\r\n /**\r\n * Clears columns, re-renders table, and repopulates columns to ensure consistent column widths rendering.\r\n */\r\n reconfig() {\r\n const cols = this.options.columns;\r\n this.options.columns = [];\r\n this.configureUi();\r\n this.options.columns = cols;\r\n }\r\n\r\n constrainPageValue(v) {\r\n let pv = v;\r\n if (this.pages < pv) {\r\n pv = this.pages;\r\n }\r\n if (pv < 1 || !pv) {\r\n pv = 1;\r\n }\r\n return pv;\r\n }\r\n\r\n fixPage() {\r\n this.pages = this.totalPages();\r\n this.page = this.constrainPageValue(this.page);\r\n\r\n // Show current page in input\r\n setAttribute(this.inputPage, \"max\", this.pages);\r\n this.inputPage.value = `${this.page}`;\r\n this.inputPage.disabled = this.pages < 2;\r\n }\r\n\r\n pageChanged() {\r\n this.reload();\r\n }\r\n\r\n responsiveChanged() {\r\n if (!this.plugins.ResponsiveGrid) {\r\n return;\r\n }\r\n if (this.options.responsive) {\r\n this.plugins.ResponsiveGrid.observe();\r\n } else {\r\n this.plugins.ResponsiveGrid.unobserve();\r\n }\r\n }\r\n\r\n menuChanged() {\r\n this.renderHeader();\r\n }\r\n\r\n /**\r\n * This is the callback for the select control\r\n */\r\n changePerPage() {\r\n this.options.perPage = Number.parseInt(this.selectPerPage.options[this.selectPerPage.selectedIndex].value);\r\n this.perPageChanged();\r\n }\r\n\r\n /**\r\n * This is the actual event triggered on attribute change\r\n */\r\n perPageChanged() {\r\n // Refresh UI\r\n if (\r\n this.options.perPage !== Number.parseInt(this.selectPerPage.options[this.selectPerPage.selectedIndex].value)\r\n ) {\r\n this.perPageValuesChanged();\r\n }\r\n // Make sure current page is still valid\r\n let updatePage = this.page;\r\n while (updatePage > 1 && this.page * this.options.perPage > this.totalRecords()) {\r\n updatePage--;\r\n }\r\n if (updatePage !== this.page) {\r\n // Triggers pageChanged, which will trigger reload\r\n this.page = updatePage;\r\n } else {\r\n // Simply reload current page\r\n this.reload(() => {\r\n // Preserve distance between top of page and select control if no fixed height\r\n if (!this.plugins.FixedHeight || !this.plugins.FixedHeight.hasFixedHeight) {\r\n this.selectPerPage.scrollIntoView();\r\n }\r\n });\r\n }\r\n }\r\n\r\n dirChanged() {\r\n setAttribute(this, \"dir\", this.options.dir);\r\n }\r\n\r\n defaultSortChanged() {\r\n this.sortChanged();\r\n }\r\n\r\n /**\r\n * Populate the select dropdown according to options\r\n */\r\n perPageValuesChanged() {\r\n if (!this.selectPerPage) {\r\n return;\r\n }\r\n while (this.selectPerPage.lastChild) {\r\n this.selectPerPage.removeChild(this.selectPerPage.lastChild);\r\n }\r\n for (const v of this.options.perPageValues) {\r\n addSelectOption(this.selectPerPage, v, v, v === this.options.perPage);\r\n }\r\n }\r\n\r\n _connected() {\r\n /**\r\n * @type {HTMLTableElement}\r\n */\r\n this.table = this.querySelector(\"table\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnFirst = this.querySelector(\".dg-btn-first\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnPrev = this.querySelector(\".dg-btn-prev\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnNext = this.querySelector(\".dg-btn-next\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnLast = this.querySelector(\".dg-btn-last\");\r\n /**\r\n * @type {HTMLSelectElement}\r\n */\r\n this.selectPerPage = this.querySelector(\".dg-select-per-page\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.inputPage = this.querySelector(\".dg-input-page\");\r\n\r\n this.getFirst = this.getFirst.bind(this);\r\n this.getPrev = this.getPrev.bind(this);\r\n this.getNext = this.getNext.bind(this);\r\n this.getLast = this.getLast.bind(this);\r\n this.changePerPage = this.changePerPage.bind(this);\r\n this.gotoPage = this.gotoPage.bind(this);\r\n\r\n this.btnFirst.addEventListener(\"click\", this.getFirst);\r\n this.btnPrev.addEventListener(\"click\", this.getPrev);\r\n this.btnNext.addEventListener(\"click\", this.getNext);\r\n this.btnLast.addEventListener(\"click\", this.getLast);\r\n this.selectPerPage.addEventListener(\"change\", this.changePerPage);\r\n this.selectPerPage.toggleAttribute(\"hidden\", this.options.hidePerPage);\r\n this.inputPage.addEventListener(\"input\", this.gotoPage);\r\n\r\n for (const plugin of Object.values(this.plugins)) {\r\n plugin.connected();\r\n }\r\n\r\n // Display even if we don't have data\r\n this.dirChanged();\r\n this.perPageValuesChanged();\r\n\r\n setTimeout(() => { //ensures all registered plugins are connected before loading data\r\n // @ts-ignore\r\n this.loadData().finally(() => {\r\n this.configureUi();\r\n\r\n this.sortChanged();\r\n this.classList.add(\"dg-initialized\"); //acts as a flag to prevent unnecessary server calls down the chain.\r\n\r\n this.filterChanged();\r\n this.reorderChanged();\r\n\r\n this.dirChanged();\r\n this.perPageValuesChanged();\r\n this.pageChanged();\r\n\r\n this.fireEvents = true; // We can now fire attributeChangedCallback events\r\n\r\n this.log(\"initialized\");\r\n });\r\n }, 0);\r\n }\r\n\r\n _disconnected() {\r\n this.btnFirst?.removeEventListener(\"click\", this.getFirst);\r\n this.btnPrev?.removeEventListener(\"click\", this.getPrev);\r\n this.btnNext?.removeEventListener(\"click\", this.getNext);\r\n this.btnLast?.removeEventListener(\"click\", this.getLast);\r\n this.selectPerPage?.removeEventListener(\"change\", this.changePerPage);\r\n this.inputPage?.removeEventListener(\"input\", this.gotoPage);\r\n\r\n for (const plugin of Object.values(this.plugins)) {\r\n plugin.disconnected();\r\n }\r\n }\r\n\r\n /**\r\n * @param {string} field\r\n * @returns {Column}\r\n */\r\n getCol(field) {\r\n let found = null;\r\n\r\n for (const col of this.options.columns) {\r\n if (col.field === field) {\r\n found = col;\r\n }\r\n }\r\n return found;\r\n }\r\n\r\n getColProp(field, prop) {\r\n const c = this.getCol(field);\r\n return c ? c[prop] : null;\r\n }\r\n\r\n setColProp(field, prop, val) {\r\n const c = this.getCol(field);\r\n if (c) {\r\n c[prop] = val;\r\n }\r\n }\r\n\r\n visibleColumns() {\r\n return this.options.columns.filter((col) => {\r\n return !col.hidden;\r\n });\r\n }\r\n\r\n hiddenColumns() {\r\n return this.options.columns.filter((col) => {\r\n return col.hidden === true;\r\n });\r\n }\r\n\r\n showColumn(field, render = true) {\r\n this.setColProp(field, \"hidden\", false);\r\n\r\n // We need to render the whole table otherwise layout fixed won't do its job\r\n if (render) this.renderTable();\r\n\r\n dispatch(this, \"columnVisibility\", {\r\n col: field,\r\n visibility: \"visible\",\r\n });\r\n }\r\n\r\n hideColumn(field, render = true) {\r\n this.setColProp(field, \"hidden\", true);\r\n\r\n // We need to render the whole table otherwise layout fixed won't do its job\r\n if (render) this.renderTable();\r\n\r\n dispatch(this, \"columnVisibility\", {\r\n col: field,\r\n visibility: \"hidden\",\r\n });\r\n }\r\n\r\n /**\r\n * Returns the starting index of actual data\r\n * @returns {Number}\r\n */\r\n startColIndex() {\r\n let start = 1;\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n start++;\r\n }\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n start++;\r\n }\r\n return start;\r\n }\r\n\r\n /**\r\n * @returns {Boolean}\r\n */\r\n isSticky() {\r\n return this.hasAttribute(\"sticky\");\r\n }\r\n\r\n /**\r\n * @param {Boolean} visibleOnly\r\n * @returns {Number}\r\n */\r\n columnsLength(visibleOnly = false) {\r\n let len = 0;\r\n // One column per (visible) column\r\n for (const col of this.options.columns) {\r\n if (visibleOnly && col.hidden) {\r\n continue;\r\n }\r\n if (!col.attr) {\r\n len++;\r\n }\r\n }\r\n // Add one col for selectable checkbox at the beginning\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n len++;\r\n }\r\n // Add one col for actions at the end\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n len++;\r\n }\r\n // Add one col for the responsive toggle\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n len++;\r\n }\r\n return len;\r\n }\r\n\r\n /**\r\n * Global configuration and renderTable\r\n * This should be called after your data has been loaded\r\n */\r\n configureUi() {\r\n this.table.style.visibility = \"hidden\";\r\n this.renderTable();\r\n if (this.options.responsive && this.plugins.ResponsiveGrid) {\r\n // Let the observer make the table visible\r\n } else {\r\n this.table.style.visibility = \"visible\";\r\n }\r\n\r\n // Store row height for later usage\r\n if (!this.rowHeight) {\r\n const tr = find(this, \"tbody tr\") || find(this, \"table tr\");\r\n if (tr) {\r\n this.rowHeight = tr.offsetHeight;\r\n }\r\n }\r\n this.fixPage();\r\n }\r\n\r\n filterChanged() {\r\n const row = this.querySelector(\"thead tr.dg-head-filters\");\r\n if (this.options.filter) {\r\n removeAttribute(row, \"hidden\");\r\n } else {\r\n this.clearFilters();\r\n setAttribute(row, \"hidden\", \"\");\r\n }\r\n }\r\n\r\n reorderChanged() {\r\n const headers = findAll(this, \"thead tr.dg-head-columns th\");\r\n for (const th of headers) {\r\n if (th.classList.contains(\"dg-selectable\") || th.classList.contains(\"dg-actions\")) {\r\n continue;\r\n }\r\n if (this.options.reorder && this.plugins.DraggableHeaders) {\r\n th.draggable = true;\r\n } else {\r\n th.removeAttribute(\"draggable\");\r\n }\r\n }\r\n }\r\n\r\n sortChanged() {\r\n this.log(\"toggle sort\");\r\n\r\n const headers = findAll(this, \"thead tr.dg-head-columns th\");\r\n for (const th of headers) {\r\n const fieldName = th.getAttribute(\"field\");\r\n if (\r\n th.classList.contains(\"dg-not-sortable\") ||\r\n (!this.fireEvents && fieldName === this.options.defaultSort)\r\n ) {\r\n return;\r\n }\r\n if (this.options.sort && !this.getColProp(fieldName, \"noSort\")) {\r\n setAttribute(th, \"aria-sort\", \"none\");\r\n } else {\r\n removeAttribute(th, \"aria-sort\");\r\n }\r\n }\r\n }\r\n\r\n selectableChanged() {\r\n this.renderTable();\r\n }\r\n\r\n addRow(row) {\r\n if (!Array.isArray(this.originalData)) {\r\n return;\r\n }\r\n this.log(\"add row\");\r\n this.originalData.push(row);\r\n this.data = this.originalData.slice();\r\n this.sortData();\r\n }\r\n\r\n /**\r\n * @param {any} value Value to remove. Defaults to last row.\r\n * @param {String} key The key of the item to remove. Defaults to first column\r\n */\r\n removeRow(value = null, key = null) {\r\n if (!Array.isArray(this.originalData)) {\r\n return;\r\n }\r\n\r\n let v = value;\r\n let k = key;\r\n if (k === null) {\r\n k = this.options.columns[0].field;\r\n }\r\n if (v === null) {\r\n v = this.originalData[this.originalData.length - 1][k];\r\n }\r\n this.log(`remove row ${k}:${v}`);\r\n for (let i = 0; i < this.originalData.length; i++) {\r\n if (this.originalData[i][k] === v) {\r\n this.originalData.splice(i, 1);\r\n break;\r\n }\r\n }\r\n this.data = this.originalData.slice();\r\n this.sortData();\r\n }\r\n\r\n /**\r\n * @param {String} key Return a specific key (eg: id) instead of the whole row\r\n * @returns {Array}\r\n */\r\n getSelection(key = null) {\r\n if (!this.plugins.SelectableRows) {\r\n return [];\r\n }\r\n return this.plugins.SelectableRows.getSelection(key);\r\n }\r\n\r\n getData() {\r\n return this.originalData;\r\n }\r\n\r\n clearData() {\r\n // Already empty\r\n if (this.data.length === 0) {\r\n return;\r\n }\r\n this.data = this.originalData = [];\r\n this.renderBody();\r\n }\r\n\r\n /**\r\n * Preloads the data intended to bypass the initial fetch operation, allowing for faster intial page load time.\r\n * Subsequent grid actions after initialization will operate as normal.\r\n * @param {Object} data - an object with meta ({total, filtered, start}) and data (array of objects) properties.\r\n */\r\n preload(data) {\r\n const metaKey = this.options.serverParams.metaKey;\r\n const dataKey = this.options.serverParams.dataKey;\r\n if (data?.[metaKey]) {\r\n this.meta = data[metaKey];\r\n }\r\n if (data?.[dataKey]) {\r\n this.data = this.originalData = data[dataKey];\r\n }\r\n }\r\n\r\n refresh(cb = null) {\r\n this.data = this.originalData = [];\r\n return this.reload(cb);\r\n }\r\n\r\n reload(cb = null) {\r\n this.log(\"reload\");\r\n\r\n // If the data was cleared, we need to render again\r\n const needRender = !this.originalData?.length;\r\n this.fixPage();\r\n // @ts-ignore\r\n this.loadData().finally(() => {\r\n if (this.hasDataError) return;\r\n // If we load data from the server, we redraw the table body\r\n // Otherwise, we just need to paginate\r\n this.options.server || needRender ? this.renderBody() : this.paginate();\r\n if (cb) {\r\n cb();\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * @returns {Promise}\r\n */\r\n loadData() {\r\n const flagEmpty = () => !this.data.length && this.classList.add(\"dg-empty\");\r\n const tbody = this.tbody;\r\n\r\n // We already have some data\r\n if (this.meta || this.originalData || this.isInit) {\r\n // We don't use server side data\r\n if (!this.options.server || (this.options.server && !this.fireEvents)) {\r\n this.log(\"skip loadData\");\r\n flagEmpty();\r\n return new Promise((resolve) => {\r\n resolve();\r\n });\r\n }\r\n }\r\n this.log(\"loadData\");\r\n this.loading = true;\r\n this.classList.add(\"dg-loading\");\r\n this.classList.remove(\"dg-empty\", \"dg-network-error\");\r\n return (\r\n this.fetchData()\r\n .then((response) => {\r\n // We can get a straight array or an object\r\n if (Array.isArray(response)) {\r\n this.data = response;\r\n } else {\r\n // Object must contain data key\r\n if (!response[this.options.serverParams.dataKey]) {\r\n console.error(\r\n \"Invalid response, it should contain a data key with an array or be a plain array\",\r\n response,\r\n );\r\n this.options.url = null;\r\n return;\r\n }\r\n\r\n // We may have a config object\r\n this.options = Object.assign(\r\n this.options,\r\n response[this.options.serverParams.optionsKey] ?? {},\r\n );\r\n // It should return meta data (see metaFilteredKey)\r\n this.meta = response[this.options.serverParams.metaKey] ?? {};\r\n this.data = response[this.options.serverParams.dataKey];\r\n }\r\n this.originalData = this.data.slice();\r\n this.fixPage();\r\n\r\n // Make sure we have a proper set of columns\r\n if (this.options.columns.length === 0 && this.originalData.length) {\r\n this.options.columns = this.convertColumns(Object.keys(this.originalData[0]));\r\n } else {\r\n this.options.columns = this.convertColumns(this.options.columns);\r\n }\r\n })\r\n .catch((err) => {\r\n this.log(err);\r\n tbody.setAttribute(\r\n \"data-empty\",\r\n this.options.errorMessage ||\r\n err.message?.replace(/^\\s+|\\r\\n|\\n|\\r$/g, \"\") ||\r\n labels.networkError,\r\n );\r\n this.classList.add(\"dg-empty\", \"dg-network-error\");\r\n dispatch(this, \"loadDataFailed\", err);\r\n })\r\n // @ts-ignore\r\n .finally(() => {\r\n flagEmpty();\r\n if (!this.hasDataError && tbody.getAttribute(\"data-empty\") !== this.labels.noData) {\r\n tbody.setAttribute(\"data-empty\", this.labels.noData);\r\n }\r\n this.classList.remove(\"dg-loading\");\r\n setAttribute(this.table, \"aria-rowcount\", this.data.length);\r\n this.loading = false;\r\n })\r\n );\r\n }\r\n\r\n getFirst() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = 1;\r\n }\r\n\r\n getLast() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = this.pages;\r\n }\r\n\r\n getPrev() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = this.page - 1;\r\n }\r\n\r\n getNext() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = this.page + 1;\r\n }\r\n\r\n gotoPage(event) {\r\n if (event.type === \"keypress\") {\r\n const key = event.keyCode || event.key;\r\n if (key === 13 || key === \"Enter\") {\r\n event.preventDefault();\r\n } else {\r\n return;\r\n }\r\n }\r\n this.page = Number.parseInt(this.inputPage.value);\r\n }\r\n\r\n getSort() {\r\n const col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n if (col) {\r\n return col.getAttribute(\"field\");\r\n }\r\n return this.options.defaultSort;\r\n }\r\n\r\n getSortDir() {\r\n const col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n if (col) {\r\n return col.getAttribute(\"aria-sort\") || \"\";\r\n }\r\n return \"\";\r\n }\r\n\r\n getFilters() {\r\n const filters = [];\r\n const inputs = findAll(this, this._filterSelector);\r\n for (const input of inputs) {\r\n filters[input.dataset.name] = input.value;\r\n }\r\n return filters;\r\n }\r\n\r\n clearFilters() {\r\n const inputs = findAll(this, this._filterSelector);\r\n for (const input of inputs) {\r\n input.value = \"\";\r\n }\r\n this.filterData();\r\n }\r\n\r\n filterData() {\r\n this.log(\"filter data\");\r\n\r\n this.page = 1;\r\n\r\n if (this.options.server) {\r\n this.reload();\r\n } else {\r\n this.data = this.originalData?.slice() ?? [];\r\n\r\n // Look for rows matching the filters\r\n const inputs = findAll(this, this._filterSelector);\r\n for (const input of inputs) {\r\n const value = input.value;\r\n if (value) {\r\n const name = input.dataset.name;\r\n this.data = this.data.filter((item) => {\r\n const str = `${item[name]}`;\r\n return str.toLowerCase().indexOf(value.toLowerCase()) !== -1;\r\n });\r\n }\r\n }\r\n this.pageChanged();\r\n\r\n const col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n if (this.options.sort && col) {\r\n this.sortData();\r\n } else {\r\n this.renderBody();\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Data will be sorted then rendered using renderBody\r\n * @param {Element} baseCol The column that was clicked or null to use current sort\r\n */\r\n sortData(baseCol = null) {\r\n this.log(\"sort data\");\r\n\r\n let col = baseCol;\r\n\r\n // Early exit\r\n if (col && this.getColProp(col.getAttribute(\"field\"), \"noSort\")) {\r\n this.log(\"sorting prevented because column is not sortable\");\r\n return;\r\n }\r\n if (this.plugins.ColumnResizer?.isResizing) {\r\n this.log(\"sorting prevented because resizing\");\r\n return;\r\n }\r\n if (this.loading) {\r\n this.log(\"sorting prevented because loading\");\r\n return;\r\n }\r\n\r\n // We clicked on a column, update sort state\r\n if (col !== null) {\r\n // Remove active sort if any\r\n const haveClasses = (c) => [\"dg-selectable\", \"dg-actions\", \"dg-responsive-toggle\"].includes(c);\r\n\r\n const headers = findAll(this, \"thead tr:first-child th\");\r\n for (const th of headers) {\r\n // @ts-ignore\r\n if ([...th.classList].some(haveClasses)) {\r\n continue;\r\n }\r\n if (th !== col) {\r\n th.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n }\r\n\r\n // Set tristate col\r\n if (!col.hasAttribute(\"aria-sort\") || col.getAttribute(\"aria-sort\") === \"none\") {\r\n col.setAttribute(\"aria-sort\", \"ascending\");\r\n } else if (col.getAttribute(\"aria-sort\") === \"ascending\") {\r\n col.setAttribute(\"aria-sort\", \"descending\");\r\n } else if (col.getAttribute(\"aria-sort\") === \"descending\") {\r\n col.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n } else {\r\n // Or fetch current sort\r\n col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n }\r\n\r\n if (this.options.server) {\r\n // Reload data with updated sort\r\n this.loadData().finally(() => {\r\n this.renderBody();\r\n });\r\n } else {\r\n const sort = col ? col.getAttribute(\"aria-sort\") : \"none\";\r\n if (sort === \"none\") {\r\n const stack = [];\r\n\r\n // Restore order while keeping filters\r\n this.originalData?.some((itemA) => {\r\n this.data.some((itemB) => {\r\n if (JSON.stringify(itemA) === JSON.stringify(itemB)) {\r\n stack.push(itemB);\r\n return true;\r\n }\r\n return false;\r\n });\r\n return stack.length === this.data.length;\r\n });\r\n\r\n this.data = stack;\r\n } else {\r\n const field = col.getAttribute(\"field\");\r\n this.data.sort((a, b) => {\r\n if (!isNaN(a[field]) && !isNaN(b[field])) {\r\n return sort === \"ascending\" ? a[field] - b[field] : b[field] - a[field];\r\n }\r\n const valA = sort === \"ascending\" ? a[field].toUpperCase() : b[field].toUpperCase();\r\n const valB = sort === \"ascending\" ? b[field].toUpperCase() : a[field].toUpperCase();\r\n\r\n switch (true) {\r\n case valA > valB:\r\n return 1;\r\n case valA < valB:\r\n return -1;\r\n case valA === valB:\r\n return 0;\r\n }\r\n });\r\n }\r\n this.renderBody();\r\n }\r\n }\r\n\r\n _sort(columnName, sortDir) {\r\n const col = this.querySelector(`.dg-head-columns th[field=${columnName}]`);\r\n const dir = sortDir === \"ascending\" ? \"none\" : sortDir === \"descending\" ? \"ascending\" : \"descending\";\r\n col?.setAttribute(\"aria-sort\", dir);\r\n this.sortData(col);\r\n }\r\n\r\n sortAsc = (columnName) => this._sort(columnName, \"ascending\");\r\n sortDesc = (columnName) => this._sort(columnName, \"descending\");\r\n sortNone = (columnName) => this._sort(columnName, \"none\");\r\n\r\n fetchData() {\r\n if (!this.options.url) {\r\n return new Promise((resolve, reject) => reject(\"No url set\"));\r\n }\r\n\r\n let base = window.location.href;\r\n // Fix trailing slash if no extension is present\r\n if (!base.split(\"/\").pop().includes(\".\")) {\r\n base += base.endsWith(\"/\") ? \"\" : \"/\";\r\n }\r\n const url = new URL(this.options.url, base);\r\n let params = {\r\n r: Date.now(),\r\n };\r\n if (this.options.server) {\r\n // 0 based\r\n params[this.options.serverParams.start] = this.page - 1;\r\n params[this.options.serverParams.length] = this.options.perPage;\r\n if (this.options.filter) params[this.options.serverParams.search] = this.getFilters();\r\n params[this.options.serverParams.sort] = this.getSort() || \"\";\r\n params[this.options.serverParams.sortDir] = this.getSortDir();\r\n\r\n // extra params ?\r\n if (this.meta?.[this.options.serverParams.paramsKey]) {\r\n params = Object.assign(params, this.meta[this.options.serverParams.paramsKey]);\r\n }\r\n }\r\n\r\n appendParamsToUrl(url, params);\r\n\r\n return fetch(url).then((response) => {\r\n const newError = new Error(response.statusText || labels.networkError);\r\n if (!response.ok) {\r\n // @ts-ignore\r\n newError.response = response;\r\n throw newError;\r\n }\r\n return response\r\n .clone()\r\n .json()\r\n .catch((err) => {\r\n let error = err;\r\n if (!this.options.debug) {\r\n error = newError;\r\n }\r\n error.response = response;\r\n throw error;\r\n });\r\n });\r\n }\r\n\r\n renderTable() {\r\n this.log(\"render table\");\r\n\r\n if (this.options.menu && this.plugins.ContextMenu) {\r\n this.plugins.ContextMenu.createMenu();\r\n }\r\n\r\n let sortedColumn;\r\n\r\n this.renderHeader();\r\n if (this.options.defaultSort) {\r\n // We can have a default sort even with sort disabled\r\n sortedColumn = this.querySelector(`thead tr.dg-head-columns th[field=\"${this.options.defaultSort}\"]`);\r\n }\r\n\r\n if (sortedColumn) {\r\n this.sortData(sortedColumn);\r\n } else {\r\n this.renderBody();\r\n }\r\n\r\n this.renderFooter();\r\n }\r\n\r\n /**\r\n * Create table header\r\n * - One row for the column headers\r\n * - One row for the filters\r\n */\r\n renderHeader() {\r\n this.log(\"render header\");\r\n\r\n const thead = this.thead;\r\n this.createColumnHeaders(thead);\r\n this.createColumnFilters(thead);\r\n\r\n if (this.options.resizable && this.plugins.ColumnResizer) {\r\n this.plugins.ColumnResizer.renderResizer(labels.resizeColumn);\r\n }\r\n\r\n dispatch(this, \"headerRendered\");\r\n }\r\n\r\n renderFooter() {\r\n this.log(\"render footer\");\r\n\r\n const tfoot = this.tfoot;\r\n const td = tfoot.querySelector(\"td\");\r\n tfoot.removeAttribute(\"hidden\");\r\n setAttribute(td, \"colspan\", this.columnsLength(true));\r\n tfoot.style.display = \"\";\r\n }\r\n\r\n /**\r\n * Create the column headers based on column definitions and set options\r\n * @param {HTMLTableSectionElement} thead\r\n */\r\n createColumnHeaders(thead) {\r\n // @link https://stackoverflow.com/questions/21064101/understanding-offsetwidth-clientwidth-scrollwidth-and-height-respectively\r\n const availableWidth = this.clientWidth;\r\n const colMaxWidth = Math.round((availableWidth / this.columnsLength(true)) * 2);\r\n\r\n let idx = 0;\r\n let tr;\r\n\r\n // Create row\r\n tr = ce(\"tr\");\r\n this.headerRow = tr;\r\n tr.setAttribute(\"role\", \"row\");\r\n tr.setAttribute(\"aria-rowindex\", \"1\");\r\n tr.setAttribute(\"class\", \"dg-head-columns\");\r\n\r\n // We need a real th from the dom to compute the size\r\n let sampleTh = thead.querySelector(\"tr.dg-head-columns th\");\r\n this.log(\"createColumnHeaders - sampleTh\", sampleTh);\r\n if (!sampleTh) {\r\n sampleTh = ce(\"th\");\r\n thead.querySelector(\"tr\").appendChild(sampleTh);\r\n }\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.createHeaderCol(tr);\r\n }\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n this.plugins.ResponsiveGrid.createHeaderCol(tr);\r\n }\r\n\r\n // Create columns\r\n idx = 0;\r\n let totalWidth = 0;\r\n this.log(\"createColumnHeaders - columns\", this.options.columns);\r\n\r\n for (const column of this.options.columns) {\r\n if (column.attr) {\r\n continue;\r\n }\r\n const colIdx = idx + this.startColIndex();\r\n const th = ce(\"th\");\r\n th.setAttribute(\"scope\", \"col\");\r\n th.setAttribute(\"role\", \"columnheader button\");\r\n th.setAttribute(\"aria-colindex\", `${colIdx}`);\r\n th.setAttribute(\"id\", randstr(\"dg-col-\"));\r\n if (this.options.sort) {\r\n th.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n th.setAttribute(\"field\", column.field);\r\n if (this.plugins.ResponsiveGrid && this.options.responsive) {\r\n setAttribute(th, \"data-responsive\", column.responsive || \"\");\r\n }\r\n // Make sure the header fits (+ add some room for sort icon if necessary)\r\n const computedWidth = getTextWidth(column.title, sampleTh, true) + 20;\r\n th.dataset.minWidth = `${computedWidth}`;\r\n applyColumnDefinition(th, column);\r\n th.tabIndex = 0;\r\n th.textContent = column.title;\r\n\r\n let w = 0;\r\n // Autosize small based on first/last row ?\r\n // Take into account minWidth of the header and max available size based on col numbers\r\n if (this.options.autosize && this.plugins.AutosizeColumn) {\r\n const colAvailableWidth = Math.min(availableWidth - totalWidth, colMaxWidth);\r\n w = this.plugins.AutosizeColumn.computeSize(\r\n th,\r\n column,\r\n Number.parseInt(th.dataset.minWidth),\r\n colAvailableWidth,\r\n );\r\n } else {\r\n w = Math.max(Number.parseInt(th.dataset.minWidth), Number.parseInt(th.getAttribute(\"width\")));\r\n }\r\n\r\n setAttribute(th, \"width\", w);\r\n if (column.hidden) {\r\n th.setAttribute(\"hidden\", \"\");\r\n } else {\r\n totalWidth += w;\r\n }\r\n\r\n // Reorder columns with drag/drop\r\n if (this.options.reorder && this.plugins.DraggableHeaders) {\r\n this.plugins.DraggableHeaders.makeHeaderDraggable(th);\r\n }\r\n\r\n tr.appendChild(th);\r\n idx++;\r\n }\r\n\r\n // There is too much available width, and we want to avoid fixed layout to split remaining amount\r\n if (totalWidth < availableWidth) {\r\n const visibleCols = findAll(tr, \"th:not([hidden],.dg-not-resizable)\");\r\n if (visibleCols.length) {\r\n const lastCol = visibleCols[visibleCols.length - 1];\r\n removeAttribute(lastCol, \"width\");\r\n }\r\n }\r\n\r\n // Actions\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n this.plugins.RowActions.makeActionHeader(tr);\r\n }\r\n\r\n thead.replaceChild(tr, thead.querySelector(\"tr.dg-head-columns\"));\r\n\r\n // Once columns are inserted, we have an actual dom to query\r\n if (thead.offsetWidth > availableWidth) {\r\n this.log(`adjust width to fix size, ${thead.offsetWidth} > ${availableWidth}`);\r\n const scrollbarWidth = this.offsetWidth - this.clientWidth;\r\n let diff = thead.offsetWidth - availableWidth - scrollbarWidth;\r\n if (this.options.responsive && this.plugins.ResponsiveGrid) {\r\n diff += scrollbarWidth;\r\n }\r\n // Remove diff for columns that can afford it\r\n const thWithWidth = findAll(tr, \"th[width]\");\r\n\r\n for (const th of thWithWidth) {\r\n if (hasClass(th, \"dg-not-resizable\")) {\r\n continue;\r\n }\r\n if (diff <= 0) {\r\n continue;\r\n }\r\n const actualWidth = Number.parseInt(th.getAttribute(\"width\"));\r\n const minWidth = th.dataset.minWidth ? Number.parseInt(th.dataset.minWidth) : 0;\r\n if (actualWidth > minWidth) {\r\n let newWidth = actualWidth - diff;\r\n if (newWidth < minWidth) {\r\n newWidth = minWidth;\r\n }\r\n diff -= actualWidth - newWidth;\r\n setAttribute(th, \"width\", newWidth);\r\n }\r\n }\r\n }\r\n\r\n // Context menu\r\n if (this.options.menu && this.plugins.ContextMenu) {\r\n this.plugins.ContextMenu.attachContextMenu();\r\n }\r\n\r\n // Sort col on click\r\n const rowsWithSort = findAll(tr, \"[aria-sort]\");\r\n for (const sortableRow of rowsWithSort) {\r\n sortableRow.addEventListener(\"click\", () => this.sortData(sortableRow));\r\n }\r\n\r\n setAttribute(this.table, \"aria-colcount\", this.columnsLength(true));\r\n }\r\n\r\n createColumnFilters(thead) {\r\n let idx = 0;\r\n let tr;\r\n\r\n // Create row for filters\r\n tr = ce(\"tr\");\r\n this.filterRow = tr;\r\n tr.setAttribute(\"role\", \"row\");\r\n tr.setAttribute(\"aria-rowindex\", \"2\");\r\n tr.setAttribute(\"class\", \"dg-head-filters\");\r\n if (!this.options.filter) {\r\n tr.setAttribute(\"hidden\", \"\");\r\n }\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.createFilterCol(tr);\r\n }\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n this.plugins.ResponsiveGrid.createFilterCol(tr);\r\n }\r\n\r\n this.log(\"createColumnFilters - columns\", this.options.columns);\r\n for (const column of this.options.columns) {\r\n if (column.attr) {\r\n continue;\r\n }\r\n const colIdx = idx + this.startColIndex();\r\n const relatedTh = thead.querySelector(`tr.dg-head-columns th[aria-colindex=\"${colIdx}\"]`);\r\n if (!relatedTh) {\r\n console.warn(\"Related th not found\", colIdx);\r\n continue;\r\n }\r\n const th = ce(\"th\");\r\n th.setAttribute(\"aria-colindex\", `${colIdx}`);\r\n\r\n const filter = this.createFilterElement(column, relatedTh);\r\n if (!this.options.filter) {\r\n th.tabIndex = 0;\r\n } else {\r\n filter.tabIndex = 0;\r\n }\r\n\r\n if (column.hidden) {\r\n th.setAttribute(\"hidden\", \"\");\r\n }\r\n\r\n th.appendChild(filter);\r\n tr.appendChild(th);\r\n idx++;\r\n }\r\n\r\n // Actions\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n this.plugins.RowActions.makeActionFilter(tr);\r\n }\r\n\r\n thead.replaceChild(tr, thead.querySelector(\"tr.dg-head-filters\"));\r\n\r\n if (typeof this.options.filterKeypressDelay !== \"number\" || this.options.filterOnEnter)\r\n this.options.filterKeypressDelay = 0;\r\n\r\n // Filter content by field events\r\n const filteredRows = findAll(tr, this._filterSelector);\r\n for (const el of filteredRows) {\r\n const eventName = /select/i.test(el.tagName) ? \"change\" : \"keyup\";\r\n const eventHandler = debounce((e) => {\r\n const key = e.keyCode || e.key;\r\n const isKeyPressFilter = !this.options.filterOnEnter && !this._excludedKeys.some((k) => k === key);\r\n if (key === 13 || key === \"Enter\" || isKeyPressFilter || e.type === \"change\") {\r\n this.filterData.call(this);\r\n }\r\n }, this.options.filterKeypressDelay);\r\n el.addEventListener(eventName, eventHandler);\r\n }\r\n }\r\n\r\n createFilterElement(column, relatedTh) {\r\n const isSelect = column.filterType === \"select\";\r\n const filter = isSelect ? ce(\"select\") : ce(\"input\");\r\n if (isSelect) {\r\n if (!Array.isArray(column.filterList)) {\r\n // Gets unique values from column records\r\n const uniqueValues = [...new Set((this.data ?? []).map((e) => e[column.field]))]\r\n .filter((v) => v)\r\n .sort();\r\n column.filterList = [column.firstFilterOption || this.defaultColumn.firstFilterOption].concat(\r\n uniqueValues.map((e) => ({ value: e, text: e })),\r\n );\r\n }\r\n\r\n for (const e of column.filterList) {\r\n const opt = ce(\"option\");\r\n opt.value = e.value;\r\n opt.text = e.text;\r\n\r\n if (filter instanceof HTMLSelectElement) {\r\n filter.add(opt);\r\n }\r\n }\r\n } else {\r\n //@ts-ignore\r\n filter.type = \"text\";\r\n filter.inputMode = \"search\";\r\n filter.autocomplete = \"off\";\r\n filter.spellcheck = false;\r\n }\r\n // Allows binding filter to this column\r\n filter.dataset.name = column.field;\r\n filter.id = randstr(\"dg-filter-\");\r\n // Don't use aria-label as it triggers autocomplete\r\n filter.setAttribute(\"aria-labelledby\", relatedTh.getAttribute(\"id\"));\r\n return filter;\r\n }\r\n\r\n /**\r\n * Render the data as rows in tbody\r\n * It will call paginate() at the end\r\n */\r\n renderBody() {\r\n this.log(\"render body\");\r\n let tr;\r\n let td;\r\n let idx;\r\n const tbody = ce(\"tbody\");\r\n\r\n this.data.forEach((item, i) => {\r\n tr = ce(\"tr\");\r\n setAttribute(tr, \"role\", \"row\");\r\n setAttribute(tr, \"hidden\", \"\");\r\n setAttribute(tr, \"aria-rowindex\", i + 1);\r\n tr.tabIndex = 0;\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.createDataCol(tr);\r\n }\r\n if (\r\n this.options.responsive &&\r\n this.plugins.ResponsiveGrid &&\r\n this.plugins.ResponsiveGrid.hasHiddenColumns()\r\n ) {\r\n this.plugins.ResponsiveGrid.createDataCol(tr);\r\n }\r\n\r\n // Expandable\r\n if (this.options.expand) {\r\n tr.classList.add(\"dg-expandable\");\r\n\r\n on(tr, \"click\", (ev) => {\r\n if (this.plugins.ResponsiveGrid) {\r\n this.plugins.ResponsiveGrid.blockObserver();\r\n }\r\n toggleClass(ev.currentTarget, \"dg-expanded\");\r\n if (this.plugins.ResponsiveGrid) {\r\n this.plugins.ResponsiveGrid.unblockObserver();\r\n }\r\n });\r\n }\r\n\r\n idx = 0;\r\n\r\n for (const column of this.options.columns) {\r\n if (!column) {\r\n console.error(\"Empty column found!\", this.options.columns);\r\n }\r\n // It should be applied as an attr of the row\r\n if (column.attr) {\r\n if (item[column.field]) {\r\n // Special case if we try to write over the class attr\r\n if (column.attr === \"class\") {\r\n addClass(tr, item[column.field]);\r\n } else {\r\n tr.setAttribute(column.attr, item[column.field]);\r\n }\r\n }\r\n return;\r\n }\r\n td = ce(\"td\");\r\n td.setAttribute(\"role\", \"gridcell\");\r\n td.setAttribute(\"aria-colindex\", `${idx}${this.startColIndex()}`);\r\n applyColumnDefinition(td, column);\r\n // This is required for pure css responsive layout\r\n td.setAttribute(\"data-name\", column.title);\r\n td.tabIndex = -1;\r\n\r\n // Inline editing ...\r\n if (column.editable && this.plugins.EditableColumn) {\r\n addClass(td, \"dg-editable-col\");\r\n this.plugins.EditableColumn.makeEditableInput(td, column, item, i);\r\n } else {\r\n // ... or formatting\r\n const v = item[column.field] ?? \"\";\r\n let tv;\r\n // TODO: make this modular\r\n switch (column.transform) {\r\n case \"uppercase\":\r\n tv = v.toUpperCase();\r\n break;\r\n case \"lowercase\":\r\n tv = v.toLowerCase();\r\n break;\r\n default:\r\n tv = v;\r\n break;\r\n }\r\n if (column.format) {\r\n // Only use formatting with values or if defaultFormatValue is set\r\n if (column.defaultFormatValue !== undefined && (tv === \"\" || tv === null)) {\r\n tv = `${column.defaultFormatValue}`;\r\n }\r\n if (typeof column.format === \"string\" && tv) {\r\n td.innerHTML = interpolate(\r\n // @ts-ignore\r\n column.format,\r\n Object.assign(\r\n {\r\n _v: v,\r\n _tv: tv,\r\n },\r\n item,\r\n ),\r\n );\r\n } else if (column.format instanceof Function) {\r\n const val = column.format.call(this, { column, rowData: item, cellData: tv, td, tr });\r\n td.innerHTML = val || tv || v;\r\n }\r\n } else {\r\n td.textContent = tv;\r\n }\r\n }\r\n tr.appendChild(td);\r\n idx++;\r\n }\r\n\r\n // Actions\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n this.plugins.RowActions.makeActionRow(tr, item);\r\n }\r\n\r\n tbody.appendChild(tr);\r\n\r\n dispatch(this, \"rowRendered\", { rowData: item, tr });\r\n });\r\n\r\n tbody.setAttribute(\"role\", \"rowgroup\");\r\n\r\n // Keep data empty message\r\n const prev = this.tbody;\r\n tbody.setAttribute(\"data-empty\", prev.getAttribute(\"data-empty\"));\r\n this.table.replaceChild(tbody, prev);\r\n\r\n if (this.plugins.FixedHeight) {\r\n this.plugins.FixedHeight.createFakeRow();\r\n }\r\n\r\n this.paginate();\r\n\r\n if (this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.shouldSelectAll(tbody);\r\n }\r\n\r\n this.data.length && this.classList.remove(\"dg-empty\");\r\n\r\n dispatch(this, \"bodyRendered\");\r\n }\r\n\r\n paginate() {\r\n this.log(\"paginate\");\r\n\r\n const total = this.totalRecords();\r\n const p = this.page || 1;\r\n const tbody = this.tbody;\r\n const tfoot = this.tfoot;\r\n const bodyRows = findAll(tbody, \"tr\");\r\n\r\n // Refresh page count in case we added/removed a page\r\n this.pages = this.totalPages();\r\n\r\n let index;\r\n let high = p * this.options.perPage;\r\n let low = high - this.options.perPage + 1;\r\n\r\n if (high > total) {\r\n high = total;\r\n }\r\n if (!total) {\r\n low = 0;\r\n }\r\n\r\n // Display all rows within the set indexes\r\n // For server side paginated grids, we display everything\r\n // since the server is taking care of actual pagination\r\n for (const tr of bodyRows) {\r\n if (this.options.server) {\r\n removeAttribute(tr, \"hidden\");\r\n continue;\r\n }\r\n index = Number(getAttribute(tr, \"aria-rowindex\"));\r\n if (index > high || index < low) {\r\n setAttribute(tr, \"hidden\", \"\");\r\n } else {\r\n removeAttribute(tr, \"hidden\");\r\n }\r\n }\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.clearCheckboxes(tbody);\r\n }\r\n\r\n // Store default height and update styles if needed\r\n if (this.plugins.FixedHeight) {\r\n this.plugins.FixedHeight.updateFakeRow();\r\n }\r\n\r\n // Enable/disable buttons if shown\r\n if (this.btnFirst) {\r\n this.btnFirst.disabled = this.page <= 1;\r\n this.btnPrev.disabled = this.page <= 1;\r\n this.btnNext.disabled = this.page >= this.pages;\r\n this.btnLast.disabled = this.page >= this.pages;\r\n }\r\n tfoot.querySelector(\".dg-low\").textContent = low.toString();\r\n tfoot.querySelector(\".dg-high\").textContent = high.toString();\r\n tfoot.querySelector(\".dg-total\").textContent = `${this.totalRecords()}`;\r\n tfoot.toggleAttribute(\"hidden\", this.options.autohidePager && this.options.perPage > this.totalRecords());\r\n }\r\n\r\n /**\r\n * @returns {number}\r\n */\r\n totalPages() {\r\n return Math.ceil(this.totalRecords() / this.options.perPage);\r\n }\r\n\r\n /**\r\n * @returns {number}\r\n */\r\n totalRecords() {\r\n if (this.options.server) {\r\n return this.meta?.[this.options.serverParams.metaFilteredKey] || 0;\r\n }\r\n return this.data.length;\r\n }\r\n}\r\n\r\nexport default DataGrid;\r\n", "/** @typedef {import(\"../data-grid\").default} DataGrid */\n\nclass BasePlugin {\n /**\n * @param {DataGrid} grid\n */\n constructor(grid) {\n this.grid = grid;\n }\n\n connected() {}\n\n disconnected() {}\n\n /**\n * Handle events within the plugin\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#handling-events\n * @param {Event} event\n */\n handleEvent(event) {\n if (this[`on${event.type}`]) {\n this[`on${event.type}`](event);\n }\n }\n}\n\nexport default BasePlugin;\n", "import BasePlugin from \"../core/base-plugin.js\";\nimport elementOffset from \"../utils/elementOffset.js\";\nimport {\n addClass,\n dispatch,\n findAll,\n getAttribute,\n hasClass,\n off,\n on,\n removeAttribute,\n removeClass,\n setAttribute,\n} from \"../utils/shortcuts.js\";\n\n/**\n * Allows to resize columns\n */\nclass ColumnResizer extends BasePlugin {\n constructor(grid) {\n super(grid);\n this.isResizing = false;\n }\n\n /**\n * @param {String} resizeLabel\n */\n renderResizer(resizeLabel) {\n const grid = this.grid;\n const table = grid.table;\n const cols = findAll(grid, \"thead tr.dg-head-columns th\");\n\n for (const col of cols) {\n if (hasClass(col, \"dg-not-resizable\")) {\n continue;\n }\n // Create a resizer element\n const resizer = document.createElement(\"div\");\n addClass(resizer, \"dg-resizer\");\n resizer.ariaLabel = resizeLabel;\n\n // Add a resizer element to the column\n col.appendChild(resizer);\n\n // Handle resizing\n let startX = 0;\n let startW = 0;\n let remainingSpace = 0;\n let max = 0;\n\n const mouseMoveHandler = (e) => {\n if (e.clientX > max) {\n return;\n }\n const newWidth = startW + (e.clientX - startX);\n if (col.dataset.minWidth && newWidth > Number.parseInt(col.dataset.minWidth)) {\n setAttribute(col, \"width\", newWidth);\n }\n };\n\n // When user releases the mouse, remove the existing event listeners\n const mouseUpHandler = () => {\n grid.log(\"resized column\");\n\n // Prevent accidental sorting if mouse is not over resize handler\n setTimeout(() => {\n this.isResizing = false;\n }, 0);\n\n removeClass(resizer, \"dg-resizer-active\");\n if (grid.options.reorder) {\n col.draggable = true;\n }\n col.style.overflow = \"hidden\";\n\n // Remove handlers\n off(document, \"mousemove\", mouseMoveHandler);\n off(document, \"mouseup\", mouseUpHandler);\n\n dispatch(grid, \"columnResized\", {\n col: getAttribute(col, \"field\"),\n width: getAttribute(col, \"width\"),\n });\n };\n\n // Otherwise it could sort the col\n on(resizer, \"click\", (e) => {\n e.stopPropagation();\n });\n\n on(resizer, \"mousedown\", (e) => {\n e.stopPropagation();\n\n this.isResizing = true;\n\n const target = e.target;\n const currentCols = findAll(grid, \"dg-head-columns th\");\n const visibleCols = currentCols.filter((col) => {\n return !col.hasAttribute(\"hidden\");\n });\n const columnIndex = visibleCols.findIndex((column) => column === target.parentNode);\n grid.log(\"resize column\");\n\n addClass(resizer, \"dg-resizer-active\");\n\n // Make sure we don't drag it\n removeAttribute(col, \"draggable\");\n\n // Allow overflow when resizing\n col.style.overflow = \"visible\";\n\n // Show full column height (-1 to avoid scrollbar)\n resizer.style.height = `${table.offsetHeight - 1}px`;\n\n // Register initial data\n startX = e.clientX;\n startW = col.offsetWidth;\n\n remainingSpace = (visibleCols.length - columnIndex) * 30;\n max = elementOffset(target).left + grid.offsetWidth - remainingSpace;\n\n // Remove width from next columns to allow auto layout\n setAttribute(col, \"width\", startW);\n for (let j = 0; j < visibleCols.length; j++) {\n if (j > columnIndex) {\n removeAttribute(cols[j], \"width\");\n }\n }\n\n // Attach handlers\n on(document, \"mousemove\", mouseMoveHandler);\n on(document, \"mouseup\", mouseUpHandler);\n });\n }\n }\n}\n\nexport default ColumnResizer;\n", "/**\n * @param {HTMLElement} el\n * @param {String} type\n * @param {String} prop\n * @returns {HTMLElement}\n */\nexport default function getParentElement(el, type, prop = \"nodeName\") {\n let parent = el;\n while (parent[prop] !== type) {\n parent = parent.parentElement;\n }\n return parent;\n}\n", "import BasePlugin from \"../core/base-plugin.js\";\nimport getParentElement from \"../utils/getParentElement.js\";\nimport { find, off, on, removeAttribute, setAttribute } from \"../utils/shortcuts.js\";\n\n/**\n * Create a right click menu on the headers\n */\nclass ContextMenu extends BasePlugin {\n connected() {\n /**\n * @type {HTMLUListElement}\n */\n this.menu = this.grid.querySelector(\".dg-menu\");\n }\n disconnected() {\n if (this.grid.headerRow) {\n off(this.grid.headerRow, \"contextmenu\", this);\n }\n }\n\n attachContextMenu() {\n const grid = this.grid;\n on(grid.headerRow, \"contextmenu\", this);\n }\n\n onchange(e) {\n const grid = this.grid;\n const t = e.target;\n const field = t.dataset.name;\n if (t.checked) {\n grid.showColumn(field);\n } else {\n // Prevent hidding last\n if (grid.visibleColumns().length <= 1) {\n // Restore checkbox value\n t.checked = true;\n return;\n }\n grid.hideColumn(field);\n }\n grid.fixPage(); //fixes Chrome footer flexbox resize issues that may appear when there is a large number of columns (i.e. more than 10).\n }\n\n oncontextmenu(e) {\n e.preventDefault();\n const grid = this.grid;\n const target = getParentElement(e.target, \"THEAD\");\n const menu = this.menu;\n const rect = target.getBoundingClientRect();\n let x = e.clientX - rect.left;\n const y = e.clientY - rect.top;\n\n menu.style.top = `${y}px`;\n menu.style.left = `${x}px`;\n\n removeAttribute(menu, \"hidden\");\n if (x + 150 > rect.width) {\n x -= menu.offsetWidth;\n menu.style.left = `${x}px`;\n }\n\n const documentClickHandler = (e) => {\n if (!menu.contains(e.target)) {\n setAttribute(menu, \"hidden\", \"\");\n off(document, \"click\", documentClickHandler);\n }\n };\n on(document, \"click\", documentClickHandler);\n }\n createMenu() {\n const grid = this.grid;\n const menu = this.menu;\n while (menu.lastChild) {\n menu.removeChild(menu.lastChild);\n }\n menu.addEventListener(\"change\", this);\n\n for (const col of grid.options.columns) {\n if (col.attr) {\n continue;\n }\n const li = document.createElement(\"li\");\n const label = document.createElement(\"label\");\n const checkbox = document.createElement(\"input\");\n setAttribute(checkbox, \"type\", \"checkbox\");\n setAttribute(checkbox, \"data-name\", col.field);\n if (!col.hidden) {\n checkbox.checked = true;\n }\n const text = document.createTextNode(col.title);\n\n label.appendChild(checkbox);\n label.appendChild(text);\n\n li.appendChild(label);\n menu.appendChild(li);\n }\n }\n}\n\nexport default ContextMenu;\n", "import BasePlugin from \"../core/base-plugin.js\";\nimport getParentElement from \"../utils/getParentElement.js\";\nimport { dispatch, findAll, getAttribute, on, setAttribute } from \"../utils/shortcuts.js\";\n\n/**\n * Allows to move headers\n */\nclass DraggableHeaders extends BasePlugin {\n /**\n * @param {HTMLTableCellElement} th\n */\n makeHeaderDraggable(th) {\n const grid = this.grid;\n th.draggable = true;\n on(th, \"dragstart\", (e) => {\n if (grid.plugins.ColumnResizer?.isResizing && e.preventDefault) {\n e.preventDefault();\n return;\n }\n grid.log(\"reorder col\");\n e.dataTransfer.effectAllowed = \"move\";\n e.dataTransfer.setData(\"text/plain\", e.target.getAttribute(\"aria-colindex\"));\n });\n on(th, \"dragover\", (e) => {\n if (e.preventDefault) {\n e.preventDefault();\n }\n e.dataTransfer.dropEffect = \"move\";\n return false;\n });\n on(th, \"drop\", (e) => {\n if (e.stopPropagation) {\n e.stopPropagation();\n }\n const t = e.target;\n const target = getParentElement(t, \"TH\");\n const index = Number.parseInt(e.dataTransfer.getData(\"text/plain\"));\n const targetIndex = Number.parseInt(target.getAttribute(\"aria-colindex\"));\n\n if (index === targetIndex) {\n grid.log(\"reordered col stayed the same\");\n return;\n }\n grid.log(`reordered col from ${index} to ${targetIndex}`);\n\n const offset = grid.startColIndex();\n const tmp = grid.options.columns[index - offset];\n grid.options.columns[index - offset] = grid.options.columns[targetIndex - offset];\n grid.options.columns[targetIndex - offset] = tmp;\n\n const swapNodes = (selector, el1) => {\n const rowIndex = el1.parentNode.getAttribute(\"aria-rowindex\");\n const el2 = grid.querySelector(\n `${selector} tr[aria-rowindex=\"${rowIndex}\"] [aria-colindex=\"${targetIndex}\"]`,\n );\n setAttribute(el1, \"aria-colindex\", targetIndex);\n setAttribute(el2, \"aria-colindex\", index);\n const newNode = document.createElement(\"th\");\n el1.parentNode.insertBefore(newNode, el1);\n el2.parentNode.replaceChild(el1, el2);\n newNode.parentNode.replaceChild(el2, newNode);\n };\n\n // Swap all rows in header and body\n for (const el1 of findAll(grid, `thead th[aria-colindex=\"${index}\"]`)) {\n swapNodes(\"thead\", el1);\n }\n for (const el1 of findAll(grid, `tbody td[aria-colindex=\"${index}\"]`)) {\n swapNodes(\"tbody\", el1);\n }\n\n // Updates the columns\n grid.options.columns = findAll(grid, \"thead tr.dg-head-columns th[field]\").map((th) =>\n grid.options.columns.find((c) => c.field === getAttribute(th, \"field\")),\n );\n\n dispatch(grid, \"columnReordered\", {\n col: tmp.field,\n from: index,\n to: targetIndex,\n });\n return false;\n });\n }\n}\n\nexport default DraggableHeaders;\n", "import BasePlugin from \"../core/base-plugin.js\";\n\n/**\n * Allows to paginate with horizontal swipe motions\n */\nclass TouchSupport extends BasePlugin {\n constructor(grid) {\n super(grid);\n this.touch = null;\n }\n connected() {\n const grid = this.grid;\n grid.addEventListener(\"touchstart\", this, { passive: true });\n grid.addEventListener(\"touchmove\", this, { passive: true });\n }\n\n disconnected() {\n const grid = this.grid;\n grid.removeEventListener(\"touchstart\", this);\n grid.removeEventListener(\"touchmove\", this);\n }\n\n ontouchstart(e) {\n this.touch = e.touches[0];\n }\n\n ontouchmove(e) {\n if (!this.touch) {\n return;\n }\n const grid = this.grid;\n const xDiff = this.touch.clientX - e.touches[0].clientX;\n const yDiff = this.touch.clientY - e.touches[0].clientY;\n\n if (Math.abs(xDiff) > Math.abs(yDiff)) {\n if (xDiff > 0) {\n grid.getNext();\n } else {\n grid.getPrev();\n }\n }\n this.touch = null;\n }\n}\n\nexport default TouchSupport;\n", "import BasePlugin from \"../core/base-plugin.js\";\nimport { dispatch, findAll, hasClass, setAttribute } from \"../utils/shortcuts.js\";\n\nconst SELECTABLE_CLASS = \"dg-selectable\";\nconst SELECT_ALL_CLASS = \"dg-select-all\";\nconst CHECKBOX_CLASS = \"form-check-input\"; //bs5\n\n/**\n * Allows to select rows\n */\nclass SelectableRows extends BasePlugin {\n disconnected() {\n if (this.selectAll) {\n this.selectAll.removeEventListener(\"change\", this);\n }\n }\n\n /**\n * @param {String} key Return a specific key (eg: id) instead of the whole row\n * @returns {Array}\n */\n getSelection(key = null) {\n const grid = this.grid;\n const selectedData = [];\n\n const inputs = findAll(grid, `tbody .${SELECTABLE_CLASS} input:checked`);\n\n for (const checkbox of inputs) {\n const idx = Number.parseInt(checkbox.dataset.id);\n const item = grid.data[idx - 1];\n if (!item) {\n console.warn(`Item ${idx} not found`);\n }\n if (key) {\n selectedData.push(item[key]);\n } else {\n selectedData.push(item);\n }\n }\n return selectedData;\n }\n\n /**\n * Uncheck box if hidden and visible only\n * @param {HTMLTableSectionElement} tbody\n */\n clearCheckboxes(tbody) {\n const grid = this.grid;\n if (!grid.options.selectVisibleOnly) {\n return;\n }\n const inputs = findAll(tbody, `tr[hidden] .${SELECTABLE_CLASS} input`);\n for (const input of inputs) {\n input.checked = false;\n }\n this.selectAll.checked = false;\n }\n\n colIndex() {\n return this.grid.startColIndex() - 2;\n }\n\n /**\n * @param {HTMLTableRowElement} tr\n */\n createHeaderCol(tr) {\n const th = document.createElement(\"th\");\n setAttribute(th, \"scope\", \"col\");\n setAttribute(th, \"role\", \"columnheader button\");\n setAttribute(th, \"aria-colindex\", this.colIndex());\n th.classList.add(...[SELECTABLE_CLASS, \"dg-not-resizable\", \"dg-not-sortable\"]);\n th.tabIndex = 0;\n\n this.selectAll = document.createElement(\"input\");\n this.selectAll.type = \"checkbox\";\n this.selectAll.classList.add(SELECT_ALL_CLASS);\n this.selectAll.classList.add(CHECKBOX_CLASS);\n this.selectAll.addEventListener(\"change\", this);\n\n const label = document.createElement(\"label\");\n label.appendChild(this.selectAll);\n\n th.appendChild(label);\n\n th.setAttribute(\"width\", \"40\");\n tr.appendChild(th);\n }\n\n /**\n * @param {HTMLTableRowElement} tr\n */\n createFilterCol(tr) {\n const th = document.createElement(\"th\");\n setAttribute(th, \"role\", \"columnheader button\");\n setAttribute(th, \"aria-colindex\", this.colIndex());\n th.classList.add(SELECTABLE_CLASS);\n th.tabIndex = 0;\n\n tr.appendChild(th);\n }\n\n /**\n * Handles the selectAll checkbox when any other .dg-selectable checkbox is checked on table body.\n * It should check selectAll if all is checked\n * It should uncheck selectAll if any is unchecked\n * @param {HTMLTableSectionElement} tbody\n */\n shouldSelectAll(tbody) {\n if (!this.selectAll) {\n return;\n }\n // Delegate listener for change events on input checkboxes\n tbody.addEventListener(\"change\", this);\n // Make sure state is up to date\n tbody.dispatchEvent(new Event(\"change\"));\n }\n\n /**\n * @param {HTMLTableRowElement} tr\n */\n createDataCol(tr) {\n // Create col\n const td = document.createElement(\"td\");\n setAttribute(td, \"role\", \"gridcell button\");\n setAttribute(td, \"aria-colindex\", this.colIndex());\n td.classList.add(SELECTABLE_CLASS);\n\n // Create input\n const selectOne = document.createElement(\"input\");\n // Alias row id for easy retrieval in getSelection\n selectOne.dataset.id = tr.getAttribute(\"aria-rowindex\");\n selectOne.type = \"checkbox\";\n selectOne.classList.add(CHECKBOX_CLASS);\n // Label need to take full space thanks to css to make the whole cell clickable\n const label = document.createElement(\"label\");\n label.classList.add(\"dg-clickable-cell\");\n label.appendChild(selectOne);\n td.appendChild(label);\n\n // Prevent unwanted click behaviour on row\n label.addEventListener(\"click\", this);\n\n tr.appendChild(td);\n }\n\n /**\n * @param {Event} e\n */\n onclick(e) {\n e.stopPropagation();\n }\n\n /**\n * Handle change event on select all or any select checkbox in the table body\n * @param {import(\"../utils/shortcuts.js\").FlexibleEvent} e\n */\n onchange(e) {\n const grid = this.grid;\n if (hasClass(e.target, SELECT_ALL_CLASS)) {\n const visibleOnly = grid.options.selectVisibleOnly;\n const inputs = findAll(grid, `tbody .${SELECTABLE_CLASS} input`);\n for (const cb of inputs) {\n if (visibleOnly && !cb.offsetWidth) {\n return;\n }\n cb.checked = this.selectAll.checked;\n }\n dispatch(grid, \"rowsSelected\", {\n selection: this.getSelection(),\n });\n } else {\n if (!e.target.closest(`.${SELECTABLE_CLASS}`)) {\n return;\n }\n const totalCheckboxes = findAll(grid, `tbody .${SELECTABLE_CLASS} input[type=checkbox]`);\n // @ts-ignore\n const totalChecked = totalCheckboxes.filter((n) => n.checked);\n this.selectAll.checked = totalChecked.length === totalCheckboxes.length;\n\n dispatch(grid, \"rowsSelected\", {\n selection: grid.getSelection(),\n });\n }\n }\n}\n\nexport default SelectableRows;\n", "import BasePlugin from \"../core/base-plugin.js\";\nimport { setAttribute } from \"../utils/shortcuts.js\";\n\n/**\n * Support for fixed table height\n *\n * We should add a fake row to push the footer down in case we don't have enough rows\n */\nclass FixedHeight extends BasePlugin {\n constructor(grid) {\n super(grid);\n\n this.hasFixedHeight = false;\n // If we have a fixed height, make sure we have overflowY set\n if (grid.style.height) {\n grid.style.overflowY = \"auto\";\n this.hasFixedHeight = true;\n }\n }\n\n /**\n */\n createFakeRow() {\n const grid = this.grid;\n const tbody = grid.querySelector(\"tbody\");\n const tr = document.createElement(\"tr\");\n setAttribute(tr, \"role\", \"row\");\n setAttribute(tr, \"hidden\", \"\");\n tr.classList.add(\"dg-fake-row\");\n tr.tabIndex = 0;\n tbody.appendChild(tr);\n }\n\n get fakeRow() {\n return this.grid.querySelector(\".dg-fake-row\");\n }\n\n /**\n * On last page, use a fake row to push footer down\n */\n updateFakeRow() {\n const grid = this.grid;\n const fakeRow = this.fakeRow;\n if (!fakeRow) {\n return;\n }\n\n // We don't need a fake row if we display everything\n if (grid.options.perPage > grid.totalRecords()) {\n return;\n }\n // We are not on last page\n if (grid.page !== grid.totalPages()) {\n return;\n }\n if (!grid.options.autoheight) {\n return;\n }\n // Find remaining missing height\n const max = grid.options.perPage * grid.rowHeight;\n const visibleRows = grid.querySelectorAll(\"tbody tr:not([hidden])\").length;\n const fakeHeight = visibleRows > 1 ? max - visibleRows * grid.rowHeight : max;\n if (fakeHeight > 0) {\n setAttribute(fakeRow, \"height\", fakeHeight);\n fakeRow.removeAttribute(\"hidden\");\n } else {\n fakeRow.removeAttribute(\"height\");\n }\n }\n}\n\nexport default FixedHeight;\n", "import BasePlugin from \"../core/base-plugin.js\";\nimport getTextWidth from \"../utils/getTextWidth.js\";\nimport { getAttribute, hasAttribute, setAttribute } from \"../utils/shortcuts.js\";\n\n/**\n * Allows to resize columns\n */\nclass AutosizeColumn extends BasePlugin {\n /**\n * Autosize col based on column data\n * @param {HTMLTableCellElement} th\n * @param {import(\"../data-grid\").Column} column\n * @param {Number} min\n * @param {Number} max\n * @returns {Number}\n */\n computeSize(th, column, min, max) {\n const grid = this.grid;\n if (hasAttribute(th, \"width\")) {\n return getAttribute(th, \"width\");\n }\n if (!grid.data.length) {\n return;\n }\n const firstVal = grid.data[0];\n const lastVal = grid.data[grid.data.length - 1];\n let v = firstVal[column.field] ? firstVal[column.field].toString() : \"\";\n const v2 = lastVal[column.field] ? lastVal[column.field].toString() : \"\";\n if (v2.length > v.length) {\n v = v2;\n }\n let width = 0;\n if (v.length <= 6) {\n width = min;\n } else if (v.length > 50) {\n width = max;\n } else {\n // Add some extra room to have some spare space\n width = getTextWidth(`${v}0000`, th);\n }\n if (width > max) {\n width = max;\n }\n if (width < min) {\n width = min;\n }\n setAttribute(th, \"width\", width);\n return width;\n }\n}\n\nexport default AutosizeColumn;\n", "import BasePlugin from \"../core/base-plugin.js\";\nimport debounce from \"../utils/debounce.js\";\nimport {\n addClass,\n ce,\n find,\n findAll,\n hasClass,\n insertAfter,\n removeAttribute,\n removeClass,\n setAttribute,\n} from \"../utils/shortcuts.js\";\n\nconst RESPONSIVE_CLASS = \"dg-responsive\";\n\nlet obsTo;\n\n/**\n * @param {Array} list\n * @returns {Array}\n */\nfunction sortByPriority(list) {\n return list.sort((a, b) => {\n const v1 = Number.parseInt(a.dataset.responsive) || 1;\n const v2 = Number.parseInt(b.dataset.responsive) || 1;\n return v2 - v1;\n });\n}\n\n/**\n * @type {ResizeObserverCallback}\n */\n//@ts-ignore\nconst callback = debounce((entries) => {\n for (const entry of entries) {\n /**\n * @type {import(\"../data-grid\").default}\n */\n // @ts-ignore\n const grid = entry.target;\n const table = grid.table;\n if (grid.plugins.ResponsiveGrid.observerBlocked) {\n return;\n }\n // check inlineSize (width) and not blockSize (height)\n const contentBoxSize = Array.isArray(entry.contentBoxSize) ? entry.contentBoxSize[0] : entry.contentBoxSize;\n const size = Number.parseInt(contentBoxSize.inlineSize);\n const tableWidth = table.offsetWidth;\n const realTableWidth = findAll(grid.headerRow, \"th\").reduce((result, th) => {\n return result + th.offsetWidth;\n }, 0);\n const diff = (realTableWidth || tableWidth) - size - 1;\n const minWidth = 50;\n const prevAction = grid.plugins.ResponsiveGrid.prevAction;\n // We have an array with the columns to show/hide are in order, most important first\n const headerCols = sortByPriority(\n findAll(grid.headerRow, \"th[field]\")\n .reverse() // Order takes precedence if no priority is set\n .filter((col) => {\n // Leave out unresponsive columns\n return col.dataset.responsive !== \"0\";\n }),\n );\n let changed = false;\n\n grid.log(`table is ${tableWidth}/${realTableWidth} and available size is ${size}. Diff: ${diff}`);\n\n // The table is too big when diff has a high value, otherwise it will be like -1 or -2\n if (diff > 0) {\n if (prevAction === \"show\") {\n return;\n }\n grid.plugins.ResponsiveGrid.prevAction = \"hide\";\n let remaining = diff;\n let cols = headerCols.filter((col) => {\n return !col.hasAttribute(\"hidden\") && col.hasAttribute(\"data-responsive\");\n });\n if (cols.length === 0) {\n cols = headerCols.filter((col) => {\n return !col.hasAttribute(\"hidden\");\n });\n // Always keep one column\n if (cols.length === 1) {\n return;\n }\n }\n\n for (const col of cols) {\n if (remaining < 0) {\n continue;\n }\n\n const colWidth = col.offsetWidth;\n const field = col.getAttribute(\"field\");\n if (!field) {\n continue;\n }\n col.dataset.baseWidth = `${col.offsetWidth}`;\n\n grid.hideColumn(field, false);\n grid.setColProp(field, \"responsiveHidden\", true);\n changed = true;\n\n remaining -= colWidth;\n remaining = Math.round(remaining);\n }\n } else {\n if (prevAction === \"hide\") {\n return;\n }\n grid.plugins.ResponsiveGrid.prevAction = \"show\";\n\n const requiredWidth =\n headerCols\n .filter((col) => {\n return !col.hasAttribute(\"hidden\");\n })\n .reduce((result, col) => {\n const width = col.dataset.minWidth ? Number.parseInt(col.dataset.minWidth) : col.offsetWidth;\n return result + width;\n }, 0) + minWidth; // Add an offset so that inserting column is smoother\n\n // Compute available width to insert columns\n let remaining = size - requiredWidth;\n // Do we have any hidden column that we can restore ?\n const filteredHeaderCols = headerCols\n .slice()\n .reverse() // Reverse the array to restore the columns in the proper order\n .filter((col) => {\n return col.hasAttribute(\"hidden\");\n });\n\n for (const col of filteredHeaderCols) {\n if (remaining < minWidth) {\n continue;\n }\n const colWidth = Number.parseInt(col.dataset.minWidth);\n\n // We need to have enough space to restore it\n if (colWidth > remaining) {\n remaining = -1; // break loop to keep restoring in order\n continue;\n }\n\n const field = col.getAttribute(\"field\");\n if (!field) {\n continue;\n }\n\n grid.showColumn(field, false);\n grid.setColProp(field, \"responsiveHidden\", false);\n changed = true;\n\n remaining -= colWidth;\n remaining = Math.round(remaining);\n }\n }\n\n // Check footer\n const footer = find(grid.table, \"tfoot\");\n const realFooterWidth = findAll(grid.table, \".dg-footer > div\").reduce((result, div) => {\n return result + div.offsetWidth;\n }, 0);\n const availableFooterWidth = footer.offsetWidth - realFooterWidth;\n if (realFooterWidth > size) {\n addClass(footer, \"dg-footer-compact\");\n } else if (availableFooterWidth > 250) {\n removeClass(footer, \"dg-footer-compact\");\n }\n if (changed) {\n grid.renderTable();\n }\n // Prevent resize loop\n setTimeout(() => {\n grid.plugins.ResponsiveGrid.prevAction = null;\n }, 1000);\n grid.table.style.visibility = \"visible\";\n }\n}, 100);\nconst resizeObserver = new ResizeObserver(callback);\n\n/**\n * Responsive data grid\n */\nclass ResponsiveGrid extends BasePlugin {\n constructor(grid) {\n super(grid);\n\n this.observerBlocked = false;\n this.prevAction = null;\n }\n\n connected() {\n if (this.grid.options.responsive) {\n this.observe();\n }\n }\n\n disconnected() {\n this.unobserve();\n }\n\n observe() {\n if (!this.grid.options.responsive) {\n return;\n }\n resizeObserver.observe(this.grid);\n this.grid.style.display = \"block\"; // Otherwise resize doesn't happen\n this.grid.style.overflowX = \"hidden\"; // Prevent scrollbars from appearing\n }\n\n unobserve() {\n resizeObserver.unobserve(this.grid);\n this.grid.style.display = \"unset\";\n this.grid.style.overflowX = \"unset\";\n }\n\n blockObserver() {\n this.observerBlocked = true;\n if (obsTo) {\n clearTimeout(obsTo);\n }\n }\n\n unblockObserver() {\n obsTo = setTimeout(() => {\n this.observerBlocked = false;\n }, 200); // more than debounce\n }\n\n /**\n * @returns {Boolean}\n */\n hasHiddenColumns() {\n let flag = false;\n\n for (const col of this.grid.options.columns) {\n if (col.responsiveHidden) {\n flag = true;\n }\n }\n return flag;\n }\n\n colIndex() {\n return this.grid.startColIndex() - 1;\n }\n\n /**\n * @param {HTMLTableRowElement} tr\n */\n createHeaderCol(tr) {\n if (!this.grid.options.responsiveToggle) {\n return;\n }\n const th = ce(\"th\", tr);\n setAttribute(th, \"scope\", \"col\");\n setAttribute(th, \"role\", \"columnheader button\");\n setAttribute(th, \"aria-colindex\", this.colIndex());\n setAttribute(th, \"width\", \"40\");\n th.classList.add(...[`${RESPONSIVE_CLASS}-toggle`, \"dg-not-resizable\", \"dg-not-sortable\"]);\n th.tabIndex = 0;\n }\n\n /**\n * @param {HTMLTableRowElement} tr\n */\n createFilterCol(tr) {\n if (!this.grid.options.responsiveToggle) {\n return;\n }\n const th = ce(\"th\", tr);\n setAttribute(th, \"role\", \"columnheader button\");\n setAttribute(th, \"aria-colindex\", this.colIndex());\n th.classList.add(`${RESPONSIVE_CLASS}-toggle`);\n th.tabIndex = 0;\n }\n\n /**\n * @param {HTMLTableRowElement} tr\n */\n createDataCol(tr) {\n if (!this.grid.options.responsiveToggle) {\n return;\n }\n // Create col\n const td = document.createElement(\"td\");\n setAttribute(td, \"role\", \"gridcell button\");\n setAttribute(td, \"aria-colindex\", this.colIndex());\n td.classList.add(`${RESPONSIVE_CLASS}-toggle`);\n\n // Create icon\n td.innerHTML = `\n
`;\n tr.appendChild(td);\n\n td.addEventListener(\"click\", this);\n td.addEventListener(\"mousedown\", this);\n }\n\n computeLabelWidth() {\n let idealWidth = 0;\n let consideredCol = 0;\n while (idealWidth < 120) {\n consideredCol++;\n const hCol = find(this.grid, `.dg-head-columns th[aria-colindex=\"${consideredCol}\"]`);\n if (hCol) {\n idealWidth += hCol.offsetWidth;\n } else {\n break;\n }\n }\n return idealWidth;\n }\n\n /**\n * @param {Event} ev\n */\n onmousedown(ev) {\n // Avoid selection through double click\n ev.preventDefault();\n }\n\n /**\n * @param {Event} ev\n */\n onclick(ev) {\n // Prevent expandable\n ev.stopPropagation();\n\n // target is the element that triggered the event (e.g., the user clicked on)\n // currentTarget is the element that the event listener is attached to.\n\n /**\n * @type {HTMLTableRowElement}\n */\n //@ts-ignore\n const td = ev.currentTarget;\n const tr = td.parentElement;\n const open = find(td, `.${RESPONSIVE_CLASS}-open`);\n const close = find(td, `.${RESPONSIVE_CLASS}-close`);\n\n this.blockObserver();\n\n const isExpanded = hasClass(tr, `${RESPONSIVE_CLASS}-expanded`);\n if (isExpanded) {\n removeClass(tr, `${RESPONSIVE_CLASS}-expanded`);\n open.style.display = \"unset\";\n close.style.display = \"none\";\n\n // Move back rows and cleanup row\n const childRow = tr.nextElementSibling;\n const hiddenCols = findAll(childRow, `.${RESPONSIVE_CLASS}-hidden`);\n\n for (const col of hiddenCols) {\n // We don't really need to care where we insert them since we are going to redraw anyway\n tr.appendChild(col);\n setAttribute(col, \"hidden\");\n }\n\n childRow.parentElement.removeChild(childRow);\n } else {\n addClass(tr, `${RESPONSIVE_CLASS}-expanded`);\n open.style.display = \"none\";\n close.style.display = \"unset\";\n\n // Create a child row and move rows into it\n const childRow = ce(\"tr\");\n insertAfter(childRow, tr);\n addClass(childRow, `${RESPONSIVE_CLASS}-child-row`);\n\n const childRowTd = ce(\"td\", childRow);\n setAttribute(childRowTd, \"colspan\", this.grid.columnsLength(true));\n\n const childTable = ce(\"table\", childRowTd);\n addClass(childTable, `${RESPONSIVE_CLASS}-table`);\n\n const hiddenCols = findAll(tr, `.${RESPONSIVE_CLASS}-hidden`);\n const idealWidth = this.computeLabelWidth();\n\n for (const col of hiddenCols) {\n const childTableRow = ce(\"tr\", childTable);\n\n // Add label\n const label = col.dataset.name;\n const labelCol = ce(\"th\", childTableRow);\n // It looks much better when aligned with an actual col\n labelCol.style.width = `${idealWidth}px`;\n labelCol.innerHTML = label;\n\n // Add actual row\n childTableRow.appendChild(col);\n removeAttribute(col, \"hidden\");\n }\n }\n\n this.unblockObserver();\n }\n}\n\nexport default ResponsiveGrid;\n", "import BasePlugin from \"../core/base-plugin.js\";\nimport interpolate from \"../utils/interpolate.js\";\nimport { dispatch, on, setAttribute } from \"../utils/shortcuts.js\";\n\n/**\n * Add action on rows\n */\nclass RowActions extends BasePlugin {\n /**\n * @returns {Boolean}\n */\n hasActions() {\n return this.grid.options.actions.length > 0;\n }\n\n /**\n *\n * @param {HTMLTableRowElement} tr\n */\n makeActionHeader(tr) {\n const actionsTh = document.createElement(\"th\");\n setAttribute(actionsTh, \"role\", \"columnheader button\");\n setAttribute(actionsTh, \"aria-colindex\", this.grid.columnsLength(true));\n actionsTh.classList.add(...[\"dg-actions\", \"dg-not-sortable\", \"dg-not-resizable\", this.actionClass]);\n actionsTh.tabIndex = 0;\n tr.appendChild(actionsTh);\n }\n\n /**\n *\n * @param {HTMLTableRowElement} tr\n */\n makeActionFilter(tr) {\n const actionsTh = document.createElement(\"th\");\n actionsTh.setAttribute(\"role\", \"columnheader button\");\n setAttribute(actionsTh, \"aria-colindex\", this.grid.columnsLength(true));\n actionsTh.classList.add(...[\"dg-actions\", this.actionClass]);\n actionsTh.tabIndex = 0;\n tr.appendChild(actionsTh);\n }\n\n /**\n * @param {HTMLTableRowElement} tr\n * @param {Object} item\n */\n makeActionRow(tr, item) {\n const labels = this.grid.labels;\n const td = document.createElement(\"td\");\n setAttribute(td, \"role\", \"gridcell\");\n setAttribute(td, \"aria-colindex\", this.grid.columnsLength(true));\n td.classList.add(...[\"dg-actions\", this.actionClass]);\n td.tabIndex = 0;\n\n // Add menu toggle\n const actionsToggle = document.createElement(\"button\");\n actionsToggle.classList.add(\"dg-actions-toggle\");\n actionsToggle.innerHTML = \"\u2630\";\n td.appendChild(actionsToggle);\n on(actionsToggle, \"click\", (ev) => {\n ev.stopPropagation();\n ev.target.parentElement.classList.toggle(\"dg-actions-expand\");\n });\n\n for (const action of this.grid.options.actions) {\n const button = document.createElement(\"button\");\n if (action.html) {\n button.innerHTML = action.html;\n } else {\n button.innerText = action.title ?? action.name;\n }\n if (action.title) {\n button.title = action.title;\n }\n if (action.url) {\n button.type = \"submit\";\n button.formAction = interpolate(action.url, item);\n }\n if (action.class) {\n button.classList.add(...action.class.split(\" \"));\n }\n const actionHandler = (ev) => {\n ev.stopPropagation();\n if (action.confirm) {\n const c = confirm(labels.areYouSure);\n if (!c) {\n ev.preventDefault();\n return;\n }\n }\n dispatch(this.grid, \"action\", {\n data: item,\n action: action.name,\n });\n };\n button.addEventListener(\"click\", actionHandler);\n td.appendChild(button);\n\n // Row action\n if (action.default) {\n tr.classList.add(\"dg-actionable\");\n tr.addEventListener(\"click\", actionHandler);\n }\n }\n\n tr.appendChild(td);\n }\n\n get actionClass() {\n if (this.grid.options.actions.length < 3 && !this.grid.options.collapseActions) {\n return `dg-actions-${this.grid.options.actions.length}`;\n }\n return \"dg-actions-more\";\n }\n}\n\nexport default RowActions;\n", "import BasePlugin from \"../core/base-plugin.js\";\nimport { dispatch } from \"../utils/shortcuts.js\";\n\n/**\n * Make editable inputs in rows\n */\nclass EditableColumn extends BasePlugin {\n /**\n *\n * @param {HTMLTableCellElement} td\n * @param {import(\"../data-grid\").Column} column\n * @param {Object} item\n * @param {number} i\n */\n makeEditableInput(td, column, item, i) {\n const gridId = this.grid.getAttribute(\"id\");\n const input = document.createElement(\"input\");\n input.type = column.editableType || \"text\";\n if (input.type === \"email\") {\n input.inputMode = \"email\";\n }\n if (input.type === \"decimal\") {\n input.type = \"text\";\n input.inputMode = \"decimal\";\n }\n input.autocomplete = \"off\";\n input.spellcheck = false;\n input.tabIndex = 0;\n input.classList.add(\"dg-editable\");\n input.name = `${gridId.replace(\"-\", \"_\")}[${i + 1}][${column.field}]`;\n input.value = item[column.field];\n input.dataset.field = column.field;\n\n // Prevent row action\n input.addEventListener(\"click\", (ev) => ev.stopPropagation());\n // Enter validates edit\n input.addEventListener(\"keypress\", (ev) => {\n if (ev.type === \"keypress\") {\n const key = ev.keyCode || ev.key;\n if (key === 13 || key === \"Enter\") {\n input.blur();\n ev.preventDefault();\n }\n }\n });\n // Save on blur\n input.addEventListener(\"blur\", () => {\n // Only fire on update\n if (input.value === item[input.dataset.field]) {\n return;\n }\n // Update underlying data\n item[input.dataset.field] = input.value;\n // Notify\n dispatch(this.grid, \"edit\", {\n data: item,\n value: input.value,\n });\n });\n td.appendChild(input);\n }\n}\n\nexport default EditableColumn;\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport { $ } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Adds an element for showing a spinning icon on grid loading.\r\n */\r\nclass SpinnerSupport extends BasePlugin {\r\n connected() {\r\n // Inserts spinner\r\n if (this.grid.options.spinnerClass && this.grid.plugins.SpinnerSupport) {\r\n this.add();\r\n }\r\n }\r\n\r\n /**\r\n * Adds a spinner element with its associated css styles.\r\n */\r\n add() {\r\n const grid = this.grid;\r\n const classes = grid.options.spinnerClass;\r\n if (!classes) {\r\n return;\r\n }\r\n const cls = classes\r\n .split(\" \")\r\n .map((e) => `.${e}`)\r\n .join(\"\");\r\n\r\n const template = `\r\n\r\n`;\r\n if (!$(\"#dg-styles\")) {\r\n const styleParent = $(\"head\") ?? $(\"body\");\r\n const position = /head/i.test(styleParent.tagName) ? \"beforeend\" : \"afterbegin\";\r\n styleParent.insertAdjacentHTML(position, template);\r\n }\r\n !$(`i${cls}`, grid) && grid.insertAdjacentHTML(\"afterbegin\", ``);\r\n }\r\n}\r\n\r\nexport default SpinnerSupport;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport { findAll } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * @typedef GridState\r\n * @property {Object} meta\r\n * @property {Number} pages\r\n * @property {Number} page\r\n * @property {Number} perPage\r\n * @property {Object} filters\r\n * @property {Array} columns\r\n * @property {String} sort\r\n * @property {String} sortDir\r\n * @property {Number} scrollTo\r\n */\r\n\r\nclass SaveState extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n this.cachedState = null;\r\n this.isFilterSortSet = false;\r\n this.isDataLoaded = false;\r\n this.isScrolled = false;\r\n this.log(\"Init\");\r\n }\r\n\r\n connected() {\r\n this.log(\"connected\");\r\n const grid = this.grid;\r\n\r\n this.log(grid.options);\r\n\r\n if (!grid.options.saveState) {\r\n this.log(\"disabled\");\r\n return;\r\n }\r\n\r\n this.log(\"enabled\");\r\n\r\n const cachedState = this._getState();\r\n if (cachedState) {\r\n this.log(\"hide columns\");\r\n\r\n for (const col of cachedState.columns) {\r\n if (col.hidden) {\r\n const hideCol = grid.options.columns.find((c) => c.field === col.field);\r\n hideCol.hidden = true;\r\n }\r\n }\r\n\r\n this.log(\"set: meta, pages\");\r\n grid.options.perPage = cachedState.perPage;\r\n if (grid.options.server) {\r\n grid.meta = cachedState.meta;\r\n grid.pages = cachedState.pages;\r\n grid.page = cachedState.page;\r\n }\r\n }\r\n\r\n this.cachedState = cachedState;\r\n this.log(\"cachedState\", this.cachedState);\r\n\r\n setTimeout(() => {\r\n const dgLoadData = grid.loadData;\r\n grid.loadData = function (...args) {\r\n return dgLoadData.apply(this, args).finally(() => {\r\n const saveState = this.plugins.SaveState;\r\n saveState.log(\"loadData\", this.options.columns);\r\n\r\n if (!grid.classList.contains(\"dg-initialized\")) {\r\n saveState.log(\"not init, loadData skipped\");\r\n return;\r\n }\r\n\r\n saveState.log(\"loadData finished, set param controls\", this.options.columns);\r\n\r\n if (saveState.cachedState && !saveState.isFilterSortSet) {\r\n saveState.log(\"set sort and filters\");\r\n\r\n const sortableHeaders = findAll(grid, \"thead tr.dg-head-columns th[aria-sort]\");\r\n for (const el of sortableHeaders) {\r\n el.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n\r\n grid.querySelector(`thead tr.dg-head-columns th[field='${saveState.cachedState.sort}']`)\r\n ?.setAttribute(\"aria-sort\", saveState.cachedState.sortDir);\r\n\r\n const filters = findAll(grid.filterRow, \"[id^=dg-filter]\");\r\n saveState.log(\"filters\", filters);\r\n\r\n for (const el of filters) {\r\n el.value = saveState?.cachedState?.filters?.[el.dataset.name] ?? \"\";\r\n saveState.log({ name: el.dataset.name, val: el.value, saveState });\r\n }\r\n saveState.isFilterSortSet = true;\r\n }\r\n\r\n /** @type {GridState} */\r\n const newState = {\r\n meta: grid.meta,\r\n pages: grid.pages,\r\n page: grid.page,\r\n perPage: grid.options.perPage,\r\n filters: {},\r\n columns: grid.options.columns.map((col) => ({ field: col.field, hidden: col.hidden })),\r\n sort: grid.getSort(),\r\n sortDir: grid.getSortDir(),\r\n scrollTo: window.scrollY,\r\n };\r\n\r\n const filters = grid.getFilters();\r\n saveState.log(\"filters\", filters);\r\n\r\n for (const key of Object.keys(filters)) {\r\n newState.filters[key] = filters[key] ?? \"\";\r\n saveState.log({ key, val: filters[key], newState, filters });\r\n }\r\n\r\n saveState.log(\"store new state\", newState);\r\n saveState._setState(newState);\r\n\r\n if (!grid.options.server && saveState.cachedState && !saveState.isDataLoaded) {\r\n saveState.isDataLoaded = true;\r\n grid.filterData();\r\n grid.page = saveState.cachedState.page;\r\n grid.pageChanged();\r\n saveState.log(\"data loaded\");\r\n }\r\n });\r\n };\r\n }, 0);\r\n\r\n const updateState = () => {\r\n const saveState = grid.plugins.SaveState;\r\n const state = saveState._getState();\r\n if (!state) {\r\n return;\r\n }\r\n state.columns = grid.options.columns.map((col) => ({ field: col.field, hidden: col.hidden }));\r\n state.sort = grid.getSort();\r\n state.sortDir = grid.getSortDir();\r\n state.scrollTo = window.scrollY;\r\n saveState._setState(state);\r\n };\r\n\r\n document.addEventListener(\"scrollend\", updateState);\r\n grid.addEventListener(\"headerRendered\", updateState);\r\n\r\n grid.addEventListener(\"bodyRendered\", (ev) => {\r\n if (!grid.classList.contains(\"dg-initialized\") || grid.classList.contains(\"dg-loading\")) {\r\n return;\r\n }\r\n\r\n if (!grid.options.server) {\r\n updateState();\r\n }\r\n\r\n const saveState = grid.plugins.SaveState;\r\n if (!saveState.cachedState || !saveState.isFilterSortSet) {\r\n return;\r\n }\r\n\r\n if (!saveState.isDataLoaded) {\r\n saveState.isDataLoaded = true;\r\n grid.reload();\r\n saveState.log(\"***grid reloaded\");\r\n } else if (!saveState.isScrolled) {\r\n saveState.isScrolled = true;\r\n window.scrollTo({ top: saveState.cachedState.scrollTo, left: 0, behavior: \"instant\" });\r\n }\r\n });\r\n }\r\n\r\n log(...data) {\r\n this.grid.log(\"[Save-State] \", ...data);\r\n }\r\n\r\n /**\r\n * @returns {GridState}\r\n */\r\n _getState() {\r\n let state;\r\n try {\r\n state = JSON.parse(sessionStorage.getItem(`gridSaveState_${this.grid.id}`));\r\n } catch (_) {}\r\n return state;\r\n }\r\n\r\n /**\r\n * @param {GridState} state\r\n */\r\n _setState(state) {\r\n sessionStorage.setItem(`gridSaveState_${this.grid.id}`, JSON.stringify(state));\r\n }\r\n}\r\n\r\nexport default SaveState;\r\n", "/**\r\n * Data Grid custom element\r\n * https://github.com/lekoala/data-grid/\r\n * @license MIT\r\n */\r\n\r\nimport DataGrid from \"./src/data-grid.js\";\r\n// Optional plugins\r\nimport ColumnResizer from \"./src/plugins/column-resizer.js\";\r\nimport ContextMenu from \"./src/plugins/context-menu.js\";\r\nimport DraggableHeaders from \"./src/plugins/draggable-headers.js\";\r\nimport TouchSupport from \"./src/plugins/touch-support.js\";\r\nimport SelectableRows from \"./src/plugins/selectable-rows.js\";\r\nimport FixedHeight from \"./src/plugins/fixed-height.js\";\r\nimport AutosizeColumn from \"./src/plugins/autosize-column.js\";\r\nimport ResponsiveGrid from \"./src/plugins/responsive-grid.js\";\r\nimport RowActions from \"./src/plugins/row-actions.js\";\r\nimport EditableColumn from \"./src/plugins/editable-column.js\";\r\nimport SpinnerSupport from \"./src/plugins/spinner-support.js\";\r\nimport SaveState from \"./src/plugins/save-state.js\";\r\n\r\n// Using shorthand property names\r\n// This make them reserved and keys will be preserved\r\n// Actual class names are renamed\r\nDataGrid.registerPlugins({\r\n ColumnResizer,\r\n ContextMenu,\r\n DraggableHeaders,\r\n TouchSupport,\r\n SelectableRows,\r\n FixedHeight,\r\n AutosizeColumn,\r\n ResponsiveGrid,\r\n RowActions,\r\n EditableColumn,\r\n SpinnerSupport,\r\n SaveState\r\n});\r\n\r\n// Prevent errors if included multiple times\r\nif (!customElements.get(\"data-grid\")) {\r\n customElements.define(\"data-grid\", DataGrid);\r\n}\r\n\r\nexport default DataGrid;\r\n\r\nconst global = typeof globalThis !== \"undefined\" ? globalThis : self;\r\nglobal.DataGrid = DataGrid;"],
- "mappings": "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",
+ "sourcesContent": ["/**\r\n * @param {String} str\r\n * @returns {String}\r\n */\r\nexport default function camelize(str) {\r\n return str.toLowerCase().replace(/[^a-zA-Z0-9]+(.)/g, (m, chr) => chr.toUpperCase());\r\n}\r\n", "/**\r\n * Parse data attribute and return properly typed data\r\n * @param {String} v\r\n * @returns {any}\r\n */\r\nexport default function normalizeData(v) {\r\n // Bool\r\n if (v === \"true\") {\r\n return true;\r\n }\r\n if (v === \"false\") {\r\n return false;\r\n }\r\n // Null or empty\r\n if (v === \"\" || v === \"null\") {\r\n return null;\r\n }\r\n // Numeric attributes\r\n if (v === Number(v).toString()) {\r\n return Number(v);\r\n }\r\n // Only attempt json parsing for array or objects\r\n if (v && typeof v.substring === \"function\" && [\"[\", \"{\"].includes(v.substring(0, 1))) {\r\n try {\r\n // In case we have only single quoted values, like ['one', 'two', 'three']\r\n let val = v;\r\n if (val.indexOf('\"') === -1) {\r\n val = val.replace(/'/g, '\"');\r\n }\r\n return JSON.parse(decodeURIComponent(val));\r\n } catch {\r\n console.error(`Failed to parse ${v}`);\r\n return {};\r\n }\r\n }\r\n return v;\r\n}\r\n", "/**\r\n * @typedef FlexibleHTMLProps\r\n * @property {boolean} [checked] (HTMLInputElement)\r\n * @property {string} [value] (HTMLInputElement)\r\n * @property {number} [rowHeight] (HTMLTableRowElement)\r\n *\r\n * A flexible type HTMLElement type that does not require using instanceof all over the place\r\n * Make sure that your selector is indeed valid\r\n * Only includes most commons props\r\n * @typedef {HTMLElement & FlexibleHTMLProps} FlexibleHTMLElement\r\n */\r\n\r\n/**\r\n * Keep this as reference for easy documentation\r\n * @typedef {HTMLElement&HTMLInputElement&HTMLTableRowElement} MixedHTMLElement\r\n */\r\n\r\n/**\r\n * @typedef FlexibleEventProps\r\n * @property {FlexibleHTMLElement} target\r\n * @property {FlexibleHTMLElement} currentTarget\r\n * @property {DataTransfer} [dataTransfer] (DragEvent)\r\n * @property {number} [clientX] (MouseEvent)\r\n * @property {number} [clientY] (MouseEvent)\r\n *\r\n * @typedef {Event & FlexibleEventProps} FlexibleEvent\r\n */\r\n\r\n/**\r\n * Keep this as reference for easy documentation\r\n * @typedef {Event&MouseEvent&InputEvent&DragEvent&FocusEvent&KeyboardEvent&PointerEvent} MixedEvent\r\n */\r\n\r\n/**\r\n * @callback FlexibleListener\r\n * @param {FlexibleEvent} event\r\n */\r\n\r\nclass FlexibleEventListenerObject {\r\n /**\r\n * @param {FlexibleEvent} e\r\n */\r\n handleEvent(e) {}\r\n}\r\n\r\nconst supportedPassiveTypes = [\r\n \"scroll\",\r\n \"wheel\",\r\n \"touchstart\",\r\n \"touchmove\",\r\n \"touchenter\",\r\n \"touchend\",\r\n \"touchleave\",\r\n \"mouseout\",\r\n \"mouseleave\",\r\n \"mouseup\",\r\n \"mousedown\",\r\n \"mousemove\",\r\n \"mouseenter\",\r\n \"mousewheel\",\r\n \"mouseover\",\r\n];\r\n\r\n/**\r\n * Automatically set passive options based on type\r\n * @param {string} type\r\n * @returns {AddEventListenerOptions}\r\n */\r\nfunction passiveOpts(type) {\r\n if (supportedPassiveTypes.includes(type)) {\r\n return { passive: true };\r\n }\r\n return {};\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n * @returns {any}\r\n */\r\nexport function getAttribute(el, name) {\r\n return el.getAttribute(name);\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n * @returns {Boolean}\r\n */\r\nexport function hasAttribute(el, name) {\r\n return el.hasAttribute(name);\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n * @param {any} v\r\n * @param {Boolean} check Prevent setting if attribute is already there\r\n */\r\nexport function setAttribute(el, name, v = \"\", check = false) {\r\n if (check && hasAttribute(el, name)) return;\r\n el.setAttribute(name, `${v}`);\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n */\r\nexport function removeAttribute(el, name) {\r\n if (hasAttribute(el, name)) {\r\n el.removeAttribute(name);\r\n }\r\n}\r\n\r\n/**\r\n * @param {EventTarget} el\r\n * @param {String} type\r\n * @param {EventListenerObject|FlexibleListener} listener\r\n */\r\nexport function on(el, type, listener) {\r\n el.addEventListener(type, listener, passiveOpts(type));\r\n}\r\n\r\n/**\r\n * @param {EventTarget} el\r\n * @param {String} type\r\n * @param {EventListenerObject|FlexibleListener} listener\r\n */\r\nexport function off(el, type, listener) {\r\n el.removeEventListener(type, listener, passiveOpts(type));\r\n}\r\n\r\n/**\r\n * @param {EventTarget} el\r\n * @param {String} type\r\n * @param {EventListenerObject|FlexibleListener} listener\r\n */\r\nexport function one(el, type, listener) {\r\n el.addEventListener(type, listener, {\r\n once: true,\r\n });\r\n}\r\n\r\n/**\r\n * @param {HTMLElement} el\r\n * @param {String} name\r\n * @param {any} data\r\n * @param {Boolean} bubbles\r\n */\r\nexport function dispatch(el, name, data = {}, bubbles = false) {\r\n const opts = {};\r\n if (bubbles) {\r\n opts.bubbles = true;\r\n }\r\n if (data) {\r\n opts.detail = data;\r\n }\r\n el.dispatchEvent(new CustomEvent(name, opts));\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n * @returns {Boolean}\r\n */\r\nexport function hasClass(el, name) {\r\n return el.classList.contains(name);\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n */\r\nexport function addClass(el, name) {\r\n el.classList.add(...name.split(\" \"));\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n */\r\nexport function removeClass(el, name) {\r\n el.classList.remove(...name.split(\" \"));\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n */\r\nexport function toggleClass(el, name) {\r\n el.classList.toggle(name);\r\n}\r\n\r\n/**\r\n * @param {String|HTMLElement} selector\r\n * @param {HTMLElement|Document} base\r\n * @returns {FlexibleHTMLElement|null}\r\n */\r\nexport function $(selector, base = document) {\r\n if (selector instanceof HTMLElement) {\r\n return selector;\r\n }\r\n return base.querySelector(selector);\r\n}\r\n\r\n/**\r\n * @param {String} selector\r\n * @param {Element|Document} base\r\n * @returns {Array}\r\n */\r\nexport function $$(selector, base = document) {\r\n return Array.from(base.querySelectorAll(selector));\r\n}\r\n\r\n/**\r\n * Easily retrieve untyped element\r\n * For actual type, prefer use of el.querySelector\r\n * @param {HTMLElement} el\r\n * @param {String|HTMLElement} selector\r\n * @returns {FlexibleHTMLElement}\r\n */\r\nexport function find(el, selector) {\r\n return $(selector, el);\r\n}\r\n\r\n/**\r\n * Easily retrieve untyped elements\r\n * For actual type, prefer use of el.querySelectorAll\r\n * @param {Element} el\r\n * @param {String} selector\r\n * @returns {Array}\r\n */\r\nexport function findAll(el, selector) {\r\n return $$(selector, el);\r\n}\r\n\r\n/**\r\n * @param {*} el\r\n * @returns {FlexibleHTMLElement}\r\n */\r\nexport function el(el) {\r\n return el;\r\n}\r\n\r\n/**\r\n * @template {keyof HTMLElementTagNameMap} K\r\n * @param {K} tagName\r\n * @param {HTMLElement} parent\r\n * @returns {HTMLElementTagNameMap[K]}\r\n */\r\nexport function ce(tagName, parent = null) {\r\n const el = document.createElement(tagName);\r\n if (parent) {\r\n parent.appendChild(el);\r\n }\r\n return el;\r\n}\r\n\r\n/**\r\n * @param {HTMLElement} newNode\r\n * @param {HTMLElement} existingNode\r\n */\r\nexport function insertAfter(newNode, existingNode) {\r\n existingNode.parentNode.insertBefore(newNode, existingNode.nextSibling);\r\n}\r\n", "import camelize from \"../utils/camelize.js\";\r\nimport normalizeData from \"../utils/normalizeData.js\";\r\nimport { dispatch, getAttribute, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/** @typedef {import('../data-grid').Options} Options */\r\n\r\n/**\r\n * Base element that does not contain any specific logic\r\n * related to this project but makes HTMLElemnt usable\r\n */\r\nclass BaseElement extends HTMLElement {\r\n /**\r\n * @param {Object} options\r\n */\r\n constructor(options = {}) {\r\n super();\r\n\r\n /** @type {Options} */\r\n this.options = Object.assign({}, this.defaultOptions, this.normalizedDataset, options);\n\r\n this.log(\"constructor\");\r\n\r\n this.setup = false;\r\n this.fireEvents = true;\r\n this._ready();\r\n\r\n this.log(\"ready\");\r\n }\r\n\r\n get defaultOptions() {\r\n return {};\r\n }\r\n\r\n /**\r\n * @param {String} opt\r\n * @returns {any}\r\n */\r\n getOption(opt) {\r\n return this.options[opt];\r\n }\r\n\r\n /**\r\n * @param {String} opt\r\n * @param {any} v\r\n */\r\n setOption(opt, v) {\r\n setAttribute(this, `data-${opt}`, v);\r\n }\r\n\r\n /**\r\n * @param {String} opt\r\n */\r\n toggleOption(opt) {\r\n setAttribute(this, `data-${opt}`, !this.getOption(opt));\r\n }\r\n\r\n get normalizedDataset() {\r\n const jsonConfig = this.dataset.config ? JSON.parse(this.dataset.config) : {};\r\n const data = { ...this.dataset };\r\n for (const key in data) {\r\n if (key === \"config\" || !data.hasOwnProperty(key) || typeof data[key] === \"function\") {\r\n continue;\r\n }\r\n data[key] = normalizeData(data[key]);\r\n }\r\n // Once normalized, merge into json config\r\n Object.assign(data, jsonConfig);\r\n return data;\r\n }\r\n\r\n /**\r\n * @returns {String}\r\n */\r\n static template() {\r\n return \"\";\r\n }\r\n\r\n /**\r\n * This is called at the end of constructor. Extend in subclass if needed.\r\n */\r\n _ready() {}\r\n\r\n /**\r\n * @param {any[]} data\r\n */\r\n log(...data) {\r\n if (this.options.debug) {\r\n console.log(`[${getAttribute(this, \"id\")}] `, ...data);\r\n }\r\n }\r\n\r\n /**\r\n * Handle events within the component\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#handling-events\r\n * @param {Event} event\r\n */\r\n handleEvent(event) {\r\n if (this[`on${event.type}`]) {\r\n this[`on${event.type}`](event);\r\n }\r\n }\r\n\r\n /**\r\n * This is called when connected. Extend in subclass if needed.\r\n */\r\n _connected() {}\r\n\r\n connectedCallback() {\r\n // already connected\r\n if (this.setup) {\r\n return;\r\n }\r\n this.setup = true;\r\n // ensure whenDefined callbacks run first\r\n setTimeout(async () => {\r\n this.log(\"connectedCallback\");\r\n\r\n // Append only when labels had the opportunity to be set\r\n // Don't use shadow dom as it makes theming super hard\r\n const template = document.createElement(\"template\");\r\n // @ts-ignore\r\n template.innerHTML = this.constructor.template();\r\n this.appendChild(template.content.cloneNode(true));\r\n\n await this._connected();\n\r\n // @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#life-cycle-events\r\n dispatch(this, \"connected\");\r\n }, 0);\r\n }\r\n\r\n /**\r\n * This is called when disconnected. Extend in subclass if needed.\r\n */\r\n _disconnected() {}\r\n\r\n /**\r\n * @link https://nolanlawson.com/2024/12/01/avoiding-unnecessary-cleanup-work-in-disconnectedcallback/\r\n */\r\n disconnectedCallback() {\r\n setTimeout(() => {\r\n if (!this.isConnected && this.setup) {\r\n this.log(\"disconnectedCallback\");\r\n this._disconnected();\r\n // @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#life-cycle-events\r\n dispatch(this, \"disconnected\");\r\n this.setup = false;\r\n }\r\n }, 0);\r\n }\r\n\r\n /**\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#a-props-like-accessor\r\n * @returns {Object}\r\n */\r\n get transformAttributes() {\r\n return {};\r\n }\r\n\r\n /**\r\n * This is only meant to work with data attributes\r\n * This allows us to have properties that reflect automatically in the component\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#reflected-dataset-attributes\r\n * @param {String} attributeName\r\n * @param {String} oldValue\r\n * @param {String} newValue\r\n */\r\n attributeChangedCallback(attributeName, oldValue, newValue) {\r\n // It didn't change\r\n if (oldValue === newValue) {\r\n return;\r\n }\r\n\r\n this.log(`attributeChangedCallback: ${attributeName}`);\r\n\r\n let isOption = false;\r\n const transformer = this.transformAttributes[attributeName] ?? normalizeData;\r\n\r\n let attr = attributeName;\r\n // Data attributes are mapped to options while other attributes are mapped as properties\r\n if (attr.indexOf(\"data-\") === 0) {\r\n attr = attr.slice(5);\r\n isOption = true;\r\n }\r\n attr = camelize(attr);\r\n if (isOption) {\r\n this.options[attr] = transformer(newValue);\r\n } else {\r\n this[attr] = transformer(newValue);\r\n }\r\n\r\n // Fire internal event\r\n if (this.fireEvents && this[`${attr}Changed`]) {\r\n this[`${attr}Changed`]();\r\n }\r\n }\r\n}\r\n\r\nexport default BaseElement;\r\n", "/**\r\n * @param {HTMLSelectElement} el\r\n * @param {String} value\r\n * @param {String} label\r\n * @param {Boolean} checked\r\n */\r\nexport default function addSelectOption(el, value, label, checked = false) {\r\n const opt = document.createElement(\"option\");\r\n opt.value = `${value}`;\r\n if (checked) {\r\n opt.selected = true;\r\n }\r\n opt.label = label;\r\n el.appendChild(opt);\r\n}\r\n", "/**\r\n * @param {URL} url\r\n * @param {Object} params\r\n */\r\nexport default function appendParamsToUrl(url, params = {}) {\r\n for (const key of Object.keys(params)) {\r\n if (Array.isArray(params[key])) {\r\n for (const k of Object.keys(params[key])) {\r\n // @ts-ignore\r\n url.searchParams.append(isNaN(k) ? `${key}[${k}]` : key, params[key][k]);\r\n }\r\n } else {\r\n url.searchParams.append(key, params[key]);\r\n }\r\n }\r\n}\r\n", "/**\r\n * Force value as arrays\r\n * @param {String|Array} v\r\n * @returns {Array}\r\n */\r\nexport default function convertArray(v) {\r\n if (typeof v === \"string\") {\r\n if (v[0] === \"[\") {\r\n // \"['my', 'value']\" would fail as a json\r\n let bv = v;\r\n if (bv.indexOf('\"') === -1) {\r\n bv = bv.replace(/'/g, '\"');\r\n }\r\n return JSON.parse(bv);\r\n }\r\n\r\n return v.split(\",\");\r\n }\r\n if (!Array.isArray(v)) {\r\n console.error(\"Invalid array\", v);\r\n return [];\r\n }\r\n return v;\r\n}\r\n", "/**\r\n * @param {HTMLElement} el\r\n * @returns {Object}\r\n */\r\nexport default function elementOffset(el) {\r\n const rect = el.getBoundingClientRect();\r\n const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;\r\n const scrollTop = window.pageYOffset || document.documentElement.scrollTop;\r\n return { top: rect.top + scrollTop, left: rect.left + scrollLeft };\r\n}\r\n", "/**\r\n * Replace element within {} by their data value\r\n * @param {String} str\r\n * @param {Object} data\r\n * @returns {String}\r\n */\r\nexport default function interpolate(str, data) {\r\n return str.replace(/\\{([^}]+)?\\}/g, ($1, $2) => data[$2]);\r\n}\r\n", "let canvas;\r\n\r\n/**\r\n * Uses canvas.measureText to compute and return the width of the given text of given font in pixels.\r\n * Getting computed styles only works for dom that are added in the dom\r\n * @see https://stackoverflow.com/questions/118241/calculate-text-width-with-javascript/21015393#21015393\r\n * @param {String} text The text to be rendered.\r\n * @param {Element} el Target element (defaults to body)\r\n * @param {Boolean} withPadding Include padding on element\r\n * @returns {Number}\r\n */\r\nexport default function getTextWidth(text, el = document.body, withPadding = false) {\r\n const styles = window.getComputedStyle(el || document.createElement(\"div\"));\r\n const fontWeight = styles.getPropertyValue(\"font-weight\") || \"normal\";\r\n const fontSize = styles.getPropertyValue(\"font-size\") || \"1rem\";\r\n const fontFamily = styles.getPropertyValue(\"font-family\") || \"Arial\";\r\n\r\n let padding = 0;\r\n if (withPadding) {\r\n const paddingLeft = styles.getPropertyValue(\"padding-left\") || \"0\";\r\n const paddingRight = styles.getPropertyValue(\"padding-right\") || \"0\";\r\n padding = Number.parseInt(paddingLeft) + Number.parseInt(paddingRight);\r\n }\r\n\r\n // re-use canvas object for better performance\r\n if (!canvas) {\r\n canvas = document.createElement(\"canvas\");\r\n }\r\n const context = canvas.getContext(\"2d\");\r\n context.font = `${fontWeight} ${fontSize} ${fontFamily}`;\r\n const metrics = context.measureText(text);\r\n return Number.parseInt(metrics.width) + padding;\r\n}\r\n", "/**\r\n * @param {String} prefix\r\n * @returns {String}\r\n */\r\nexport default function randstr(prefix) {\r\n return Math.random()\r\n .toString(36)\r\n .replace(\"0.\", prefix || \"\");\r\n}\r\n", "/**\r\n * Define a function that can be happily passed to addEventListener\r\n * @typedef {Function & EventListenerOrEventListenerObject} ExtendedFunction\r\n */\r\n\r\n/**\r\n * @param {Function} handler\r\n * @param {Number} timeout\r\n * @returns {ExtendedFunction}\r\n */\r\nexport default function debounce(handler, timeout = 300) {\r\n let timer = null;\r\n return (...args) => {\r\n clearTimeout(timer);\r\n timer = setTimeout(() => {\r\n timer = null;\r\n handler(...args);\r\n }, timeout);\r\n };\r\n}\r\n", "/**\r\n * Data Grid Web component\r\n *\r\n * Credits for inspiration\r\n * @link https://github.com/riverside/zino-grid\r\n */\r\n\r\nimport BaseElement from \"./core/base-element.js\";\r\nimport addSelectOption from \"./utils/addSelectOption.js\";\r\nimport appendParamsToUrl from \"./utils/appendParamsToUrl.js\";\r\nimport camelize from \"./utils/camelize.js\";\r\nimport convertArray from \"./utils/convertArray.js\";\r\nimport elementOffset from \"./utils/elementOffset.js\";\r\nimport interpolate from \"./utils/interpolate.js\";\r\nimport getTextWidth from \"./utils/getTextWidth.js\";\r\nimport randstr from \"./utils/randstr.js\";\r\nimport debounce from \"./utils/debounce.js\";\r\nimport {\r\n $,\r\n $$,\r\n dispatch,\r\n find,\r\n findAll,\r\n hasClass,\r\n removeAttribute,\r\n getAttribute,\r\n setAttribute,\r\n addClass,\r\n toggleClass,\r\n on,\r\n ce,\r\n} from \"./utils/shortcuts.js\";\r\n\r\n/**\r\n * Column definition\r\n * @typedef Column\r\n * @property {String} field - the key in the data\r\n * @property {String} title - the title to display in the header (defaults to \"field\" if not set)\r\n * @property {Number} [width] - the width of the column (auto otherwise)\r\n * @property {String} [class] - class to set on the column (target body or header with th.class or td.class)\r\n * @property {String} [attr] - don't render the column and set a matching attribute on the row with the value of the field\r\n * @property {Boolean} [hidden] - hide the column\r\n * @property {Boolean} [noSort] - allow disabling sort for a given column\r\n * @property {String | Function} [format] - custom data formatting\r\n * @property {String} [defaultFormatValue] - default value to use for formatting\r\n * @property {String} [transform] - custom value transformation\r\n * @property {Boolean} [editable] - replace with input (EditableColumn module)\r\n * @property {String} [editableType] - type of input (EditableColumn module)\r\n * @property {Number} [responsive] - the higher the value, the sooner it will be hidden, disable with 0 (ResponsiveGrid module)\r\n * @property {Boolean} [responsiveHidden] - hidden through responsive module (ResponsiveGrid module)\r\n * @property {String} [filterType] - defines a filter field type (\"text\" or \"select\" - defaults to \"text\")\r\n * @property {Array} [filterList] - defines a custom array to populate a filter select field in the format of [{value: \"\", text: \"\"},...]. When defined, it overrides the default behaviour where the filter select elements are populated by the unique values from the corresponding column records.\r\n * @property {Object} [firstFilterOption] - defines an object for the first option element of the filter select field. defaults to {value: \"\", text: \"\"}\r\n */\r\n\r\n/**\r\n * Row action\r\n * @typedef Action\r\n * @property {String} title - the title of the button\r\n * @property {String} name - the name of the action\r\n * @property {String} class - the class for the button\r\n * @property {String} url - link for the action\r\n * @property {String} html - custom button data\r\n * @property {Boolean} [confirm] - needs confirmation\r\n * @property {Boolean} default - is the default row action\r\n */\r\n\r\n// Import definitions without importing the actual file\r\n/** @typedef {import('./plugins/autosize-column').default} AutosizeColumn */\r\n/** @typedef {import('./plugins/column-resizer').default} ColumnResizer */\r\n/** @typedef {import('./plugins/context-menu').default} ContextMenu */\r\n/** @typedef {import('./plugins/draggable-headers').default} DraggableHeaders */\r\n/** @typedef {import('./plugins/editable-column').default} EditableColumn */\r\n/** @typedef {import('./plugins/fixed-height').default} FixedHeight */\r\n/** @typedef {import('./plugins/responsive-grid').default} ResponsiveGrid */\r\n/** @typedef {import('./plugins/row-actions').default} RowActions */\r\n/** @typedef {import('./plugins/selectable-rows').default} SelectableRows */\r\n/** @typedef {import('./plugins/touch-support').default} TouchSupport */\r\n/** @typedef {import('./plugins/spinner-support').default} SpinnerSupport */\r\n/** @typedef {import('./plugins/save-state').default} SaveState */\r\n\r\n/**\r\n * These plugins are all optional\r\n * @typedef {Object} Plugins\r\n * @property {ColumnResizer} [ColumnResizer] resize handlers in the headers\r\n * @property {ContextMenu} [ContextMenu] menu to show/hide columns\r\n * @property {DraggableHeaders} [DraggableHeaders] draggable headers columns\r\n * @property {EditableColumn} [EditableColumn] draggable headers columns\r\n * @property {TouchSupport} [TouchSupport] touch swipe\r\n * @property {SelectableRows} [SelectableRows] create a column with checkboxes to select rows\r\n * @property {FixedHeight} [FixedHeight] allows having fixed height tables\r\n * @property {AutosizeColumn} [AutosizeColumn] compute ideal width based on column content\r\n * @property {ResponsiveGrid} [ResponsiveGrid] hide/show column on the fly\r\n * @property {RowActions} [RowActions] add action on rows\r\n * @property {SpinnerSupport} [SpinnerSupport] inserts a spinning icon element to indicate grid loading.\r\n * @property {SaveState} [SaveState] stores grid filter, sort, and paging.\r\n */\r\n\r\n/**\r\n * Parameters to pass along or receive from the server\r\n * @typedef ServerParams\r\n * @property {String} serverParams.start\r\n * @property {String} serverParams.length\r\n * @property {String} serverParams.search\r\n * @property {String} serverParams.sort\r\n * @property {String} serverParams.sortDir\r\n * @property {String} serverParams.dataKey\r\n * @property {String} serverParams.metaKey\r\n * @property {String} serverParams.metaTotalKey\r\n * @property {String} serverParams.metaFilteredKey\r\n * @property {String} serverParams.optionsKey\r\n * @property {String} serverParams.paramsKey\r\n */\r\n\r\n/**\r\n * Available data grid options, plugins included\r\n * @typedef Options\r\n * @property {?String} id Custom id for the grid\r\n * @property {?String} url An URL with data to display in JSON format\r\n * @property {Boolean} debug Log actions in DevTools console\r\n * @property {Boolean} filter Allows a filtering functionality\r\n * @property {Boolean} sort Allows a sort by column functionality\r\n * @property {String} defaultSort Default sort field if sorting is enabled\r\n * @property {Boolean} server Is a server side powered grid\r\n * @property {ServerParams} serverParams Describe keys passed to the server backend\r\n * @property {String} dir Dir\r\n * @property {Array} perPageValues Available per page options\r\n * @property {Boolean} hidePerPage Hides the page size select element\r\n * @property {Column[]} columns Available columns\r\n * @property {Number} defaultPage Starting page\r\n * @property {Number} perPage Number of records displayed per page (page size)\r\n * @property {Boolean} expand Allow cell content to spawn over multiple lines\r\n * @property {Action[]} actions Row actions (RowActions module)\r\n * @property {Boolean} collapseActions Group actions (RowActions module)\r\n * @property {Boolean} resizable Make columns resizable (ColumnResizer module)\r\n * @property {Boolean} selectable Allow multi-selecting rows with a checkboxes (SelectableRows module)\r\n * @property {Boolean} selectVisibleOnly Select all only selects visible rows (SelectableRows module)\r\n * @property {Boolean} singleSelect Enables single row select with radio buttons - no need to set selectable (SelectableRows module)\r\n * @property {Boolean} autosize Compute column sizes based on given data (Autosize module)\r\n * @property {Boolean} autoheight Adjust height so that it matches table size (FixedHeight module)\r\n * @property {Boolean} autohidePager auto-hides the pager when number of records falls below the selected page size\r\n * @property {Boolean} menu Right click menu on column headers (ContextMenu module)\r\n * @property {Boolean} reorder Allows a column reordering functionality (DraggableHeaders module)\r\n * @property {Boolean} responsive Change display mode on small screens (ResponsiveGrid module)\r\n * @property {Boolean} responsiveToggle Show toggle column (ResponsiveGrid module)\r\n * @property {Boolean} filterOnEnter Toggles the ability to filter column data by pressing the Enter or Return key\r\n * @property {String} spinnerClass Sets a space-delimited string of css classes for a spinner (use spinner-border css class for bootstrap 5 spinner)\r\n * @property {Number} filterKeypressDelay Sets a keypress delay time in milliseconds before triggering filter operation.\r\n * @property {Boolean} saveState Enable/disable save state plugin (SaveState module)\r\n * @property {?String} errorMessage A generic text to be displayed in footer when error occurs.\r\n * @property {?String} noData A custom text to be displayed when no data is loaded. This is different from the generic labels.noData that applies for data-grid as a component.\r\n */\r\n\r\n/**\r\n * Available labels that can be translated\r\n * @typedef Labels\r\n * @property {String} itemsPerPage\r\n * @property {String} gotoPage\r\n * @property {String} gotoFirstPage\r\n * @property {String} gotoPrevPage\r\n * @property {String} gotoNextPage\r\n * @property {String} gotoLastPage\r\n * @property {String} of\r\n * @property {String} items\r\n * @property {String} resizeColumn\r\n * @property {String} noData\r\n * @property {String} areYouSure\r\n * @property {String} networkError\r\n */\r\n\r\n/**\r\n * List of registered plugins\r\n * @type {Plugins}\r\n */\r\nlet plugins = {};\r\n\r\n/**\r\n * @type {Labels}\r\n */\r\nlet labels = {\r\n itemsPerPage: \"Items per page\",\r\n gotoPage: \"Go to page\",\r\n gotoFirstPage: \"Go to first page\",\r\n gotoPrevPage: \"Go to previous page\",\r\n gotoNextPage: \"Go to next page\",\r\n gotoLastPage: \"Go to last page\",\r\n of: \"of\",\r\n items: \"items\",\r\n resizeColumn: \"Resize column\",\r\n noData: \"No data\",\r\n areYouSure: \"Are you sure?\",\r\n networkError: \"Network response error\",\r\n};\r\n\r\n/**\r\n * Column definition will update some props on the html element\r\n * @param {HTMLElement} el\r\n * @param {Column} column\r\n */\r\nfunction applyColumnDefinition(el, column) {\r\n if (column.width) {\r\n setAttribute(el, \"width\", column.width);\r\n }\r\n if (column.class) {\r\n addClass(el, column.class);\r\n }\r\n if (column.hidden) {\r\n setAttribute(el, \"hidden\", \"\");\r\n if (column.responsiveHidden) {\r\n addClass(el, \"dg-responsive-hidden\");\r\n }\r\n }\r\n}\r\n\r\n/**\r\n */\r\nclass DataGrid extends BaseElement {\r\n _filterSelector = \"[id^=dg-filter]\";\n _excludedRowElementSelector = \"a,button,input,select,textarea\";\r\n _excludedKeys = [\r\n 37,\r\n 39,\r\n 38,\r\n 40,\r\n 45,\r\n 36,\r\n 35,\r\n 33,\r\n 34,\r\n 27,\r\n 20,\r\n 16,\r\n 17,\r\n 91,\r\n 92,\r\n 18,\r\n 93,\r\n 144,\r\n 231,\r\n \"ArrowLeft\",\r\n \"ArrowRight\",\r\n \"ArrowUp\",\r\n \"ArrowDown\",\r\n \"Insert\",\r\n \"Home\",\r\n \"End\",\r\n \"PageUp\",\r\n \"PageDown\",\r\n \"Escape\",\r\n \"CapsLock\",\r\n \"Shift\",\r\n \"Control\",\r\n \"Meta\",\r\n \"Alt\",\r\n \"ContextMenu\",\r\n \"NumLock\",\r\n \"Unidentified\",\r\n ];\n\r\n _ready() {\r\n setAttribute(this, \"id\", this.options.id ?? randstr(\"el-\"), true);\r\n\r\n /**\r\n * The grid displays that data\r\n * @type {Array}\r\n */\r\n this.data = [];\r\n /**\r\n * We store the original data in this\r\n * @type {Array}\r\n */\r\n this.originalData; // declared uninitialized to allow data preloading before fetch.\r\n\r\n // Make the IDE happy\r\n /**\r\n * @type {Options}\r\n */\r\n this.options = this.options || this.defaultOptions;\n if (this.options.singleSelect) this.options.selectable = true; // singleSelect implies selectable\r\n\r\n // Init values\r\n this.fireEvents = false;\r\n this.page = this.options.defaultPage || 1;\r\n this.pages = 0;\r\n this.meta; // declared uninitialized to allow data preloading before fetch.\r\n /**\r\n * @type {Plugins}\r\n */\r\n this.plugins = {};\r\n // Init plugins\r\n for (const [pluginName, pluginClass] of Object.entries(plugins)) {\r\n // @ts-ignore until we can set typeof import ...\r\n this.plugins[pluginName] = new pluginClass(this);\r\n }\r\n\r\n // Expose options as observed attributes in the dom\r\n // Do it when fireEvents is disabled to avoid firing change callbacks\r\n for (const attr of DataGrid.observedAttributes) {\r\n if (attr.indexOf(\"data-\") === 0) {\r\n setAttribute(this, attr, this.options[camelize(attr.slice(5))]);\r\n }\r\n }\r\n }\r\n\r\n static template() {\r\n return `\r\n\r\n \r\n |
\r\n
\r\n \r\n \r\n \r\n \r\n | \r\n \r\n | \r\n
\r\n \r\n \r\n
\r\n`;\r\n }\r\n\r\n /**\r\n * @returns {Labels}\r\n */\r\n get labels() {\r\n return labels;\r\n }\r\n\r\n /**\r\n * @returns {Labels}\r\n */\r\n static getLabels() {\r\n return labels;\r\n }\r\n\r\n /**\r\n * @param {Object} v\r\n */\r\n static setLabels(v) {\r\n labels = Object.assign(labels, v);\r\n }\n\r\n /** Gets the text to be displayed when no data is loaded. */\n get noData() {\n return this.options.noData || this.labels.noData;\r\n }\n\n /**\r\n * @param {HTMLTableSectionElement} tbody\r\n */\n #setNoData(tbody) {\n if (!this.hasDataError && tbody.getAttribute(\"data-empty\") !== this.noData) {\r\n tbody.setAttribute(\"data-empty\", this.noData);\r\n }\r\n }\n\r\n /**\r\n * @returns {Column}\r\n */\r\n get defaultColumn() {\r\n return {\r\n field: \"\",\r\n title: \"\",\r\n width: 0,\r\n class: \"\",\r\n attr: \"\",\r\n hidden: false,\r\n editable: false,\r\n noSort: false,\r\n responsive: 1,\r\n responsiveHidden: false,\r\n format: \"\",\r\n transform: \"\",\r\n filterType: \"text\",\r\n firstFilterOption: { value: \"\", text: \"\" },\r\n };\r\n }\r\n\r\n /**\r\n * @returns {Options}\r\n */\r\n get defaultOptions() {\r\n return {\r\n id: null,\r\n url: \"\",\r\n perPage: 10,\r\n debug: false,\r\n filter: false,\r\n menu: false,\r\n sort: false,\r\n server: false,\r\n serverParams: {\r\n start: \"start\",\r\n length: \"length\",\r\n search: \"search\",\r\n sort: \"sort\",\r\n sortDir: \"sortDir\",\r\n dataKey: \"data\",\r\n metaKey: \"meta\",\r\n metaTotalKey: \"total\",\r\n metaFilteredKey: \"filtered\",\r\n optionsKey: \"options\",\r\n paramsKey: \"params\",\r\n },\r\n defaultSort: \"\",\r\n reorder: false,\r\n dir: \"ltr\",\r\n perPageValues: [10, 25, 50, 100, 250],\r\n hidePerPage: false,\r\n columns: [],\r\n actions: [],\r\n collapseActions: false,\r\n selectable: false,\r\n selectVisibleOnly: true,\n singleSelect: false,\r\n defaultPage: 1,\r\n resizable: false,\r\n autosize: true,\r\n expand: false,\r\n autoheight: true,\r\n autohidePager: false,\r\n responsive: false,\r\n responsiveToggle: true,\r\n filterOnEnter: true,\r\n filterKeypressDelay: 500,\r\n spinnerClass: \"\",\r\n saveState: false,\r\n errorMessage: \"\",\n noData: \"\"\r\n };\r\n }\r\n\r\n /**\r\n * Determines if the grid is initialized.\r\n * @returns {Boolean}\r\n */\r\n get isInit() {\r\n return this.classList.contains(\"dg-initialized\");\r\n }\r\n\r\n /**\r\n * Determines if data load has failed.\r\n * @returns {Boolean}\r\n */\r\n get hasDataError() {\r\n return this.classList.contains(\"dg-network-error\");\r\n }\r\n\r\n /**\r\n * @param {Plugins} list\r\n */\r\n static registerPlugins(list) {\r\n plugins = list;\r\n }\r\n\r\n /**\r\n * @param {String} plugin\r\n */\r\n static unregisterPlugins(plugin = null) {\r\n if (plugin === null) {\r\n plugins = {};\r\n } else {\r\n delete plugins[plugin];\r\n }\r\n }\r\n\r\n /**\r\n * @returns {Plugins}\r\n */\r\n static registeredPlugins() {\r\n return plugins;\r\n }\r\n\r\n /**\r\n * @param {Object|Array} columns\r\n * @returns {Column[]}\r\n */\r\n convertColumns(columns) {\r\n const cols = [];\r\n // Convert key:value objects to actual columns\r\n if (typeof columns === \"object\" && !Array.isArray(columns)) {\r\n for (const key of Object.keys(columns)) {\r\n const col = Object.assign({}, this.defaultColumn);\r\n col.title = columns[key];\r\n col.field = key;\r\n cols.push(col);\r\n }\r\n } else {\r\n for (const item of columns) {\r\n let col = Object.assign({}, this.defaultColumn);\r\n if (typeof item === \"string\") {\r\n col.title = item;\r\n col.field = item;\r\n } else if (typeof item === \"object\") {\r\n col = Object.assign(col, item);\r\n if (!col.field) {\r\n console.error(\"Invalid column definition\", item);\r\n }\r\n if (!col.title) {\r\n col.title = col.field;\r\n }\r\n } else {\r\n console.error(\"Column definition must be a string or an object\");\r\n }\r\n cols.push(col);\r\n }\r\n }\r\n return cols;\r\n }\r\n\r\n /**\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#reflected-dom-attributes\r\n * @returns {Array}\r\n */\r\n static get observedAttributes() {\r\n return [\r\n \"page\",\r\n \"data-filter\",\r\n \"data-sort\",\r\n \"data-debug\",\r\n \"data-reorder\",\r\n \"data-menu\",\r\n \"data-selectable\",\n \"data-single-select\",\r\n \"data-url\",\r\n \"data-per-page\",\r\n \"data-responsive\",\r\n ];\r\n }\r\n\r\n get transformAttributes() {\r\n return {\r\n columns: (v) => this.convertColumns(convertArray(v)),\r\n actions: (v) => convertArray(v),\r\n defaultPage: (v) => Number.parseInt(v),\r\n perPage: (v) => Number.parseInt(v),\r\n };\r\n }\r\n\r\n /** @returns {HTMLTableSectionElement} */\r\n get thead() {\r\n //@ts-ignore\r\n return $(\"thead\", this);\r\n }\r\n\r\n /** @returns {HTMLTableSectionElement} */\r\n get tbody() {\r\n //@ts-ignore\r\n return $(\"tbody\", this);\r\n }\r\n\r\n /** @returns {HTMLTableSectionElement} */\r\n get tfoot() {\r\n //@ts-ignore\r\n return $(\"tfoot\", this);\r\n }\r\n\r\n get page() {\r\n return Number.parseInt(this.getAttribute(\"page\"));\r\n }\r\n\r\n set page(val) {\r\n setAttribute(this, \"page\", this.constrainPageValue(val));\r\n }\r\n\r\n /**\r\n * Loads data and configures the grid.\r\n * @param {Boolean} initOnly\r\n */\r\n urlChanged(initOnly = false) {\r\n if (initOnly && !this.isInit) return this;\r\n this.reconfig();\r\n return this.loadData().then(() => this.configureUi());\r\n }\r\n\r\n /**\r\n * Clears columns, re-renders table, and repopulates columns to ensure consistent column widths rendering.\r\n */\r\n reconfig() {\r\n const cols = this.options.columns;\r\n this.options.columns = [];\r\n this.configureUi();\r\n return this.options.columns = cols, this;\r\n }\r\n\r\n constrainPageValue(v) {\r\n let pv = v;\r\n if (this.pages < pv) {\r\n pv = this.pages;\r\n }\r\n if (pv < 1 || !pv) {\r\n pv = 1;\r\n }\r\n return pv;\r\n }\r\n\r\n fixPage() {\n if (!this.inputPage) return this;\r\n this.pages = this.totalPages();\r\n this.page = this.constrainPageValue(this.page);\r\n\r\n // Show current page in input\r\n setAttribute(this.inputPage, \"max\", this.pages);\r\n this.inputPage.value = `${this.page}`;\r\n return this.inputPage.disabled = this.pages < 2, this;\r\n }\r\n\r\n pageChanged() {\r\n this.reload();\r\n }\r\n\r\n responsiveChanged() {\r\n if (!this.plugins.ResponsiveGrid) {\r\n return;\r\n }\r\n if (this.options.responsive) {\r\n this.plugins.ResponsiveGrid.observe();\r\n } else {\r\n this.plugins.ResponsiveGrid.unobserve();\r\n }\r\n }\r\n\r\n menuChanged() {\r\n this.renderHeader();\r\n }\r\n\r\n /**\r\n * This is the callback for the select control\r\n */\r\n changePerPage() {\r\n this.options.perPage = Number.parseInt(this.selectPerPage.options[this.selectPerPage.selectedIndex].value);\r\n this.perPageChanged();\r\n }\r\n\r\n /**\r\n * This is the actual event triggered on attribute change\r\n */\r\n perPageChanged() {\r\n // Refresh UI\r\n if (\r\n this.options.perPage !== Number.parseInt(this.selectPerPage.options[this.selectPerPage.selectedIndex].value)\r\n ) {\r\n this.perPageValuesChanged();\r\n }\r\n // Make sure current page is still valid\r\n let updatePage = this.page;\r\n while (updatePage > 1 && this.page * this.options.perPage > this.totalRecords()) {\r\n updatePage--;\r\n }\r\n if (updatePage !== this.page) {\r\n // Triggers pageChanged, which will trigger reload\r\n this.page = updatePage;\r\n } else {\r\n // Simply reload current page\r\n this.reload(() => {\r\n // Preserve distance between top of page and select control if no fixed height\r\n if (!this.plugins.FixedHeight || !this.plugins.FixedHeight.hasFixedHeight) {\r\n this.selectPerPage.scrollIntoView();\r\n }\r\n });\r\n }\r\n }\r\n\r\n dirChanged() {\r\n setAttribute(this, \"dir\", this.options.dir);\r\n }\r\n\r\n defaultSortChanged() {\r\n this.sortChanged();\r\n }\r\n\r\n /**\r\n * Populate the select dropdown according to options\r\n */\r\n perPageValuesChanged() {\r\n if (!this.selectPerPage) {\r\n return;\r\n }\r\n while (this.selectPerPage.lastChild) {\r\n this.selectPerPage.removeChild(this.selectPerPage.lastChild);\r\n }\r\n for (const v of this.options.perPageValues) {\r\n addSelectOption(this.selectPerPage, v, v, v === this.options.perPage);\r\n }\r\n }\r\n\r\n async _connected() {\r\n /**\r\n * @type {HTMLTableElement}\r\n */\r\n this.table = this.querySelector(\"table\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnFirst = this.querySelector(\".dg-btn-first\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnPrev = this.querySelector(\".dg-btn-prev\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnNext = this.querySelector(\".dg-btn-next\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnLast = this.querySelector(\".dg-btn-last\");\r\n /**\r\n * @type {HTMLSelectElement}\r\n */\r\n this.selectPerPage = this.querySelector(\".dg-select-per-page\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.inputPage = this.querySelector(\".dg-input-page\");\r\n\r\n this.getFirst = this.getFirst.bind(this);\r\n this.getPrev = this.getPrev.bind(this);\r\n this.getNext = this.getNext.bind(this);\r\n this.getLast = this.getLast.bind(this);\r\n this.changePerPage = this.changePerPage.bind(this);\r\n this.gotoPage = this.gotoPage.bind(this);\r\n\r\n this.btnFirst.addEventListener(\"click\", this.getFirst);\r\n this.btnPrev.addEventListener(\"click\", this.getPrev);\r\n this.btnNext.addEventListener(\"click\", this.getNext);\r\n this.btnLast.addEventListener(\"click\", this.getLast);\r\n this.selectPerPage.addEventListener(\"change\", this.changePerPage);\r\n this.selectPerPage.toggleAttribute(\"hidden\", this.options.hidePerPage);\r\n this.inputPage.addEventListener(\"input\", this.gotoPage);\r\n\r\n for (const plugin of Object.values(this.plugins)) {\r\n await plugin.connected();\r\n }\r\n\r\n // Display even if we don't have data\r\n this.dirChanged();\r\n this.perPageValuesChanged();\r\n\n await this.init();\r\n }\r\n\r\n _disconnected() {\r\n this.btnFirst?.removeEventListener(\"click\", this.getFirst);\r\n this.btnPrev?.removeEventListener(\"click\", this.getPrev);\r\n this.btnNext?.removeEventListener(\"click\", this.getNext);\r\n this.btnLast?.removeEventListener(\"click\", this.getLast);\r\n this.selectPerPage?.removeEventListener(\"change\", this.changePerPage);\r\n this.inputPage?.removeEventListener(\"input\", this.gotoPage);\r\n\r\n for (const plugin of Object.values(this.plugins)) {\r\n plugin.disconnected();\r\n }\r\n }\n\n init() {\n return this.loadData().finally(() => {\r\n this.configureUi();\r\n\r\n this.sortChanged();\r\n this.classList.add(\"dg-initialized\"); //acts as a flag to prevent unnecessary server calls down the chain.\r\n\r\n this.filterChanged();\r\n this.reorderChanged();\r\n\r\n this.dirChanged();\r\n this.perPageValuesChanged();\r\n this.pageChanged();\r\n\r\n this.fireEvents = true; // We can now fire attributeChangedCallback events\r\n\r\n this.log(\"initialized\");\r\n });\n }\r\n\r\n /**\r\n * @param {string} field\r\n * @returns {Column}\r\n */\r\n getCol(field) {\r\n let found = null;\r\n\r\n for (const col of this.options.columns) {\r\n if (col.field === field) {\r\n found = col;\r\n }\r\n }\r\n return found;\r\n }\r\n\r\n getColProp(field, prop) {\r\n const c = this.getCol(field);\r\n return c ? c[prop] : null;\r\n }\r\n\r\n setColProp(field, prop, val) {\r\n const c = this.getCol(field);\r\n if (c) {\r\n c[prop] = val;\r\n }\r\n }\r\n\r\n visibleColumns() {\r\n return this.options.columns.filter((col) => {\r\n return !col.hidden;\r\n });\r\n }\r\n\r\n hiddenColumns() {\r\n return this.options.columns.filter((col) => {\r\n return col.hidden === true;\r\n });\r\n }\r\n\r\n showColumn(field, render = true) {\r\n this.setColProp(field, \"hidden\", false);\r\n\r\n // We need to render the whole table otherwise layout fixed won't do its job\r\n if (render) this.renderTable();\r\n\r\n dispatch(this, \"columnVisibility\", {\r\n col: field,\r\n visibility: \"visible\",\r\n });\r\n }\r\n\r\n hideColumn(field, render = true) {\r\n this.setColProp(field, \"hidden\", true);\r\n\r\n // We need to render the whole table otherwise layout fixed won't do its job\r\n if (render) this.renderTable();\r\n\r\n dispatch(this, \"columnVisibility\", {\r\n col: field,\r\n visibility: \"hidden\",\r\n });\r\n }\r\n\r\n /**\r\n * Returns the starting index of actual data\r\n * @returns {Number}\r\n */\r\n startColIndex() {\r\n let start = 1;\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n start++;\r\n }\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n start++;\r\n }\r\n return start;\r\n }\r\n\r\n /**\r\n * @returns {Boolean}\r\n */\r\n isSticky() {\r\n return this.hasAttribute(\"sticky\");\r\n }\r\n\r\n /**\r\n * @param {Boolean} visibleOnly\r\n * @returns {Number}\r\n */\r\n columnsLength(visibleOnly = false) {\r\n let len = 0;\r\n // One column per (visible) column\r\n for (const col of this.options.columns) {\r\n if (visibleOnly && col.hidden) {\r\n continue;\r\n }\r\n if (!col.attr) {\r\n len++;\r\n }\r\n }\r\n // Add one col for selectable checkbox at the beginning\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n len++;\r\n }\r\n // Add one col for actions at the end\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n len++;\r\n }\r\n // Add one col for the responsive toggle\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n len++;\r\n }\r\n return len;\r\n }\r\n\r\n /**\r\n * Global configuration and renderTable\r\n * This should be called after your data has been loaded\r\n */\r\n configureUi() {\r\n if (!this.table) return this;\n this.table.style.visibility = \"hidden\";\r\n this.renderTable();\r\n if (this.options.responsive && this.plugins.ResponsiveGrid) {\r\n // Let the observer make the table visible\r\n } else {\r\n this.table.style.visibility = \"visible\";\r\n }\r\n\r\n // Store row height for later usage\r\n if (!this.rowHeight) {\r\n const tr = find(this, \"tbody tr\") || find(this, \"table tr\");\r\n if (tr) {\r\n this.rowHeight = tr.offsetHeight;\r\n }\r\n }\n this.#setNoData(this.tbody);\r\n return this.fixPage();\r\n }\r\n\r\n filterChanged() {\r\n const row = this.querySelector(\"thead tr.dg-head-filters\");\r\n if (this.options.filter) {\r\n removeAttribute(row, \"hidden\");\r\n } else {\r\n this.clearFilters();\r\n setAttribute(row, \"hidden\", \"\");\r\n }\r\n }\r\n\r\n reorderChanged() {\r\n const headers = findAll(this, \"thead tr.dg-head-columns th\");\r\n for (const th of headers) {\r\n if (th.classList.contains(\"dg-selectable\") || th.classList.contains(\"dg-actions\")) {\r\n continue;\r\n }\r\n if (this.options.reorder && this.plugins.DraggableHeaders) {\r\n th.draggable = true;\r\n } else {\r\n th.removeAttribute(\"draggable\");\r\n }\r\n }\r\n }\r\n\r\n sortChanged() {\r\n this.log(\"toggle sort\");\r\n\r\n const headers = findAll(this, \"thead tr.dg-head-columns th\");\r\n for (const th of headers) {\r\n const fieldName = th.getAttribute(\"field\");\r\n if (\r\n th.classList.contains(\"dg-not-sortable\") ||\r\n (!this.fireEvents && fieldName === this.options.defaultSort)\r\n ) {\r\n return;\r\n }\r\n if (this.options.sort && !this.getColProp(fieldName, \"noSort\")) {\r\n setAttribute(th, \"aria-sort\", \"none\");\r\n } else {\r\n removeAttribute(th, \"aria-sort\");\r\n }\r\n }\r\n }\r\n\r\n selectableChanged() {\r\n this.renderTable();\r\n }\r\n\r\n addRow(row) {\r\n if (!Array.isArray(this.originalData)) {\r\n return;\r\n }\r\n this.log(\"add row\");\r\n this.originalData.push(row);\r\n this.data = this.originalData.slice();\r\n this.sortData();\r\n }\r\n\r\n /**\r\n * @param {any} value Value to remove. Defaults to last row.\r\n * @param {String} key The key of the item to remove. Defaults to first column\r\n */\r\n removeRow(value = null, key = null) {\r\n if (!Array.isArray(this.originalData)) {\r\n return;\r\n }\r\n\r\n let v = value;\r\n let k = key;\r\n if (k === null) {\r\n k = this.options.columns[0].field;\r\n }\r\n if (v === null) {\r\n v = this.originalData[this.originalData.length - 1][k];\r\n }\r\n this.log(`remove row ${k}:${v}`);\r\n for (let i = 0; i < this.originalData.length; i++) {\r\n if (this.originalData[i][k] === v) {\r\n this.originalData.splice(i, 1);\r\n break;\r\n }\r\n }\r\n this.data = this.originalData.slice();\r\n this.sortData();\r\n }\r\n\r\n /**\n * Get selected rows or specific fields from selected rows.\n * If no keys are provided, returns the full row objects.\n * If one key is provided, returns an array of values for that key.\n * If multiple keys are provided, returns an array of objects with those keys and values.\n * In single select mode, returns a single object or value.\n * @param {...String} keys - Field names to select from each row.\n * @returns {Array|Object} Selected rows, values, or objects depending on selection and keys.\n */\n getSelection(...keys) {\n if (!this.plugins.SelectableRows) {\n return [];\n }\n return this.plugins.SelectableRows.getSelection(...keys);\n }\r\n\r\n getData() {\r\n return this.originalData;\r\n }\r\n\r\n clearData(force = false) {\r\n // Already empty\r\n if (!force && this.data.length === 0) {\r\n return;\r\n }\n this.classList.remove(\"dg-empty\", \"dg-network-error\");\n this.tbody?.setAttribute(\"data-empty\", this.noData);\r\n this.data = this.originalData = [];\r\n this.renderBody();\r\n }\r\n\r\n /**\r\n * Preloads the data intended to bypass the initial fetch operation, allowing for faster intial page load time.\r\n * Subsequent grid actions after initialization will operate as normal.\r\n * @param {Object} data - an object with meta ({total, filtered, start}) and data (array of objects) properties.\r\n */\r\n preload(data) {\r\n const metaKey = this.options.serverParams.metaKey;\r\n const dataKey = this.options.serverParams.dataKey;\r\n if (data?.[metaKey]) {\r\n this.meta = data[metaKey];\r\n }\r\n if (data?.[dataKey]) {\r\n this.data = this.originalData = data[dataKey];\r\n }\r\n }\r\n\n /**\n * Clears and reloads data from url.\n * @param {Function|String} callbackOrUrl\n * @returns {DataGrid}\n */\r\n refresh(callbackOrUrl = null) {\r\n this.data = this.originalData = [];\r\n return this.reload(callbackOrUrl);\r\n }\r\n\n /**\n * Reloads data from url.\n * @param {Function|String} callbackOrUrl\n * @returns {DataGrid}\n */\r\n reload(callbackOrUrl = null) {\r\n this.log(\"reload\");\r\n if (typeof callbackOrUrl === \"string\") {\n this.options.url = callbackOrUrl;\n }\r\n // If the data was cleared, we need to render again\r\n const needRender = !this.originalData?.length;\r\n this.fixPage();\r\n // @ts-ignore\r\n return this.loadData().finally(() => {\r\n if (this.hasDataError) return;\r\n // If we load data from the server, we redraw the table body\r\n // Otherwise, we just need to paginate\r\n this.options.server || needRender ? this.renderBody() : this.paginate();\r\n if (typeof callbackOrUrl === \"function\") {\r\n callbackOrUrl();\r\n }\r\n }).then(() => this);\r\n }\r\n\r\n /**\r\n * @returns {Promise}\r\n */\r\n loadData() {\r\n const flagEmpty = () => !this.data.length && this.classList.add(\"dg-empty\");\r\n const tbody = this.tbody;\r\n\r\n // We already have some data\r\n if (this.meta || this.originalData || this.isInit) {\r\n // We don't use server side data\r\n if (!this.options.server || (this.options.server && !this.fireEvents)) {\r\n this.log(\"skip loadData\");\r\n flagEmpty();\r\n return new Promise((resolve) => {\r\n resolve();\r\n });\r\n }\r\n }\r\n this.log(\"loadData\");\r\n this.loading = true;\r\n this.classList.add(\"dg-loading\");\r\n this.classList.remove(\"dg-empty\", \"dg-network-error\");\r\n return (\r\n this.fetchData()\r\n .then((response) => {\r\n // We can get a straight array or an object\r\n if (Array.isArray(response)) {\r\n this.data = response;\r\n } else {\r\n // Object must contain data key\r\n if (!response[this.options.serverParams.dataKey]) {\r\n console.error(\r\n \"Invalid response, it should contain a data key with an array or be a plain array\",\r\n response,\r\n );\r\n this.options.url = null;\r\n return;\r\n }\r\n\r\n // We may have a config object\r\n this.options = Object.assign(\r\n this.options,\r\n response[this.options.serverParams.optionsKey] ?? {},\r\n );\r\n // It should return meta data (see metaFilteredKey)\r\n this.meta = response[this.options.serverParams.metaKey] ?? {};\r\n this.data = response[this.options.serverParams.dataKey];\r\n }\r\n this.originalData = this.data.slice();\r\n this.fixPage();\r\n\r\n // Make sure we have a proper set of columns\r\n if (this.options.columns.length === 0 && this.originalData.length) {\r\n this.options.columns = this.convertColumns(Object.keys(this.originalData[0]));\r\n } else {\r\n this.options.columns = this.convertColumns(this.options.columns);\r\n }\r\n })\r\n .catch((err) => {\r\n this.log(err);\r\n tbody.setAttribute(\r\n \"data-empty\",\r\n this.options.errorMessage ||\r\n err.message?.replace(/^\\s+|\\r\\n|\\n|\\r$/g, \"\") ||\r\n labels.networkError,\r\n );\r\n this.classList.add(\"dg-empty\", \"dg-network-error\");\r\n dispatch(this, \"loadDataFailed\", err);\r\n })\r\n // @ts-ignore\r\n .finally(() => {\r\n flagEmpty();\r\n this.#setNoData(tbody);\r\n this.classList.remove(\"dg-loading\");\r\n setAttribute(this.table, \"aria-rowcount\", this.data.length);\r\n this.loading = false;\r\n })\r\n );\r\n }\r\n\r\n getFirst() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = 1;\r\n }\r\n\r\n getLast() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = this.pages;\r\n }\r\n\r\n getPrev() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = this.page - 1;\r\n }\r\n\r\n getNext() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = this.page + 1;\r\n }\r\n\r\n gotoPage(event) {\r\n if (event.type === \"keypress\") {\r\n const key = event.keyCode || event.key;\r\n if (key === 13 || key === \"Enter\") {\r\n event.preventDefault();\r\n } else {\r\n return;\r\n }\r\n }\r\n this.page = Number.parseInt(this.inputPage.value);\r\n }\r\n\r\n getSort() {\r\n const col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n if (col) {\r\n return col.getAttribute(\"field\");\r\n }\r\n return this.options.defaultSort;\r\n }\r\n\r\n getSortDir() {\r\n const col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n if (col) {\r\n return col.getAttribute(\"aria-sort\") || \"\";\r\n }\r\n return \"\";\r\n }\r\n\r\n getFilters() {\r\n const filters = [];\r\n const inputs = findAll(this, this._filterSelector);\r\n for (const input of inputs) {\r\n filters[input.dataset.name] = input.value;\r\n }\r\n return filters;\r\n }\r\n\r\n clearFilters() {\r\n const inputs = findAll(this, this._filterSelector);\r\n for (const input of inputs) {\r\n input.value = \"\";\r\n }\r\n this.filterData();\r\n }\r\n\r\n filterData() {\r\n this.log(\"filter data\");\r\n\r\n this.page = 1;\r\n\r\n if (this.options.server) {\r\n this.reload();\r\n } else {\r\n this.data = this.originalData?.slice() ?? [];\r\n\r\n // Look for rows matching the filters\r\n const inputs = findAll(this, this._filterSelector);\r\n for (const input of inputs) {\r\n const value = input.value;\r\n if (value) {\r\n const name = input.dataset.name;\r\n this.data = this.data.filter((item) => {\r\n const str = `${item[name]}`;\r\n return str.toLowerCase().indexOf(value.toLowerCase()) !== -1;\r\n });\r\n }\r\n }\r\n this.pageChanged();\r\n\r\n const col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n if (this.options.sort && col) {\r\n this.sortData();\r\n } else {\r\n this.renderBody();\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Data will be sorted then rendered using renderBody\r\n * @param {Element} baseCol The column that was clicked or null to use current sort\r\n */\r\n sortData(baseCol = null) {\r\n this.log(\"sort data\");\r\n\r\n let col = baseCol;\r\n\r\n // Early exit\r\n if (col && this.getColProp(col.getAttribute(\"field\"), \"noSort\")) {\r\n this.log(\"sorting prevented because column is not sortable\");\r\n return;\r\n }\r\n if (this.plugins.ColumnResizer?.isResizing) {\r\n this.log(\"sorting prevented because resizing\");\r\n return;\r\n }\r\n if (this.loading) {\r\n this.log(\"sorting prevented because loading\");\r\n return;\r\n }\r\n\r\n // We clicked on a column, update sort state\r\n if (col !== null) {\r\n // Remove active sort if any\r\n const haveClasses = (c) => [\"dg-selectable\", \"dg-actions\", \"dg-responsive-toggle\"].includes(c);\r\n\r\n const headers = findAll(this, \"thead tr:first-child th\");\r\n for (const th of headers) {\r\n // @ts-ignore\r\n if ([...th.classList].some(haveClasses) || !th.hasAttribute(\"aria-sort\")) {\r\n continue;\r\n }\r\n if (th !== col) {\r\n th.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n }\r\n\r\n // Set tristate col\r\n if (!col.hasAttribute(\"aria-sort\") || col.getAttribute(\"aria-sort\") === \"none\") {\r\n col.setAttribute(\"aria-sort\", \"ascending\");\r\n } else if (col.getAttribute(\"aria-sort\") === \"ascending\") {\r\n col.setAttribute(\"aria-sort\", \"descending\");\r\n } else if (col.getAttribute(\"aria-sort\") === \"descending\") {\r\n col.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n } else {\r\n // Or fetch current sort\r\n col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n }\r\n\r\n if (this.options.server) {\r\n // Reload data with updated sort\r\n this.loadData().finally(() => {\r\n this.renderBody();\r\n });\r\n } else {\r\n const sort = col ? col.getAttribute(\"aria-sort\") : \"none\";\r\n if (sort === \"none\") {\r\n const stack = [];\r\n\r\n // Restore order while keeping filters\r\n this.originalData?.some((itemA) => {\r\n this.data.some((itemB) => {\r\n if (JSON.stringify(itemA) === JSON.stringify(itemB)) {\r\n stack.push(itemB);\r\n return true;\r\n }\r\n return false;\r\n });\r\n return stack.length === this.data.length;\r\n });\r\n\r\n this.data = stack;\r\n } else {\r\n const field = col.getAttribute(\"field\");\r\n this.data.sort((a, b) => {\r\n if (!isNaN(a[field]) && !isNaN(b[field])) {\r\n return sort === \"ascending\" ? a[field] - b[field] : b[field] - a[field];\r\n }\r\n const valA = sort === \"ascending\" ? a[field].toUpperCase() : b[field].toUpperCase();\r\n const valB = sort === \"ascending\" ? b[field].toUpperCase() : a[field].toUpperCase();\r\n\r\n switch (true) {\r\n case valA > valB:\r\n return 1;\r\n case valA < valB:\r\n return -1;\r\n case valA === valB:\r\n return 0;\r\n }\r\n });\r\n }\r\n this.renderBody();\r\n }\r\n }\r\n\r\n _sort(columnName, sortDir) {\r\n const col = this.querySelector(`.dg-head-columns th[field=${columnName}]`);\r\n const dir = sortDir === \"ascending\" ? \"none\" : sortDir === \"descending\" ? \"ascending\" : \"descending\";\r\n col?.setAttribute(\"aria-sort\", dir);\r\n this.sortData(col);\r\n }\r\n\r\n sortAsc = (columnName) => this._sort(columnName, \"ascending\");\r\n sortDesc = (columnName) => this._sort(columnName, \"descending\");\r\n sortNone = (columnName) => this._sort(columnName, \"none\");\r\n\r\n fetchData() {\r\n if (!this.options.url) {\r\n return new Promise((resolve, reject) => reject(\"No url set\"));\r\n }\r\n\r\n let base = window.location.href;\r\n // Fix trailing slash if no extension is present\r\n if (!base.split(\"/\").pop().includes(\".\")) {\r\n base += base.endsWith(\"/\") ? \"\" : \"/\";\r\n }\r\n const url = new URL(this.options.url, base);\r\n let params = {\r\n r: Date.now(),\r\n };\r\n if (this.options.server) {\r\n // 0 based\r\n params[this.options.serverParams.start] = this.page - 1;\r\n params[this.options.serverParams.length] = this.options.perPage;\r\n if (this.options.filter) params[this.options.serverParams.search] = this.getFilters();\r\n params[this.options.serverParams.sort] = this.getSort() || \"\";\r\n params[this.options.serverParams.sortDir] = this.getSortDir();\r\n\r\n // extra params ?\r\n if (this.meta?.[this.options.serverParams.paramsKey]) {\r\n params = Object.assign(params, this.meta[this.options.serverParams.paramsKey]);\r\n }\r\n }\r\n\r\n appendParamsToUrl(url, params);\r\n\r\n return fetch(url).then((response) => {\r\n const newError = new Error(response.statusText || labels.networkError);\r\n if (!response.ok) {\r\n // @ts-ignore\r\n newError.response = response;\r\n throw newError;\r\n }\r\n return response\r\n .clone()\r\n .json()\r\n .catch((err) => {\r\n let error = err;\r\n if (!this.options.debug) {\r\n error = newError;\r\n }\r\n error.response = response;\r\n throw error;\r\n });\r\n });\r\n }\r\n\r\n renderTable() {\r\n this.log(\"render table\");\r\n\r\n if (this.options.menu && this.plugins.ContextMenu) {\r\n this.plugins.ContextMenu.createMenu();\r\n }\r\n\r\n let sortedColumn;\r\n\r\n this.renderHeader();\r\n if (this.options.defaultSort) {\r\n // We can have a default sort even with sort disabled\r\n sortedColumn = this.querySelector(`thead tr.dg-head-columns th[field=\"${this.options.defaultSort}\"]`);\r\n }\r\n\r\n if (sortedColumn) {\r\n this.sortData(sortedColumn);\r\n } else {\r\n this.renderBody();\r\n }\r\n\r\n this.renderFooter();\r\n }\r\n\r\n /**\r\n * Create table header\r\n * - One row for the column headers\r\n * - One row for the filters\r\n */\r\n renderHeader() {\r\n this.log(\"render header\");\r\n\r\n const thead = this.thead;\r\n this.createColumnHeaders(thead);\r\n this.createColumnFilters(thead);\r\n\r\n if (this.options.resizable && this.plugins.ColumnResizer) {\r\n this.plugins.ColumnResizer.renderResizer(labels.resizeColumn);\r\n }\r\n\r\n dispatch(this, \"headerRendered\");\r\n }\r\n\r\n renderFooter() {\r\n this.log(\"render footer\");\r\n\r\n const tfoot = this.tfoot;\r\n if (!tfoot) return;\n const td = tfoot.querySelector(\"td\");\r\n tfoot.removeAttribute(\"hidden\");\r\n setAttribute(td, \"colspan\", this.columnsLength(true));\r\n tfoot.style.display = \"\";\r\n }\r\n\r\n /**\r\n * Create the column headers based on column definitions and set options\r\n * @param {HTMLTableSectionElement} thead\r\n */\r\n createColumnHeaders(thead) {\r\n // @link https://stackoverflow.com/questions/21064101/understanding-offsetwidth-clientwidth-scrollwidth-and-height-respectively\r\n const availableWidth = this.clientWidth;\r\n const colMaxWidth = Math.round((availableWidth / this.columnsLength(true)) * 2);\r\n\r\n let idx = 0;\r\n let tr;\r\n\r\n // Create row\r\n tr = ce(\"tr\");\r\n this.headerRow = tr;\r\n tr.setAttribute(\"role\", \"row\");\r\n tr.setAttribute(\"aria-rowindex\", \"1\");\r\n tr.setAttribute(\"class\", \"dg-head-columns\");\r\n\r\n // We need a real th from the dom to compute the size\r\n let sampleTh = thead?.querySelector(\"tr.dg-head-columns th\");\n this.log(\"createColumnHeaders - sampleTh\", sampleTh);\r\n if (!sampleTh) {\r\n sampleTh = ce(\"th\");\r\n thead?.querySelector(\"tr\").appendChild(sampleTh);\r\n }\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.createHeaderCol(tr);\r\n }\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n this.plugins.ResponsiveGrid.createHeaderCol(tr);\r\n }\r\n\r\n // Create columns\r\n idx = 0;\r\n let totalWidth = 0;\r\n this.log(\"createColumnHeaders - columns\", this.options.columns);\r\n\r\n for (const column of this.options.columns) {\r\n if (column.attr) {\r\n continue;\r\n }\r\n const colIdx = idx + this.startColIndex();\r\n const th = ce(\"th\");\r\n th.setAttribute(\"scope\", \"col\");\r\n th.setAttribute(\"role\", \"columnheader button\");\r\n th.setAttribute(\"aria-colindex\", `${colIdx}`);\r\n th.setAttribute(\"id\", randstr(\"dg-col-\"));\r\n if (this.options.sort) {\r\n th.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n th.setAttribute(\"field\", column.field);\r\n if (this.plugins.ResponsiveGrid && this.options.responsive) {\r\n setAttribute(th, \"data-responsive\", column.responsive || \"\");\r\n }\r\n // Make sure the header fits (+ add some room for sort icon if necessary)\r\n const computedWidth = getTextWidth(column.title, sampleTh, true) + 20;\r\n th.dataset.minWidth = `${computedWidth}`;\r\n applyColumnDefinition(th, column);\r\n th.tabIndex = 0;\r\n th.textContent = column.title;\r\n\r\n let w = 0;\r\n // Autosize small based on first/last row ?\r\n // Take into account minWidth of the header and max available size based on col numbers\r\n if (this.options.autosize && this.plugins.AutosizeColumn) {\r\n const colAvailableWidth = Math.min(availableWidth - totalWidth, colMaxWidth);\r\n w = this.plugins.AutosizeColumn.computeSize(\r\n th,\r\n column,\r\n Number.parseInt(th.dataset.minWidth),\r\n colAvailableWidth,\r\n );\r\n } else {\r\n w = Math.max(Number.parseInt(th.dataset.minWidth), Number.parseInt(th.getAttribute(\"width\")));\r\n }\r\n\r\n setAttribute(th, \"width\", w);\r\n if (column.hidden) {\r\n th.setAttribute(\"hidden\", \"\");\r\n } else {\r\n totalWidth += w;\r\n }\r\n\r\n // Reorder columns with drag/drop\r\n if (this.options.reorder && this.plugins.DraggableHeaders) {\r\n this.plugins.DraggableHeaders.makeHeaderDraggable(th);\r\n }\r\n\r\n tr.appendChild(th);\r\n idx++;\r\n }\r\n\r\n // There is too much available width, and we want to avoid fixed layout to split remaining amount\r\n if (totalWidth < availableWidth) {\r\n const visibleCols = findAll(tr, \"th:not([hidden],.dg-not-resizable)\");\r\n if (visibleCols.length) {\r\n const lastCol = visibleCols[visibleCols.length - 1];\r\n removeAttribute(lastCol, \"width\");\r\n }\r\n }\r\n\r\n // Actions\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n this.plugins.RowActions.makeActionHeader(tr);\r\n }\r\n\r\n thead?.replaceChild(tr, thead.querySelector(\"tr.dg-head-columns\"));\r\n\r\n // Once columns are inserted, we have an actual dom to query\r\n if (thead && thead.offsetWidth > availableWidth) {\r\n this.log(`adjust width to fix size, ${thead.offsetWidth} > ${availableWidth}`);\r\n const scrollbarWidth = this.offsetWidth - this.clientWidth;\r\n let diff = thead.offsetWidth - availableWidth - scrollbarWidth;\r\n if (this.options.responsive && this.plugins.ResponsiveGrid) {\r\n diff += scrollbarWidth;\r\n }\r\n // Remove diff for columns that can afford it\r\n const thWithWidth = findAll(tr, \"th[width]\");\r\n\r\n for (const th of thWithWidth) {\r\n if (hasClass(th, \"dg-not-resizable\")) {\r\n continue;\r\n }\r\n if (diff <= 0) {\r\n continue;\r\n }\r\n const actualWidth = Number.parseInt(th.getAttribute(\"width\"));\r\n const minWidth = th.dataset.minWidth ? Number.parseInt(th.dataset.minWidth) : 0;\r\n if (actualWidth > minWidth) {\r\n let newWidth = actualWidth - diff;\r\n if (newWidth < minWidth) {\r\n newWidth = minWidth;\r\n }\r\n diff -= actualWidth - newWidth;\r\n setAttribute(th, \"width\", newWidth);\r\n }\r\n }\r\n }\r\n\r\n // Context menu\r\n if (this.options.menu && this.plugins.ContextMenu) {\r\n this.plugins.ContextMenu.attachContextMenu();\r\n }\r\n\r\n // Sort col on click\r\n const rowsWithSort = findAll(tr, \"[aria-sort]\");\r\n for (const sortableRow of rowsWithSort) {\r\n sortableRow.addEventListener(\"click\", () => this.sortData(sortableRow));\r\n }\r\n\r\n this.table && setAttribute(this.table, \"aria-colcount\", this.columnsLength(true));\r\n }\r\n\r\n createColumnFilters(thead) {\r\n let idx = 0;\r\n let tr;\r\n\r\n // Create row for filters\r\n tr = ce(\"tr\");\r\n this.filterRow = tr;\r\n tr.setAttribute(\"role\", \"row\");\r\n tr.setAttribute(\"aria-rowindex\", \"2\");\r\n tr.setAttribute(\"class\", \"dg-head-filters\");\r\n if (!this.options.filter) {\r\n tr.setAttribute(\"hidden\", \"\");\r\n }\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.createFilterCol(tr);\r\n }\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n this.plugins.ResponsiveGrid.createFilterCol(tr);\r\n }\r\n\r\n this.log(\"createColumnFilters - columns\", this.options.columns);\r\n for (const column of this.options.columns) {\r\n if (column.attr) {\r\n continue;\r\n }\r\n const colIdx = idx + this.startColIndex();\r\n const relatedTh = thead?.querySelector(`tr.dg-head-columns th[aria-colindex=\"${colIdx}\"]`);\r\n if (!relatedTh) {\r\n console.warn(\"Related th not found\", colIdx);\r\n continue;\r\n }\r\n const th = ce(\"th\");\r\n th.setAttribute(\"aria-colindex\", `${colIdx}`);\r\n\r\n const filter = this.createFilterElement(column, relatedTh);\r\n if (!this.options.filter) {\r\n th.tabIndex = 0;\r\n } else {\r\n filter.tabIndex = 0;\r\n }\r\n\r\n if (column.hidden) {\r\n th.setAttribute(\"hidden\", \"\");\r\n }\r\n\r\n th.appendChild(filter);\r\n tr.appendChild(th);\r\n idx++;\r\n }\r\n\r\n // Actions\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n this.plugins.RowActions.makeActionFilter(tr);\r\n }\r\n\r\n thead?.replaceChild(tr, thead.querySelector(\"tr.dg-head-filters\"));\r\n\r\n if (typeof this.options.filterKeypressDelay !== \"number\" || this.options.filterOnEnter)\r\n this.options.filterKeypressDelay = 0;\r\n\r\n // Filter content by field events\r\n const filteredRows = findAll(tr, this._filterSelector);\r\n for (const el of filteredRows) {\r\n const eventName = /select/i.test(el.tagName) ? \"change\" : \"keyup\";\r\n const eventHandler = debounce((e) => {\r\n const key = e.keyCode || e.key;\r\n const isKeyPressFilter = !this.options.filterOnEnter && !this._excludedKeys.some((k) => k === key);\r\n if (key === 13 || key === \"Enter\" || isKeyPressFilter || e.type === \"change\") {\r\n this.filterData.call(this);\r\n }\r\n }, this.options.filterKeypressDelay);\r\n el.addEventListener(eventName, eventHandler);\r\n }\r\n }\r\n\r\n createFilterElement(column, relatedTh) {\r\n const isSelect = column.filterType === \"select\";\r\n const filter = isSelect ? ce(\"select\") : ce(\"input\");\r\n if (isSelect) {\r\n if (!Array.isArray(column.filterList)) {\r\n // Gets unique values from column records\r\n const uniqueValues = [...new Set((this.data ?? []).map((e) => e[column.field]))]\r\n .filter((v) => v)\r\n .sort();\r\n column.filterList = [column.firstFilterOption || this.defaultColumn.firstFilterOption].concat(\r\n uniqueValues.map((e) => ({ value: e, text: e })),\r\n );\r\n }\r\n\r\n for (const e of column.filterList) {\r\n const opt = ce(\"option\");\r\n opt.value = e.value;\r\n opt.text = e.text;\r\n\r\n if (filter instanceof HTMLSelectElement) {\r\n filter.add(opt);\r\n }\r\n }\r\n } else {\r\n //@ts-ignore\r\n filter.type = \"text\";\r\n filter.inputMode = \"search\";\r\n filter.autocomplete = \"off\";\r\n filter.spellcheck = false;\r\n }\r\n // Allows binding filter to this column\r\n filter.dataset.name = column.field;\r\n filter.id = randstr(\"dg-filter-\");\r\n // Don't use aria-label as it triggers autocomplete\r\n filter.setAttribute(\"aria-labelledby\", relatedTh.getAttribute(\"id\"));\r\n return filter;\r\n }\r\n\r\n /**\r\n * Render the data as rows in tbody\r\n * It will call paginate() at the end\r\n */\r\n renderBody() {\r\n this.log(\"render body\");\r\n let tr;\r\n let td;\r\n let idx;\r\n const tbody = ce(\"tbody\");\r\n\r\n this.data.forEach((item, i) => {\r\n tr = ce(\"tr\");\r\n setAttribute(tr, \"role\", \"row\");\r\n setAttribute(tr, \"hidden\", \"\");\r\n setAttribute(tr, \"aria-rowindex\", i + 1);\r\n tr.tabIndex = 0;\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.createDataCol(tr);\r\n }\r\n if (\r\n this.options.responsive &&\r\n this.plugins.ResponsiveGrid &&\r\n this.plugins.ResponsiveGrid.hasHiddenColumns()\r\n ) {\r\n this.plugins.ResponsiveGrid.createDataCol(tr);\r\n }\r\n\r\n // Expandable\r\n if (this.options.expand) {\r\n tr.classList.add(\"dg-expandable\");\r\n\r\n on(tr, \"click\", (ev) => {\n if (ev.target.matches(this._excludedRowElementSelector)) return;\r\n if (this.plugins.ResponsiveGrid) {\r\n this.plugins.ResponsiveGrid.blockObserver();\r\n }\r\n toggleClass(ev.currentTarget, \"dg-expanded\");\r\n if (this.plugins.ResponsiveGrid) {\r\n this.plugins.ResponsiveGrid.unblockObserver();\r\n }\r\n });\r\n }\r\n\r\n idx = 0;\r\n\r\n for (const column of this.options.columns) {\r\n if (!column) {\r\n console.error(\"Empty column found!\", this.options.columns);\r\n }\r\n // It should be applied as an attr of the row\r\n if (column.attr) {\r\n if (item[column.field]) {\r\n // Special case if we try to write over the class attr\r\n if (column.attr === \"class\") {\r\n addClass(tr, item[column.field]);\r\n } else {\r\n tr.setAttribute(column.attr, item[column.field]);\r\n }\r\n }\r\n return;\r\n }\r\n td = ce(\"td\");\r\n td.setAttribute(\"role\", \"gridcell\");\r\n td.setAttribute(\"aria-colindex\", `${idx}${this.startColIndex()}`);\r\n applyColumnDefinition(td, column);\r\n // This is required for pure css responsive layout\r\n td.setAttribute(\"data-name\", column.title);\r\n td.tabIndex = -1;\r\n\r\n // Inline editing ...\r\n if (column.editable && this.plugins.EditableColumn) {\r\n addClass(td, \"dg-editable-col\");\r\n this.plugins.EditableColumn.makeEditableInput(td, column, item, i);\r\n } else {\r\n // ... or formatting\r\n const v = item[column.field] ?? \"\";\r\n let tv;\r\n // TODO: make this modular\r\n switch (column.transform) {\r\n case \"uppercase\":\r\n tv = v.toUpperCase();\r\n break;\r\n case \"lowercase\":\r\n tv = v.toLowerCase();\r\n break;\r\n default:\r\n tv = v;\r\n break;\r\n }\r\n if (column.format) {\r\n // Only use formatting with values or if defaultFormatValue is set\r\n if (column.defaultFormatValue !== undefined && (tv === \"\" || tv === null)) {\r\n tv = `${column.defaultFormatValue}`;\r\n }\r\n if (typeof column.format === \"string\" && tv) {\r\n td.innerHTML = interpolate(\r\n // @ts-ignore\r\n column.format,\r\n Object.assign(\r\n {\r\n _v: v,\r\n _tv: tv,\r\n },\r\n item,\r\n ),\r\n );\r\n } else if (column.format instanceof Function) {\r\n const val = column.format.call(this, { column, rowData: item, cellData: tv, td, tr });\r\n td.innerHTML = val || tv || v;\r\n }\r\n } else {\r\n td.textContent = tv;\r\n }\r\n }\r\n tr.appendChild(td);\r\n idx++;\r\n }\r\n\r\n // Actions\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n this.plugins.RowActions.makeActionRow(tr, item);\r\n }\r\n\r\n tbody.appendChild(tr);\r\n\n dispatch(this, \"rowRendered\", { rowData: item, tr });\r\n });\r\n\r\n tbody.setAttribute(\"role\", \"rowgroup\");\r\n\r\n // Keep data empty message\r\n const prev = this.tbody;\r\n prev && tbody.setAttribute(\"data-empty\", prev.getAttribute(\"data-empty\"));\r\n this.table?.replaceChild(tbody, prev);\r\n\r\n if (this.plugins.FixedHeight) {\r\n this.plugins.FixedHeight.createFakeRow();\r\n }\r\n\r\n this.paginate();\r\n\r\n if (this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.shouldSelectAll(tbody);\r\n }\r\n\r\n this.classList.toggle(\"dg-empty\", !this.data.length);\r\n\r\n dispatch(this, \"bodyRendered\");\r\n }\r\n\r\n paginate() {\r\n this.log(\"paginate\");\r\n\r\n const total = this.totalRecords();\r\n const p = this.page || 1;\r\n const tbody = this.tbody;\r\n const tfoot = this.tfoot;\r\n if (!tbody || !tfoot) return;\n const bodyRows = findAll(tbody, \"tr\");\r\n\r\n // Refresh page count in case we added/removed a page\r\n this.pages = this.totalPages();\r\n\r\n let index;\r\n let high = p * this.options.perPage;\r\n let low = high - this.options.perPage + 1;\r\n\r\n if (high > total) {\r\n high = total;\r\n }\r\n if (!total) {\r\n low = 0;\r\n }\r\n\r\n // Display all rows within the set indexes\r\n // For server side paginated grids, we display everything\r\n // since the server is taking care of actual pagination\r\n for (const tr of bodyRows) {\r\n if (this.options.server) {\r\n removeAttribute(tr, \"hidden\");\r\n continue;\r\n }\r\n index = Number(getAttribute(tr, \"aria-rowindex\"));\r\n if (index > high || index < low) {\r\n setAttribute(tr, \"hidden\", \"\");\r\n } else {\r\n removeAttribute(tr, \"hidden\");\r\n }\r\n }\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.clearCheckboxes(tbody);\r\n }\r\n\r\n // Store default height and update styles if needed\r\n if (this.plugins.FixedHeight) {\r\n this.plugins.FixedHeight.updateFakeRow();\r\n }\r\n\r\n // Enable/disable buttons if shown\r\n if (this.btnFirst) {\r\n this.btnFirst.disabled = this.page <= 1;\r\n this.btnPrev.disabled = this.page <= 1;\r\n this.btnNext.disabled = this.page >= this.pages;\r\n this.btnLast.disabled = this.page >= this.pages;\r\n }\r\n tfoot.querySelector(\".dg-low\").textContent = low.toString();\r\n tfoot.querySelector(\".dg-high\").textContent = high.toString();\r\n tfoot.querySelector(\".dg-total\").textContent = `${this.totalRecords()}`;\r\n tfoot.toggleAttribute(\"hidden\", this.options.autohidePager && this.options.perPage > this.totalRecords());\r\n }\r\n\r\n /**\r\n * @returns {number}\r\n */\r\n totalPages() {\r\n return Math.ceil(this.totalRecords() / this.options.perPage);\r\n }\r\n\r\n /**\r\n * @returns {number}\r\n */\r\n totalRecords() {\r\n if (this.options.server) {\r\n return this.meta?.[this.options.serverParams.metaFilteredKey] || 0;\r\n }\r\n return this.data.length;\r\n }\r\n}\r\n\r\nexport default DataGrid;\r\n", "/** @typedef {import(\"../data-grid\").default} DataGrid */\r\n\r\nclass BasePlugin {\r\n /**\r\n * @param {DataGrid} grid\r\n */\r\n constructor(grid) {\r\n this.grid = grid;\r\n }\r\n\r\n connected() {}\r\n\r\n disconnected() {}\r\n\r\n /**\r\n * Handle events within the plugin\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#handling-events\r\n * @param {Event} event\r\n */\r\n handleEvent(event) {\r\n if (this[`on${event.type}`]) {\r\n this[`on${event.type}`](event);\r\n }\r\n }\r\n}\r\n\r\nexport default BasePlugin;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport elementOffset from \"../utils/elementOffset.js\";\r\nimport {\r\n addClass,\r\n dispatch,\r\n findAll,\r\n getAttribute,\r\n hasClass,\r\n off,\r\n on,\r\n removeAttribute,\r\n removeClass,\r\n setAttribute,\r\n} from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Allows to resize columns\r\n */\r\nclass ColumnResizer extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n this.isResizing = false;\r\n }\r\n\r\n /**\r\n * @param {String} resizeLabel\r\n */\r\n renderResizer(resizeLabel) {\r\n const grid = this.grid;\r\n const table = grid.table;\r\n const cols = findAll(grid, \"thead tr.dg-head-columns th\");\r\n\r\n for (const col of cols) {\r\n if (hasClass(col, \"dg-not-resizable\")) {\r\n continue;\r\n }\r\n // Create a resizer element\r\n const resizer = document.createElement(\"div\");\r\n addClass(resizer, \"dg-resizer\");\r\n resizer.ariaLabel = resizeLabel;\r\n\r\n // Add a resizer element to the column\r\n col.appendChild(resizer);\r\n\r\n // Handle resizing\r\n let startX = 0;\r\n let startW = 0;\r\n let remainingSpace = 0;\r\n let max = 0;\r\n\r\n const mouseMoveHandler = (e) => {\r\n if (e.clientX > max) {\r\n return;\r\n }\r\n const newWidth = startW + (e.clientX - startX);\r\n if (col.dataset.minWidth && newWidth > Number.parseInt(col.dataset.minWidth)) {\r\n setAttribute(col, \"width\", newWidth);\r\n }\r\n };\r\n\r\n // When user releases the mouse, remove the existing event listeners\r\n const mouseUpHandler = () => {\r\n grid.log(\"resized column\");\r\n\r\n // Prevent accidental sorting if mouse is not over resize handler\r\n setTimeout(() => {\r\n this.isResizing = false;\r\n }, 0);\r\n\r\n removeClass(resizer, \"dg-resizer-active\");\r\n if (grid.options.reorder) {\r\n col.draggable = true;\r\n }\r\n col.style.overflow = \"hidden\";\r\n\r\n // Remove handlers\r\n off(document, \"mousemove\", mouseMoveHandler);\r\n off(document, \"mouseup\", mouseUpHandler);\r\n\r\n dispatch(grid, \"columnResized\", {\r\n col: getAttribute(col, \"field\"),\r\n width: getAttribute(col, \"width\"),\r\n });\r\n };\r\n\r\n // Otherwise it could sort the col\r\n on(resizer, \"click\", (e) => {\r\n e.stopPropagation();\r\n });\r\n\r\n on(resizer, \"mousedown\", (e) => {\r\n e.stopPropagation();\r\n\r\n this.isResizing = true;\r\n\r\n const target = e.target;\r\n const currentCols = findAll(grid, \"dg-head-columns th\");\r\n const visibleCols = currentCols.filter((col) => {\r\n return !col.hasAttribute(\"hidden\");\r\n });\r\n const columnIndex = visibleCols.findIndex((column) => column === target.parentNode);\r\n grid.log(\"resize column\");\r\n\r\n addClass(resizer, \"dg-resizer-active\");\r\n\r\n // Make sure we don't drag it\r\n removeAttribute(col, \"draggable\");\r\n\r\n // Allow overflow when resizing\r\n col.style.overflow = \"visible\";\r\n\r\n // Show full column height (-1 to avoid scrollbar)\r\n resizer.style.height = `${table.offsetHeight - 1}px`;\r\n\r\n // Register initial data\r\n startX = e.clientX;\r\n startW = col.offsetWidth;\r\n\r\n remainingSpace = (visibleCols.length - columnIndex) * 30;\r\n max = elementOffset(target).left + grid.offsetWidth - remainingSpace;\r\n\r\n // Remove width from next columns to allow auto layout\r\n setAttribute(col, \"width\", startW);\r\n for (let j = 0; j < visibleCols.length; j++) {\r\n if (j > columnIndex) {\r\n removeAttribute(cols[j], \"width\");\r\n }\r\n }\r\n\r\n // Attach handlers\r\n on(document, \"mousemove\", mouseMoveHandler);\r\n on(document, \"mouseup\", mouseUpHandler);\r\n });\r\n }\r\n }\r\n}\r\n\r\nexport default ColumnResizer;\r\n", "/**\r\n * @param {HTMLElement} el\r\n * @param {String} type\r\n * @param {String} prop\r\n * @returns {HTMLElement}\r\n */\r\nexport default function getParentElement(el, type, prop = \"nodeName\") {\r\n let parent = el;\r\n while (parent[prop] !== type) {\r\n parent = parent.parentElement;\r\n }\r\n return parent;\r\n}\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport getParentElement from \"../utils/getParentElement.js\";\r\nimport { find, off, on, removeAttribute, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Create a right click menu on the headers\r\n */\r\nclass ContextMenu extends BasePlugin {\r\n connected() {\r\n /**\r\n * @type {HTMLUListElement}\r\n */\r\n this.menu = this.grid.querySelector(\".dg-menu\");\r\n }\r\n disconnected() {\r\n if (this.grid.headerRow) {\r\n off(this.grid.headerRow, \"contextmenu\", this);\r\n }\r\n }\r\n\r\n attachContextMenu() {\r\n const grid = this.grid;\r\n on(grid.headerRow, \"contextmenu\", this);\r\n }\r\n\r\n onchange(e) {\r\n const grid = this.grid;\r\n const t = e.target;\r\n const field = t.dataset.name;\r\n if (t.checked) {\r\n grid.showColumn(field);\r\n } else {\r\n // Prevent hidding last\r\n if (grid.visibleColumns().length <= 1) {\r\n // Restore checkbox value\r\n t.checked = true;\r\n return;\r\n }\r\n grid.hideColumn(field);\r\n }\r\n grid.fixPage(); //fixes Chrome footer flexbox resize issues that may appear when there is a large number of columns (i.e. more than 10).\r\n }\r\n\r\n oncontextmenu(e) {\r\n e.preventDefault();\r\n const grid = this.grid;\r\n const target = getParentElement(e.target, \"THEAD\");\r\n const menu = this.menu;\r\n const rect = target.getBoundingClientRect();\r\n let x = e.clientX - rect.left;\r\n const y = e.clientY - rect.top;\r\n\r\n menu.style.top = `${y}px`;\r\n menu.style.left = `${x}px`;\r\n\r\n removeAttribute(menu, \"hidden\");\r\n if (x + 150 > rect.width) {\r\n x -= menu.offsetWidth;\r\n menu.style.left = `${x}px`;\r\n }\r\n\r\n const documentClickHandler = (e) => {\r\n if (!menu.contains(e.target)) {\r\n setAttribute(menu, \"hidden\", \"\");\r\n off(document, \"click\", documentClickHandler);\r\n }\r\n };\r\n on(document, \"click\", documentClickHandler);\r\n }\r\n createMenu() {\r\n const grid = this.grid;\r\n const menu = this.menu;\r\n while (menu.lastChild) {\r\n menu.removeChild(menu.lastChild);\r\n }\r\n menu.addEventListener(\"change\", this);\r\n\r\n for (const col of grid.options.columns) {\r\n if (col.attr) {\r\n continue;\r\n }\r\n const li = document.createElement(\"li\");\r\n const label = document.createElement(\"label\");\r\n const checkbox = document.createElement(\"input\");\r\n setAttribute(checkbox, \"type\", \"checkbox\");\r\n setAttribute(checkbox, \"data-name\", col.field);\r\n if (!col.hidden) {\r\n checkbox.checked = true;\r\n }\r\n const text = document.createTextNode(col.title);\r\n\r\n label.appendChild(checkbox);\r\n label.appendChild(text);\r\n\r\n li.appendChild(label);\r\n menu.appendChild(li);\r\n }\r\n }\r\n}\r\n\r\nexport default ContextMenu;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport getParentElement from \"../utils/getParentElement.js\";\r\nimport { dispatch, findAll, getAttribute, on, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Allows to move headers\r\n */\r\nclass DraggableHeaders extends BasePlugin {\r\n /**\r\n * @param {HTMLTableCellElement} th\r\n */\r\n makeHeaderDraggable(th) {\r\n const grid = this.grid;\r\n th.draggable = true;\r\n on(th, \"dragstart\", (e) => {\r\n if (grid.plugins.ColumnResizer?.isResizing && e.preventDefault) {\r\n e.preventDefault();\r\n return;\r\n }\r\n grid.log(\"reorder col\");\r\n e.dataTransfer.effectAllowed = \"move\";\r\n e.dataTransfer.setData(\"text/plain\", e.target.getAttribute(\"aria-colindex\"));\r\n });\r\n on(th, \"dragover\", (e) => {\r\n if (e.preventDefault) {\r\n e.preventDefault();\r\n }\r\n e.dataTransfer.dropEffect = \"move\";\r\n return false;\r\n });\r\n on(th, \"drop\", (e) => {\r\n if (e.stopPropagation) {\r\n e.stopPropagation();\r\n }\r\n const t = e.target;\r\n const target = getParentElement(t, \"TH\");\r\n const index = Number.parseInt(e.dataTransfer.getData(\"text/plain\"));\r\n const targetIndex = Number.parseInt(target.getAttribute(\"aria-colindex\"));\r\n\r\n if (index === targetIndex) {\r\n grid.log(\"reordered col stayed the same\");\r\n return;\r\n }\r\n grid.log(`reordered col from ${index} to ${targetIndex}`);\r\n\r\n const offset = grid.startColIndex();\r\n const tmp = grid.options.columns[index - offset];\r\n grid.options.columns[index - offset] = grid.options.columns[targetIndex - offset];\r\n grid.options.columns[targetIndex - offset] = tmp;\r\n\r\n const swapNodes = (selector, el1) => {\r\n const rowIndex = el1.parentNode.getAttribute(\"aria-rowindex\");\r\n const el2 = grid.querySelector(\r\n `${selector} tr[aria-rowindex=\"${rowIndex}\"] [aria-colindex=\"${targetIndex}\"]`,\r\n );\r\n setAttribute(el1, \"aria-colindex\", targetIndex);\r\n setAttribute(el2, \"aria-colindex\", index);\r\n const newNode = document.createElement(\"th\");\r\n el1.parentNode.insertBefore(newNode, el1);\r\n el2.parentNode.replaceChild(el1, el2);\r\n newNode.parentNode.replaceChild(el2, newNode);\r\n };\r\n\r\n // Swap all rows in header and body\r\n for (const el1 of findAll(grid, `thead th[aria-colindex=\"${index}\"]`)) {\r\n swapNodes(\"thead\", el1);\r\n }\r\n for (const el1 of findAll(grid, `tbody td[aria-colindex=\"${index}\"]`)) {\r\n swapNodes(\"tbody\", el1);\r\n }\r\n\r\n // Updates the columns\r\n grid.options.columns = findAll(grid, \"thead tr.dg-head-columns th[field]\").map((th) =>\r\n grid.options.columns.find((c) => c.field === getAttribute(th, \"field\")),\r\n );\r\n\r\n dispatch(grid, \"columnReordered\", {\r\n col: tmp.field,\r\n from: index,\r\n to: targetIndex,\r\n });\r\n return false;\r\n });\r\n }\r\n}\r\n\r\nexport default DraggableHeaders;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\n\r\n/**\r\n * Allows to paginate with horizontal swipe motions\r\n */\r\nclass TouchSupport extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n this.touch = null;\r\n }\r\n connected() {\r\n const grid = this.grid;\r\n grid.addEventListener(\"touchstart\", this, { passive: true });\r\n grid.addEventListener(\"touchmove\", this, { passive: true });\r\n }\r\n\r\n disconnected() {\r\n const grid = this.grid;\r\n grid.removeEventListener(\"touchstart\", this);\r\n grid.removeEventListener(\"touchmove\", this);\r\n }\r\n\r\n ontouchstart(e) {\r\n this.touch = e.touches[0];\r\n }\r\n\r\n ontouchmove(e) {\r\n if (!this.touch) {\r\n return;\r\n }\r\n const grid = this.grid;\r\n const xDiff = this.touch.clientX - e.touches[0].clientX;\r\n const yDiff = this.touch.clientY - e.touches[0].clientY;\r\n\r\n if (Math.abs(xDiff) > Math.abs(yDiff)) {\r\n if (xDiff > 0) {\r\n grid.getNext();\r\n } else {\r\n grid.getPrev();\r\n }\r\n }\r\n this.touch = null;\r\n }\r\n}\r\n\r\nexport default TouchSupport;\r\n", "// @ts-nocheck\r\nimport BasePlugin from \"../core/base-plugin.js\";\r\nimport { dispatch, findAll, hasClass, setAttribute, $, $$ } from \"../utils/shortcuts.js\";\r\n\r\nconst SELECTABLE_CLASS = \"dg-selectable\";\r\nconst SELECT_ALL_CLASS = \"dg-select-all\";\r\nconst CHECKBOX_CLASS = \"form-check-input\"; //bs5\n\r\n/**\r\n * Allows to select rows\r\n */\r\nclass SelectableRows extends BasePlugin {\n #cbSelector = `tbody tr${this.visibleOnly ? \":not([hidden])\" : \"\"} .${SELECTABLE_CLASS} input[type=checkbox]`;\n #inputSelector = `tbody .${SELECTABLE_CLASS} input`;\n\r\n disconnected() {\r\n if (this.selectAll) {\r\n this.selectAll.removeEventListener(\"change\", this);\r\n }\r\n }\n\n get isSingleSelect() {\n return this.grid.options.singleSelect;\n }\n\n get visibleOnly() {\n return this.grid.options.selectVisibleOnly;\n }\n\r\n /**\n * Get selected rows or fields.\n * Returns full rows, a single field's values, or objects with specified fields.\n * In single select mode, returns a single item.\n * @param {...string} keys Field names to select.\n * @returns {Array|Object} Selected data.\n */\n getSelection(...keys) {\n const grid = this.grid;\n const selectedData = [];\n\n const inputs = findAll(grid, `${this.#inputSelector}:checked`);\n\n for (const checkbox of inputs) {\n const idx = Number.parseInt(checkbox.dataset.id);\n const item = grid.data[idx - 1];\n if (!item) {\n console.warn(`Item ${idx} not found`);\n continue;\n }\n if (keys.length === 0) {\n selectedData.push(item);\n } else if (keys.length === 1) {\n selectedData.push(item[keys[0]]);\n } else {\n selectedData.push(Object.fromEntries(keys.map(k => [k, item[k]])));\n }\n }\n return this.isSingleSelect ? selectedData[0] ?? {} : selectedData;\n }\r\n\r\n /**\r\n * Uncheck box if hidden and visible only\r\n * @param {HTMLTableSectionElement} tbody\r\n */\r\n clearCheckboxes(tbody) {\r\n const grid = this.grid;\r\n if (!grid.options.selectVisibleOnly) {\r\n return;\r\n }\r\n const inputs = findAll(tbody, `tr[hidden] .${SELECTABLE_CLASS} input`);\r\n for (const input of inputs) {\r\n input.checked = false;\n if (this.isSingleSelect) {\n input.dataset.toggled = \"false\"; // Reset toggled state for radio buttons\n }\r\n }\r\n this.selectAll.checked = false;\n }\r\n\r\n colIndex() {\r\n return this.grid.startColIndex() - 2;\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createHeaderCol(tr) {\r\n const th = document.createElement(\"th\");\r\n setAttribute(th, \"scope\", \"col\");\r\n setAttribute(th, \"role\", \"columnheader button\");\r\n setAttribute(th, \"aria-colindex\", this.colIndex());\r\n th.classList.add(...[SELECTABLE_CLASS, \"dg-not-resizable\", \"dg-not-sortable\"]);\r\n th.tabIndex = 0;\r\n\n this.selectAll = document.createElement(\"input\");\r\n this.selectAll.type = \"checkbox\";\r\n this.selectAll.classList.add(SELECT_ALL_CLASS);\r\n this.selectAll.classList.add(CHECKBOX_CLASS);\r\n this.selectAll.addEventListener(\"change\", this);\r\n\r\n const label = document.createElement(\"label\");\n label.hidden = this.isSingleSelect;\r\n label.appendChild(this.selectAll);\r\n\r\n th.appendChild(label);\n\r\n th.setAttribute(\"width\", \"40\");\r\n tr.appendChild(th);\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createFilterCol(tr) {\r\n const th = document.createElement(\"th\");\r\n setAttribute(th, \"role\", \"columnheader button\");\r\n setAttribute(th, \"aria-colindex\", this.colIndex());\r\n th.classList.add(SELECTABLE_CLASS);\r\n th.tabIndex = 0;\r\n\r\n tr.appendChild(th);\r\n }\r\n\r\n /**\r\n * Handles the selectAll checkbox when any other .dg-selectable checkbox is checked on table body.\r\n * It should check selectAll if all is checked\r\n * It should uncheck selectAll if any is unchecked\r\n * @param {HTMLTableSectionElement} tbody\r\n */\r\n shouldSelectAll(tbody) {\r\n if (!this.selectAll) {\r\n return;\r\n }\r\n // Delegate listener for change events on input checkboxes\r\n tbody.addEventListener(\"change\", this);\r\n // Make sure state is up to date\r\n tbody.dispatchEvent(new Event(\"change\"));\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createDataCol(tr) {\r\n // Create col\r\n const td = document.createElement(\"td\");\r\n setAttribute(td, \"role\", \"gridcell button\");\r\n setAttribute(td, \"aria-colindex\", this.colIndex());\r\n td.classList.add(SELECTABLE_CLASS);\r\n\r\n // Create input\r\n const input = document.createElement(\"input\");\r\n // Alias row id for easy retrieval in getSelection\r\n input.dataset.id = tr.getAttribute(\"aria-rowindex\");\r\n input.type = this.isSingleSelect ? \"radio\" : \"checkbox\";\r\n input.classList.add(CHECKBOX_CLASS);\n if (this.isSingleSelect) {\n input.name = \"dg-row-select\";\n input.dataset.toggled = \"false\";\n }\n\r\n // Label need to take full space thanks to css to make the whole cell clickable\r\n const label = document.createElement(\"label\");\r\n label.classList.add(\"dg-clickable-cell\");\n\r\n label.appendChild(input);\r\n td.appendChild(label);\r\n\r\n // Prevent unwanted click behaviour on row\r\n label.addEventListener(\"click\", this);\r\n\r\n tr.appendChild(td);\r\n }\r\n\r\n /**\r\n * @param {Event} e\r\n */\r\n onclick(e) {\n if (!this.isSingleSelect) return e.stopPropagation();\n\n // Implements radio button toggle behaviour for selecting and unselecting a row\n const el = e.target,\n unchecked = el.dataset.toggled !== \"true\";\n unchecked && $$(`${this.#cbSelector.replace(\"checkbox\", \"radio\")}`, this.grid)?.forEach(r => {\n // Uncheck all other radios in the same group and reset their data-toggled\n if (r.name === el.name && r !== el) r.checked = r.dataset.toggled = false;\n });\r\n el.checked = el.dataset.toggled = unchecked;\n !unchecked && this.onchange(e); // Fires rowsSelected event\r\n }\r\n\r\n /**\r\n * Handle change event on select all or any select checkbox in the table body\r\n * @param {import(\"../utils/shortcuts.js\").FlexibleEvent} e\r\n */\r\n onchange(e) {\n const el = e.target, grid = this.grid;\n if (hasClass(e.target, SELECT_ALL_CLASS)) {\n findAll(grid, this.#inputSelector).forEach(cb => {\n if (!this.visibleOnly || cb.offsetWidth) cb.checked = this.selectAll.checked;\n });\n } else if (el.matches(this.#cbSelector)) {\n if (!el.closest(`.${SELECTABLE_CLASS}`)) return;\n const totalCheckboxes = findAll(grid, this.#cbSelector);\n this.selectAll.checked = totalCheckboxes.every(n => n.checked);\n }\n if (el.matches(`.${SELECT_ALL_CLASS},${this.#inputSelector}`)) {\r\n dispatch(el, \"rowsSelected\", {\r\n selection: grid.getSelection()\n }, true);\r\n }\n }\r\n}\r\n\r\nexport default SelectableRows;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport { setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Support for fixed table height\r\n *\r\n * We should add a fake row to push the footer down in case we don't have enough rows\r\n */\r\nclass FixedHeight extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n\r\n this.hasFixedHeight = false;\r\n // If we have a fixed height, make sure we have overflowY set\r\n if (grid.style.height) {\r\n grid.style.overflowY = \"auto\";\r\n this.hasFixedHeight = true;\r\n }\r\n }\r\n\r\n /**\r\n */\r\n createFakeRow() {\r\n const grid = this.grid;\r\n const tbody = grid.querySelector(\"tbody\");\r\n const tr = document.createElement(\"tr\");\r\n setAttribute(tr, \"role\", \"row\");\r\n setAttribute(tr, \"hidden\", \"\");\r\n tr.classList.add(\"dg-fake-row\");\r\n tr.tabIndex = 0;\r\n tbody?.appendChild(tr);\r\n }\r\n\r\n get fakeRow() {\r\n return this.grid.querySelector(\".dg-fake-row\");\r\n }\r\n\r\n /**\r\n * On last page, use a fake row to push footer down\r\n */\r\n updateFakeRow() {\r\n const grid = this.grid;\r\n const fakeRow = this.fakeRow;\r\n if (!fakeRow) {\r\n return;\r\n }\r\n\r\n // We don't need a fake row if we display everything\r\n if (grid.options.perPage > grid.totalRecords()) {\r\n return;\r\n }\r\n // We are not on last page\r\n if (grid.page !== grid.totalPages()) {\r\n return;\r\n }\r\n if (!grid.options.autoheight) {\r\n return;\r\n }\r\n // Find remaining missing height\r\n const max = grid.options.perPage * grid.rowHeight;\r\n const visibleRows = grid.querySelectorAll(\"tbody tr:not([hidden])\").length;\r\n const fakeHeight = visibleRows > 1 ? max - visibleRows * grid.rowHeight : max;\r\n if (fakeHeight > 0) {\r\n setAttribute(fakeRow, \"height\", fakeHeight);\r\n fakeRow.removeAttribute(\"hidden\");\r\n } else {\r\n fakeRow.removeAttribute(\"height\");\r\n }\r\n }\r\n}\r\n\r\nexport default FixedHeight;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport getTextWidth from \"../utils/getTextWidth.js\";\r\nimport { getAttribute, hasAttribute, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Allows to resize columns\r\n */\r\nclass AutosizeColumn extends BasePlugin {\r\n /**\r\n * Autosize col based on column data\r\n * @param {HTMLTableCellElement} th\r\n * @param {import(\"../data-grid\").Column} column\r\n * @param {Number} min\r\n * @param {Number} max\r\n * @returns {Number}\r\n */\r\n computeSize(th, column, min, max) {\r\n const grid = this.grid;\r\n if (hasAttribute(th, \"width\")) {\r\n return getAttribute(th, \"width\");\r\n }\r\n if (!grid.data.length) {\r\n return;\r\n }\r\n const firstVal = grid.data[0];\r\n const lastVal = grid.data[grid.data.length - 1];\r\n let v = firstVal[column.field] ? firstVal[column.field].toString() : \"\";\r\n const v2 = lastVal[column.field] ? lastVal[column.field].toString() : \"\";\r\n if (v2.length > v.length) {\r\n v = v2;\r\n }\r\n let width = 0;\r\n if (v.length <= 6) {\r\n width = min;\r\n } else if (v.length > 50) {\r\n width = max;\r\n } else {\r\n // Add some extra room to have some spare space\r\n width = getTextWidth(`${v}0000`, th);\r\n }\r\n if (width > max) {\r\n width = max;\r\n }\r\n if (width < min) {\r\n width = min;\r\n }\r\n setAttribute(th, \"width\", width);\r\n return width;\r\n }\r\n}\r\n\r\nexport default AutosizeColumn;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport debounce from \"../utils/debounce.js\";\r\nimport {\r\n addClass,\r\n ce,\r\n find,\r\n findAll,\r\n hasClass,\r\n insertAfter,\r\n removeAttribute,\r\n removeClass,\r\n setAttribute,\r\n} from \"../utils/shortcuts.js\";\r\n\r\nconst RESPONSIVE_CLASS = \"dg-responsive\";\r\n\r\nlet obsTo;\r\n\r\n/**\r\n * @param {Array} list\r\n * @returns {Array}\r\n */\r\nfunction sortByPriority(list) {\r\n return list.sort((a, b) => {\r\n const v1 = Number.parseInt(a.dataset.responsive) || 1;\r\n const v2 = Number.parseInt(b.dataset.responsive) || 1;\r\n return v2 - v1;\r\n });\r\n}\r\n\r\n/**\r\n * @type {ResizeObserverCallback}\r\n */\r\n//@ts-ignore\r\nconst callback = debounce((entries) => {\r\n for (const entry of entries) {\r\n /**\r\n * @type {import(\"../data-grid\").default}\r\n */\r\n // @ts-ignore\r\n const grid = entry.target;\r\n const table = grid.table;\r\n if (grid.plugins.ResponsiveGrid.observerBlocked) {\r\n return;\r\n }\r\n // check inlineSize (width) and not blockSize (height)\r\n const contentBoxSize = Array.isArray(entry.contentBoxSize) ? entry.contentBoxSize[0] : entry.contentBoxSize;\r\n const size = Number.parseInt(contentBoxSize.inlineSize);\r\n const tableWidth = table.offsetWidth;\r\n const realTableWidth = findAll(grid.headerRow, \"th\").reduce((result, th) => {\r\n return result + th.offsetWidth;\r\n }, 0);\r\n const diff = (realTableWidth || tableWidth) - size - 1;\r\n const minWidth = 50;\r\n const prevAction = grid.plugins.ResponsiveGrid.prevAction;\r\n // We have an array with the columns to show/hide are in order, most important first\r\n const headerCols = sortByPriority(\r\n findAll(grid.headerRow, \"th[field]\")\r\n .reverse() // Order takes precedence if no priority is set\r\n .filter((col) => {\r\n // Leave out unresponsive columns\r\n return col.dataset.responsive !== \"0\";\r\n }),\r\n );\r\n let changed = false;\r\n\r\n grid.log(`table is ${tableWidth}/${realTableWidth} and available size is ${size}. Diff: ${diff}`);\r\n\r\n // The table is too big when diff has a high value, otherwise it will be like -1 or -2\r\n if (diff > 0) {\r\n if (prevAction === \"show\") {\r\n return;\r\n }\r\n grid.plugins.ResponsiveGrid.prevAction = \"hide\";\r\n let remaining = diff;\r\n let cols = headerCols.filter((col) => {\r\n return !col.hasAttribute(\"hidden\") && col.hasAttribute(\"data-responsive\");\r\n });\r\n if (cols.length === 0) {\r\n cols = headerCols.filter((col) => {\r\n return !col.hasAttribute(\"hidden\");\r\n });\r\n // Always keep one column\r\n if (cols.length === 1) {\r\n return;\r\n }\r\n }\r\n\r\n for (const col of cols) {\r\n if (remaining < 0) {\r\n continue;\r\n }\r\n\r\n const colWidth = col.offsetWidth;\r\n const field = col.getAttribute(\"field\");\r\n if (!field) {\r\n continue;\r\n }\r\n col.dataset.baseWidth = `${col.offsetWidth}`;\r\n\r\n grid.hideColumn(field, false);\r\n grid.setColProp(field, \"responsiveHidden\", true);\r\n changed = true;\r\n\r\n remaining -= colWidth;\r\n remaining = Math.round(remaining);\r\n }\r\n } else {\r\n if (prevAction === \"hide\") {\r\n return;\r\n }\r\n grid.plugins.ResponsiveGrid.prevAction = \"show\";\r\n\r\n const requiredWidth =\r\n headerCols\r\n .filter((col) => {\r\n return !col.hasAttribute(\"hidden\");\r\n })\r\n .reduce((result, col) => {\r\n const width = col.dataset.minWidth ? Number.parseInt(col.dataset.minWidth) : col.offsetWidth;\r\n return result + width;\r\n }, 0) + minWidth; // Add an offset so that inserting column is smoother\r\n\r\n // Compute available width to insert columns\r\n let remaining = size - requiredWidth;\r\n // Do we have any hidden column that we can restore ?\r\n const filteredHeaderCols = headerCols\r\n .slice()\r\n .reverse() // Reverse the array to restore the columns in the proper order\r\n .filter((col) => {\r\n return col.hasAttribute(\"hidden\");\r\n });\r\n\r\n for (const col of filteredHeaderCols) {\r\n if (remaining < minWidth) {\r\n continue;\r\n }\r\n const colWidth = Number.parseInt(col.dataset.minWidth);\r\n\r\n // We need to have enough space to restore it\r\n if (colWidth > remaining) {\r\n remaining = -1; // break loop to keep restoring in order\r\n continue;\r\n }\r\n\r\n const field = col.getAttribute(\"field\");\r\n if (!field) {\r\n continue;\r\n }\r\n\r\n grid.showColumn(field, false);\r\n grid.setColProp(field, \"responsiveHidden\", false);\r\n changed = true;\r\n\r\n remaining -= colWidth;\r\n remaining = Math.round(remaining);\r\n }\r\n }\r\n\r\n // Check footer\r\n const footer = find(grid.table, \"tfoot\");\r\n const realFooterWidth = findAll(grid.table, \".dg-footer > div\").reduce((result, div) => {\r\n return result + div.offsetWidth;\r\n }, 0);\r\n const availableFooterWidth = footer.offsetWidth - realFooterWidth;\r\n if (realFooterWidth > size) {\r\n addClass(footer, \"dg-footer-compact\");\r\n } else if (availableFooterWidth > 250) {\r\n removeClass(footer, \"dg-footer-compact\");\r\n }\r\n if (changed) {\r\n grid.renderTable();\r\n }\r\n // Prevent resize loop\r\n setTimeout(() => {\r\n grid.plugins.ResponsiveGrid.prevAction = null;\r\n }, 1000);\r\n grid.table.style.visibility = \"visible\";\r\n }\r\n}, 100);\r\nconst resizeObserver = new ResizeObserver(callback);\r\n\r\n/**\r\n * Responsive data grid\r\n */\r\nclass ResponsiveGrid extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n\r\n this.observerBlocked = false;\r\n this.prevAction = null;\r\n }\r\n\r\n connected() {\r\n if (this.grid.options.responsive) {\r\n this.observe();\r\n }\r\n }\r\n\r\n disconnected() {\r\n this.unobserve();\r\n }\r\n\r\n observe() {\r\n if (!this.grid.options.responsive) {\r\n return;\r\n }\r\n resizeObserver.observe(this.grid);\r\n this.grid.style.display = \"block\"; // Otherwise resize doesn't happen\r\n this.grid.style.overflowX = \"hidden\"; // Prevent scrollbars from appearing\r\n }\r\n\r\n unobserve() {\r\n resizeObserver.unobserve(this.grid);\r\n this.grid.style.display = \"unset\";\r\n this.grid.style.overflowX = \"unset\";\r\n }\r\n\r\n blockObserver() {\r\n this.observerBlocked = true;\r\n if (obsTo) {\r\n clearTimeout(obsTo);\r\n }\r\n }\r\n\r\n unblockObserver() {\r\n obsTo = setTimeout(() => {\r\n this.observerBlocked = false;\r\n }, 200); // more than debounce\r\n }\r\n\r\n /**\r\n * @returns {Boolean}\r\n */\r\n hasHiddenColumns() {\r\n let flag = false;\r\n\r\n for (const col of this.grid.options.columns) {\r\n if (col.responsiveHidden) {\r\n flag = true;\r\n }\r\n }\r\n return flag;\r\n }\r\n\r\n colIndex() {\r\n return this.grid.startColIndex() - 1;\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createHeaderCol(tr) {\r\n if (!this.grid.options.responsiveToggle) {\r\n return;\r\n }\r\n const th = ce(\"th\", tr);\r\n setAttribute(th, \"scope\", \"col\");\r\n setAttribute(th, \"role\", \"columnheader button\");\r\n setAttribute(th, \"aria-colindex\", this.colIndex());\r\n setAttribute(th, \"width\", \"40\");\r\n th.classList.add(...[`${RESPONSIVE_CLASS}-toggle`, \"dg-not-resizable\", \"dg-not-sortable\"]);\r\n th.tabIndex = 0;\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createFilterCol(tr) {\r\n if (!this.grid.options.responsiveToggle) {\r\n return;\r\n }\r\n const th = ce(\"th\", tr);\r\n setAttribute(th, \"role\", \"columnheader button\");\r\n setAttribute(th, \"aria-colindex\", this.colIndex());\r\n th.classList.add(`${RESPONSIVE_CLASS}-toggle`);\r\n th.tabIndex = 0;\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createDataCol(tr) {\r\n if (!this.grid.options.responsiveToggle) {\r\n return;\r\n }\r\n // Create col\r\n const td = document.createElement(\"td\");\r\n setAttribute(td, \"role\", \"gridcell button\");\r\n setAttribute(td, \"aria-colindex\", this.colIndex());\r\n td.classList.add(`${RESPONSIVE_CLASS}-toggle`);\r\n\r\n // Create icon\r\n td.innerHTML = `\r\n
`;\r\n tr.appendChild(td);\r\n\r\n td.addEventListener(\"click\", this);\r\n td.addEventListener(\"mousedown\", this);\r\n }\r\n\r\n computeLabelWidth() {\r\n let idealWidth = 0;\r\n let consideredCol = 0;\r\n while (idealWidth < 120) {\r\n consideredCol++;\r\n const hCol = find(this.grid, `.dg-head-columns th[aria-colindex=\"${consideredCol}\"]`);\r\n if (hCol) {\r\n idealWidth += hCol.offsetWidth;\r\n } else {\r\n break;\r\n }\r\n }\r\n return idealWidth;\r\n }\r\n\r\n /**\r\n * @param {Event} ev\r\n */\r\n onmousedown(ev) {\r\n // Avoid selection through double click\r\n ev.preventDefault();\r\n }\r\n\r\n /**\r\n * @param {Event} ev\r\n */\r\n onclick(ev) {\r\n // Prevent expandable\r\n ev.stopPropagation();\r\n\r\n // target is the element that triggered the event (e.g., the user clicked on)\r\n // currentTarget is the element that the event listener is attached to.\r\n\r\n /**\r\n * @type {HTMLTableRowElement}\r\n */\r\n //@ts-ignore\r\n const td = ev.currentTarget;\r\n const tr = td.parentElement;\r\n const open = find(td, `.${RESPONSIVE_CLASS}-open`);\r\n const close = find(td, `.${RESPONSIVE_CLASS}-close`);\r\n\r\n this.blockObserver();\r\n\r\n const isExpanded = hasClass(tr, `${RESPONSIVE_CLASS}-expanded`);\r\n if (isExpanded) {\r\n removeClass(tr, `${RESPONSIVE_CLASS}-expanded`);\r\n open.style.display = \"unset\";\r\n close.style.display = \"none\";\r\n\r\n // Move back rows and cleanup row\r\n const childRow = tr.nextElementSibling;\r\n const hiddenCols = findAll(childRow, `.${RESPONSIVE_CLASS}-hidden`);\r\n\r\n for (const col of hiddenCols) {\r\n // We don't really need to care where we insert them since we are going to redraw anyway\r\n tr.appendChild(col);\r\n setAttribute(col, \"hidden\");\r\n }\r\n\r\n childRow.parentElement.removeChild(childRow);\r\n } else {\r\n addClass(tr, `${RESPONSIVE_CLASS}-expanded`);\r\n open.style.display = \"none\";\r\n close.style.display = \"unset\";\r\n\r\n // Create a child row and move rows into it\r\n const childRow = ce(\"tr\");\r\n insertAfter(childRow, tr);\r\n addClass(childRow, `${RESPONSIVE_CLASS}-child-row`);\r\n\r\n const childRowTd = ce(\"td\", childRow);\r\n setAttribute(childRowTd, \"colspan\", this.grid.columnsLength(true));\r\n\r\n const childTable = ce(\"table\", childRowTd);\r\n addClass(childTable, `${RESPONSIVE_CLASS}-table`);\r\n\r\n const hiddenCols = findAll(tr, `.${RESPONSIVE_CLASS}-hidden`);\r\n const idealWidth = this.computeLabelWidth();\r\n\r\n for (const col of hiddenCols) {\r\n const childTableRow = ce(\"tr\", childTable);\r\n\r\n // Add label\r\n const label = col.dataset.name;\r\n const labelCol = ce(\"th\", childTableRow);\r\n // It looks much better when aligned with an actual col\r\n labelCol.style.width = `${idealWidth}px`;\r\n labelCol.innerHTML = label;\r\n\r\n // Add actual row\r\n childTableRow.appendChild(col);\r\n removeAttribute(col, \"hidden\");\r\n }\r\n }\r\n\r\n this.unblockObserver();\r\n }\r\n}\r\n\r\nexport default ResponsiveGrid;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport interpolate from \"../utils/interpolate.js\";\r\nimport { dispatch, on, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Add action on rows\r\n */\r\nclass RowActions extends BasePlugin {\r\n /**\r\n * @returns {Boolean}\r\n */\r\n hasActions() {\r\n return this.grid.options.actions.length > 0;\r\n }\r\n\r\n /**\r\n *\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n makeActionHeader(tr) {\r\n const actionsTh = document.createElement(\"th\");\r\n setAttribute(actionsTh, \"role\", \"columnheader button\");\r\n setAttribute(actionsTh, \"aria-colindex\", this.grid.columnsLength(true));\r\n actionsTh.classList.add(...[\"dg-actions\", \"dg-not-sortable\", \"dg-not-resizable\", this.actionClass]);\r\n actionsTh.tabIndex = 0;\r\n tr.appendChild(actionsTh);\r\n }\r\n\r\n /**\r\n *\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n makeActionFilter(tr) {\r\n const actionsTh = document.createElement(\"th\");\r\n actionsTh.setAttribute(\"role\", \"columnheader button\");\r\n setAttribute(actionsTh, \"aria-colindex\", this.grid.columnsLength(true));\r\n actionsTh.classList.add(...[\"dg-actions\", this.actionClass]);\r\n actionsTh.tabIndex = 0;\r\n tr.appendChild(actionsTh);\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n * @param {Object} item\r\n */\r\n makeActionRow(tr, item) {\r\n const labels = this.grid.labels;\r\n const td = document.createElement(\"td\");\r\n setAttribute(td, \"role\", \"gridcell\");\r\n setAttribute(td, \"aria-colindex\", this.grid.columnsLength(true));\r\n td.classList.add(...[\"dg-actions\", this.actionClass]);\r\n td.tabIndex = 0;\r\n\r\n // Add menu toggle\r\n const actionsToggle = document.createElement(\"button\");\r\n actionsToggle.classList.add(\"dg-actions-toggle\");\r\n actionsToggle.innerHTML = \"\u2630\";\r\n td.appendChild(actionsToggle);\r\n on(actionsToggle, \"click\", (ev) => {\r\n ev.stopPropagation();\r\n ev.target.parentElement.classList.toggle(\"dg-actions-expand\");\r\n });\r\n\r\n for (const action of this.grid.options.actions) {\r\n const button = document.createElement(\"button\");\r\n if (action.html) {\r\n button.innerHTML = action.html;\r\n } else {\r\n button.innerText = action.title ?? action.name;\r\n }\r\n if (action.title) {\r\n button.title = action.title;\r\n }\r\n if (action.url) {\r\n button.type = \"submit\";\r\n button.formAction = interpolate(action.url, item);\r\n }\r\n if (action.class) {\r\n button.classList.add(...action.class.split(\" \"));\r\n }\r\n const actionHandler = (ev) => {\r\n ev.stopPropagation();\r\n if (action.confirm) {\r\n const c = confirm(labels.areYouSure);\r\n if (!c) {\r\n ev.preventDefault();\r\n return;\r\n }\r\n }\r\n dispatch(this.grid, \"action\", {\r\n data: item,\r\n action: action.name,\r\n });\r\n };\r\n button.addEventListener(\"click\", actionHandler);\r\n td.appendChild(button);\r\n\r\n // Row action\r\n if (action.default) {\r\n tr.classList.add(\"dg-actionable\");\r\n tr.addEventListener(\"click\", actionHandler);\r\n }\r\n }\r\n\r\n tr.appendChild(td);\r\n }\r\n\r\n get actionClass() {\r\n if (this.grid.options.actions.length < 3 && !this.grid.options.collapseActions) {\r\n return `dg-actions-${this.grid.options.actions.length}`;\r\n }\r\n return \"dg-actions-more\";\r\n }\r\n}\r\n\r\nexport default RowActions;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport { dispatch } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Make editable inputs in rows\r\n */\r\nclass EditableColumn extends BasePlugin {\r\n /**\r\n *\r\n * @param {HTMLTableCellElement} td\r\n * @param {import(\"../data-grid\").Column} column\r\n * @param {Object} item\r\n * @param {number} i\r\n */\r\n makeEditableInput(td, column, item, i) {\r\n const gridId = this.grid.getAttribute(\"id\");\r\n const input = document.createElement(\"input\");\r\n input.type = column.editableType || \"text\";\r\n if (input.type === \"email\") {\r\n input.inputMode = \"email\";\r\n }\r\n if (input.type === \"decimal\") {\r\n input.type = \"text\";\r\n input.inputMode = \"decimal\";\r\n }\r\n input.autocomplete = \"off\";\r\n input.spellcheck = false;\r\n input.tabIndex = 0;\r\n input.classList.add(\"dg-editable\");\r\n input.name = `${gridId.replace(\"-\", \"_\")}[${i + 1}][${column.field}]`;\r\n input.value = item[column.field];\r\n input.dataset.field = column.field;\r\n\r\n // Prevent row action\r\n input.addEventListener(\"click\", (ev) => ev.stopPropagation());\r\n // Enter validates edit\r\n input.addEventListener(\"keypress\", (ev) => {\r\n if (ev.type === \"keypress\") {\r\n const key = ev.keyCode || ev.key;\r\n if (key === 13 || key === \"Enter\") {\r\n input.blur();\r\n ev.preventDefault();\r\n }\r\n }\r\n });\r\n // Save on blur\r\n input.addEventListener(\"blur\", () => {\r\n // Only fire on update\r\n if (input.value === item[input.dataset.field]) {\r\n return;\r\n }\r\n // Update underlying data\r\n item[input.dataset.field] = input.value;\r\n // Notify\r\n dispatch(this.grid, \"edit\", {\r\n data: item,\r\n value: input.value,\r\n });\r\n });\r\n td.appendChild(input);\r\n }\r\n}\r\n\r\nexport default EditableColumn;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport { $ } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Adds an element for showing a spinning icon on grid loading.\r\n */\r\nclass SpinnerSupport extends BasePlugin {\n connected() {\n // Inserts spinner\r\n if (this.grid.options.spinnerClass && this.grid.plugins.SpinnerSupport) {\r\n this.add();\r\n }\r\n }\n\r\n /**\r\n * Adds a spinner element with its associated css styles.\r\n */\r\n add() {\r\n const grid = this.grid;\r\n const classes = grid.options.spinnerClass;\r\n if (!classes) {\r\n return;\r\n }\r\n const cls = classes\r\n .split(\" \")\r\n .map((e) => `.${e}`)\r\n .join(\"\");\r\n\r\n const template = `\r\n\r\n`;\r\n if (!$(\"#dg-styles\")) {\r\n const styleParent = $(\"head\") ?? $(\"body\");\r\n const position = /head/i.test(styleParent.tagName) ? \"beforeend\" : \"afterbegin\";\r\n styleParent.insertAdjacentHTML(position, template);\r\n }\r\n !$(`i${cls}`, grid) && grid.insertAdjacentHTML(\"afterbegin\", ``);\r\n }\r\n}\r\n\r\nexport default SpinnerSupport;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport { findAll } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * @typedef GridState\r\n * @property {Object} meta\r\n * @property {Number} pages\r\n * @property {Number} page\r\n * @property {Number} perPage\r\n * @property {Object} filters\r\n * @property {Array} columns\r\n * @property {String} sort\r\n * @property {String} sortDir\r\n * @property {Number} scrollTo\r\n */\r\n\r\nclass SaveState extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n this.cachedState = null;\r\n this.isFilterSortSet = false;\r\n this.isDataLoaded = false;\r\n this.isScrolled = false;\r\n this.log(\"Init\");\r\n }\r\n\r\n async connected() {\r\n this.log(\"connected\");\r\n const grid = this.grid;\r\n\r\n this.log(grid.options);\n\r\n if (!grid.options.saveState) {\r\n this.log(\"disabled\");\r\n return;\r\n }\r\n\r\n this.log(\"enabled\");\r\n\r\n const cachedState = this._getState();\r\n if (cachedState) {\n const waitForColumns = async () => { // Use async/await to wait for columns to be available\n if (!grid.options.server) return;\n let timeout = 500, // Timeout (in millisecond) to wait for columns to be set\n start = Date.now(), colAbsent;\n while ((colAbsent = !grid.options.columns?.length) && Date.now() - start < timeout) {\n await new Promise(resolve => requestAnimationFrame(resolve));\n }\n colAbsent && this.log(\"Timeout waiting for columns.\");\n };\n const restoreState = async () => { // Ensures columns are loaded before state restoration\n await waitForColumns();\n\r\n this.log(\"hide columns\");\r\n\r\n for (const col of cachedState.columns) {\r\n if (col.hidden) {\r\n const hideCol = grid.options.columns.find((c) => c.field === col.field);\r\n hideCol.hidden = true;\r\n }\r\n }\r\n\r\n this.log(\"set: meta, pages\");\r\n grid.options.perPage = cachedState.perPage;\r\n if (grid.options.server) {\r\n grid.meta = cachedState.meta;\r\n grid.pages = cachedState.pages;\r\n grid.page = cachedState.page;\r\n }\n };\n await restoreState();\n }\r\n\r\n this.cachedState = cachedState;\n this.log(\"cachedState\", this.cachedState);\n\r\n const dgLoadData = grid.loadData;\r\n grid.loadData = function (...args) {\r\n return dgLoadData.apply(this, args).finally(() => {\n const saveState = this.plugins.SaveState;\r\n saveState.log(\"loadData\", this.options.columns);\n\r\n if (!grid.classList.contains(\"dg-initialized\")) {\r\n saveState.log(\"not init, loadData skipped\");\r\n return;\r\n }\r\n\r\n saveState.log(\"loadData finished, set param controls\", this.options.columns);\r\n\r\n if (saveState.cachedState && !saveState.isFilterSortSet) {\r\n saveState.log(\"set sort and filters\");\r\n\r\n const sortableHeaders = findAll(grid, \"thead tr.dg-head-columns th[aria-sort]\");\r\n for (const el of sortableHeaders) {\r\n el.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n\r\n grid.querySelector(`thead tr.dg-head-columns th[field='${saveState.cachedState.sort}']`)\n ?.setAttribute(\"aria-sort\", saveState.cachedState.sortDir);\r\n\r\n const filters = findAll(grid.filterRow, \"[id^=dg-filter]\");\r\n saveState.log(\"filters\", filters);\r\n\r\n for (const el of filters) {\r\n el.value = saveState?.cachedState?.filters?.[el.dataset.name] ?? \"\";\r\n saveState.log({ name: el.dataset.name, val: el.value, saveState });\r\n }\r\n saveState.isFilterSortSet = true;\r\n }\r\n\r\n /** @type {GridState} */\r\n const newState = {\r\n meta: grid.meta,\r\n pages: grid.pages,\r\n page: grid.page,\r\n perPage: grid.options.perPage,\r\n filters: {},\r\n columns: grid.options.columns.map((col) => ({ field: col.field, hidden: col.hidden })),\r\n sort: grid.getSort(),\r\n sortDir: grid.getSortDir(),\r\n scrollTo: window.scrollY,\r\n };\r\n\r\n const filters = grid.getFilters();\r\n saveState.log(\"filters\", filters);\r\n\r\n for (const key of Object.keys(filters)) {\r\n newState.filters[key] = filters[key] ?? \"\";\r\n saveState.log({ key, val: filters[key], newState, filters });\r\n }\r\n\r\n saveState.log(\"store new state\", newState);\r\n saveState._setState(newState);\r\n\r\n if (!grid.options.server && saveState.cachedState && !saveState.isDataLoaded) {\r\n saveState.isDataLoaded = true;\r\n grid.filterData();\r\n grid.page = saveState.cachedState.page;\r\n grid.pageChanged();\r\n saveState.log(\"data loaded\");\r\n }\r\n });\r\n };\r\n\r\n const updateState = () => {\r\n const saveState = grid.plugins.SaveState;\r\n const state = saveState._getState();\r\n if (!state) {\r\n return;\r\n }\r\n state.columns = grid.options.columns.map((col) => ({ field: col.field, hidden: col.hidden }));\r\n state.sort = grid.getSort();\r\n state.sortDir = grid.getSortDir();\r\n state.scrollTo = window.scrollY;\r\n saveState._setState(state);\r\n };\r\n\r\n document.addEventListener(\"scrollend\", updateState);\r\n grid.addEventListener(\"headerRendered\", updateState);\r\n\r\n grid.addEventListener(\"bodyRendered\", (ev) => {\r\n if (!grid.classList.contains(\"dg-initialized\") || grid.classList.contains(\"dg-loading\")) {\r\n return;\r\n }\r\n\r\n if (!grid.options.server) {\r\n updateState();\r\n }\r\n\r\n const saveState = grid.plugins.SaveState;\r\n if (!saveState.cachedState || !saveState.isFilterSortSet) {\r\n return;\r\n }\r\n\r\n if (!saveState.isDataLoaded) {\r\n saveState.isDataLoaded = true;\n grid.reload();\r\n saveState.log(\"***grid reloaded\");\r\n } else if (!saveState.isScrolled) {\r\n saveState.isScrolled = true;\r\n window.scrollTo({ top: saveState.cachedState.scrollTo, left: 0, behavior: \"instant\" });\r\n }\r\n });\r\n }\r\n\r\n log(...data) {\r\n this.grid.log(\"[Save-State] \", ...data);\r\n }\r\n\r\n /**\r\n * @returns {GridState}\r\n */\r\n _getState() {\r\n let state;\r\n try {\r\n state = JSON.parse(sessionStorage.getItem(`gridSaveState_${this.grid.id}`));\r\n } catch (_) {}\r\n return state;\r\n }\r\n\r\n /**\r\n * @param {GridState} state\r\n */\r\n _setState(state) {\r\n sessionStorage.setItem(`gridSaveState_${this.grid.id}`, JSON.stringify(state));\r\n }\r\n}\r\n\r\nexport default SaveState;\r\n", "/**\r\n * Data Grid custom element\r\n * https://github.com/lekoala/data-grid/\r\n * @license MIT\r\n */\r\n\r\nimport DataGrid from \"./src/data-grid.js\";\r\n// Optional plugins\r\nimport ColumnResizer from \"./src/plugins/column-resizer.js\";\r\nimport ContextMenu from \"./src/plugins/context-menu.js\";\r\nimport DraggableHeaders from \"./src/plugins/draggable-headers.js\";\r\nimport TouchSupport from \"./src/plugins/touch-support.js\";\r\nimport SelectableRows from \"./src/plugins/selectable-rows.js\";\r\nimport FixedHeight from \"./src/plugins/fixed-height.js\";\r\nimport AutosizeColumn from \"./src/plugins/autosize-column.js\";\r\nimport ResponsiveGrid from \"./src/plugins/responsive-grid.js\";\r\nimport RowActions from \"./src/plugins/row-actions.js\";\r\nimport EditableColumn from \"./src/plugins/editable-column.js\";\r\nimport SpinnerSupport from \"./src/plugins/spinner-support.js\";\r\nimport SaveState from \"./src/plugins/save-state.js\";\r\n\r\n// Using shorthand property names\r\n// This make them reserved and keys will be preserved\r\n// Actual class names are renamed\r\nDataGrid.registerPlugins({\r\n ColumnResizer,\r\n ContextMenu,\r\n DraggableHeaders,\r\n TouchSupport,\r\n SelectableRows,\r\n FixedHeight,\r\n AutosizeColumn,\r\n ResponsiveGrid,\r\n RowActions,\r\n EditableColumn,\r\n SpinnerSupport,\r\n SaveState\r\n});\r\n\r\n// Prevent errors if included multiple times\r\nif (!customElements.get(\"data-grid\")) {\r\n customElements.define(\"data-grid\", DataGrid);\r\n}\r\n\r\nexport default DataGrid;\r\n\r\nconst global = typeof globalThis !== \"undefined\" ? globalThis : self;\r\nglobal.DataGrid = DataGrid;"],
+ "mappings": "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",
"names": ["col", "e", "th", "labels", "filters", "data_grid_default"]
}
diff --git a/dist/data-grid.min.css b/dist/data-grid.min.css
index 460d654..911663e 100644
--- a/dist/data-grid.min.css
+++ b/dist/data-grid.min.css
@@ -1,3 +1,3 @@
-@keyframes dataGridShow{0%{opacity:1}100%{opacity:.5}}data-grid{--padding: 0.5rem;--padding-x: 0.75rem;--padding-y: 0.5rem;--padding-y-header: 0.75rem;--padding-half: calc(var(--padding) / 2);--color-rgb: var(--bs-primary-rgb, 13, 110, 253);--color: rgb(var(--color-rgb));--highlight-color: #fffcee;--body-background: var(--bs-table-bg, #fff);--striped-background: rgba(0, 0, 0, 0.05);--header-background: var(--bs-gray-200, #e9ecef);--header-color: var(--bs-dark, #212529);--input-background: var(--bs-body-bg, #ffffff);--input-border-color: var(--bs-border-color, #e9ecef);--btn-background: var(--bs-body-bg, #ffffff);--btn-color: var(--color);--btn-border-color: var(--bs-border-color, #e9ecef);--body-bg: var(--bs-body-bg, #212529);--body-color: var(--bs-body-color, #212529);--icon-scale: 1;--border-radius: 0.25rem;--row-border-color: #f2f2f2;--responsive-width: 60%;--black: var(--bs-black, #000);--white: var(--bs-white, #fff);--gray: var(--bs-gray, #6c757d);--gray-dark: var(--bs-gray-dark, #343a40);--gray-100: var(--bs-gray-100, #f8f9fa);--gray-200: var(--bs-gray-200, #e9ecef);--gray-300: var(--bs-gray-300, #dee2e6);--gray-400: var(--bs-gray-400, #ced4da);--gray-500: var(--bs-gray-500, #adb5bd);--gray-600: var(--bs-gray-600, #6c757d);--gray-700: var(--bs-gray-700, #495057);--gray-800: var(--bs-gray-800, #343a40);--gray-900: var(--bs-gray-900, #212529);display:block;min-height:6rem;position:relative}data-grid{--scroller-color: 0, 0%;--scroller-color-lightness: 80%;--scroller-hover-factor: 0.8;--scroller-thumb: hsl(var(--scroller-color), var(--scroller-color-lightness));--scroller-thumb-hover: hsl(var(--scroller-color), calc(var(--scroller-color-lightness) * var(--scroller-hover-factor)));--scroller-background: transparent;scrollbar-color:var(--scroller-thumb) var(--scroller-background);scrollbar-width:thin}data-grid::-webkit-scrollbar{width:8px;height:8px}data-grid::-webkit-scrollbar-track{background:rgba(0,0,0,0)}data-grid::-webkit-scrollbar-thumb{background:var(--scroller-thumb)}data-grid::-webkit-scrollbar-thumb:hover{background:var(--scroller-thumb-hover)}data-grid>table[role=grid] tr.dg-head-columns:is(:empty,:has(>:first-child:not([scope=col]))){display:none}data-grid img{border:none;height:auto;max-width:100%;vertical-align:middle}data-grid [hidden]{display:none}data-grid table{display:table;table-layout:fixed;width:100%;max-width:100%;white-space:normal;background:var(--body-background)}data-grid thead,data-grid tfoot{background-color:var(--header-background);color:var(--header-color)}data-grid.dg-loading:not(.dg-initialized) thead,data-grid.dg-loading:not(.dg-initialized) tfoot{background:none}data-grid.dg-loading tbody{animation-name:dataGridShow;animation-timing-function:ease-in;animation-fill-mode:forwards;animation-duration:.3s;pointer-events:none}data-grid.dg-loading:not(:has(th)) tfoot{display:none}data-grid tr{position:relative}data-grid th,data-grid td{empty-cells:show;padding:var(--padding-y) var(--padding-x);text-align:left}data-grid th[tabindex],data-grid td[tabindex]{outline:none;word-break:normal}data-grid th{font-weight:bold;padding:var(--padding-y-header) var(--padding-x)}data-grid th,data-grid td{position:relative;overflow:hidden;text-align:left;text-overflow:ellipsis;white-space:nowrap}data-grid th.dg-wrap,data-grid td.dg-wrap{white-space:normal;word-break:break-all}data-grid .dg-expandable{cursor:pointer}data-grid .dg-expandable.dg-expanded td{white-space:normal;word-break:break-all}data-grid .dg-selectable label{display:flex;align-items:center;margin:0}data-grid .dg-clickable-cell{margin:0;position:absolute;top:0;left:0;width:100%;height:100%;cursor:pointer;display:flex;align-items:center;justify-content:center}data-grid[sticky] table thead,data-grid[sticky] table tfoot{z-index:2;position:sticky;margin:0;border:0}data-grid[sticky] table thead{inset-block-start:-1px}data-grid[sticky] table tfoot{inset-block-end:-1px}data-grid .dg-nav-icon,data-grid .dg-skip-icon{width:22px;height:22px;box-sizing:border-box;position:absolute;display:block;top:50%;left:50%;transform:translate(-50%, -50%) scale(var(--icon-scale, 1))}data-grid .dg-nav-icon:before,data-grid .dg-nav-icon:after,data-grid .dg-skip-icon:before,data-grid .dg-skip-icon:after{content:"";display:block;box-sizing:border-box;position:absolute}data-grid .dg-nav-icon::before{width:0;height:10px;border-top:5px solid rgba(0,0,0,0);border-bottom:5px solid rgba(0,0,0,0);border-left:6px solid;top:6px;left:9px}data-grid .dg-skip-icon::before{width:3px;height:10px;background:currentColor;top:6px;left:14px}data-grid .dg-skip-icon::after{width:0;height:10px;border-top:5px solid rgba(0,0,0,0);border-bottom:5px solid rgba(0,0,0,0);border-left:6px solid;top:6px;left:7px}data-grid .dg-rotate{transform:rotate(-180deg)}data-grid button{background-color:var(--btn-background);border:solid 1px var(--btn-border-color);border-radius:var(--border-radius);color:var(--body-color);height:2rem;margin:0 .2rem;padding:0 .5rem;pointer-events:all;text-align:center;cursor:pointer}data-grid button:hover{opacity:.7}data-grid button:disabled:hover{background-color:inherit;border-color:inherit}data-grid input[type=checkbox]{margin:0;padding:0}data-grid input:not([type=checkbox]),data-grid select{background-color:var(--input-background, "#fff");color:currentColor;box-sizing:border-box;border:1px solid var(--input-border-color, "#f0f0f0");border-radius:var(--border-radius);height:2rem;margin:0 .2rem;padding:0 var(--padding);max-width:none}data-grid input:not([type=checkbox]):focus,data-grid select:focus,data-grid button:focus{box-shadow:0 0 0 var(--padding-half) rgba(var(--color-rgb), 0.25);outline:0}data-grid input:not([type=checkbox])[disabled],data-grid input:not([type=checkbox]):disabled,data-grid select[disabled],data-grid select:disabled,data-grid button[disabled],data-grid button:disabled{opacity:.35;pointer-events:none}data-grid thead tr:nth-child(2) th{padding:0 2px 0 0;background-color:rgba(0,0,0,0)}data-grid thead tr:nth-child(2) th>*{width:100%;border-radius:0;margin:0}data-grid thead tr:nth-child(2) th input:focus{box-shadow:inset 0px 0px 0px 1px var(--color)}data-grid tbody td.dg-editable-col{padding:0;height:0}data-grid tbody td input.dg-editable{width:100%;background:rgba(0,0,0,0);border:0;border-radius:0;margin:0;box-shadow:none;height:100%}data-grid tbody td input.dg-editable:focus{box-shadow:inset 0px 0px 0px 1px var(--color)}data-grid.dg-empty tbody{height:4rem;position:relative}data-grid.dg-empty tbody:before{position:absolute;top:50%;left:50%;content:attr(data-empty);transform:translate(-50%, -50%);opacity:.5;font-size:1.5rem;text-align:center;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;width:90%}data-grid.dg-empty tr.dg-fake-row{height:4rem;border:none}data-grid.dg-empty.dg-network-error table{color:#842029;background-color:#f8d7da;border:1px solid #f5c2c7}data-grid.dg-empty.dg-network-error tbody{height:auto}data-grid.dg-empty.dg-network-error tbody:before{font-size:1.2rem}data-grid.dg-empty.dg-network-error tbody tr:not(.dg-fake-row){display:none}data-grid tbody tr{border-bottom:solid 1px var(--row-border-color)}data-grid tbody tr:nth-child(even){background-color:var(--striped-background)}data-grid tbody tr:hover{background-color:var(--highlight-color) !important}data-grid tbody tr:focus{background-color:var(--highlight-color) !important;border-bottom-color:var(--highlight-color) !important;outline:none}data-grid tfoot{min-width:280px}data-grid tfoot td{padding:var(--padding-y-header) var(--padding-x)}data-grid tfoot .dg-page-nav{display:flex;align-items:center}data-grid tfoot .dg-input-page{width:4rem}data-grid tfoot .dg-footer{display:flex;align-items:center;flex-direction:row;justify-content:space-between}data-grid tfoot .dg-pagination{display:flex;text-align:center}data-grid tfoot .dg-pagination button{position:relative;width:2rem}data-grid tfoot .dg-meta{text-align:right}data-grid tfoot.dg-footer-compact .dg-meta{display:none}data-grid tfoot.dg-footer-compact .dg-input-page{display:none}data-grid [aria-sort]{cursor:pointer;padding-right:1.5rem}data-grid [aria-sort=none]:after,data-grid [aria-sort=none]:before,data-grid [aria-sort=ascending]:before,data-grid [aria-sort=descending]:after{right:.5rem;top:calc(50% - .5rem);border:solid rgba(0,0,0,0);content:" ";height:0;width:0;position:absolute;border-color:rgba(0,0,0,0);border-width:.25rem;margin-left:-0.25rem}data-grid [aria-sort=none]:before{border-bottom-color:currentColor;opacity:.25;top:calc(50% - .6rem)}data-grid [aria-sort=none]:after{border-top-color:currentColor;opacity:.25;bottom:calc(50% - .5rem);top:auto}data-grid [aria-sort=ascending]:before{border-bottom-color:var(--body-color);opacity:.75}data-grid [aria-sort=descending]:after{border-top-color:var(--body-color);opacity:.75;bottom:calc(50% - .5rem);top:auto}[data-bs-theme=dark] data-grid{--scroller-color-lightness: 20%;--highlight-color: #43423e;--body-background: #212529;--striped-background: #2c3034;--header-background: var(--bs-gray-800, #34373b);--header-color: var(--bs-light, #e9ecef);--body-color: var(--bs-body-color, #494e53);--row-border-color: var(--bs-gray-900, #212325)}data-grid[dir=rtl] th,data-grid[dir=rtl] td{text-align:right}data-grid[dir=rtl] [aria-sort]{padding-left:1rem;padding-right:.5rem}data-grid[dir=rtl] [aria-sort=none]:after,data-grid[dir=rtl] [aria-sort=none]:before,data-grid[dir=rtl] [aria-sort=ascending]:before,data-grid[dir=rtl] [aria-sort=descending]:after{left:.75rem;right:auto}data-grid[dir=rtl] tfoot .dg-meta{text-align:left}data-grid .dg-menu{position:absolute;z-index:3;background:var(--body-bg);list-style:none;max-width:150px;margin:0;padding:var(--padding);box-shadow:0 0 1rem rgba(0,0,0,.25);border-radius:var(--border-radius)}data-grid .dg-menu li{margin:0;padding:0}data-grid .dg-menu label{display:flex;align-items:center;margin-bottom:.25em}data-grid .dg-menu input{margin-right:.5em}data-grid .dg-actions{text-overflow:initial;width:100px;text-align:right;white-space:nowrap !important}data-grid .dg-actions button{margin:0}data-grid .dg-actions button+button{margin-left:.25rem}data-grid .dg-actions .dg-actions-toggle{display:none;width:calc(100px - var(--padding-x)*2)}data-grid .dg-actions.dg-actions-1{width:100%}data-grid .dg-actions.dg-actions-2 button{width:calc(50% - .25rem)}data-grid .dg-actions.dg-actions-more button{display:none}data-grid .dg-actions.dg-actions-more button.dg-actions-toggle{display:inline-block}data-grid .dg-actions.dg-actions-expand{position:absolute;right:0;display:flex;align-items:center;justify-content:flex-end;width:100%;height:100%}data-grid .dg-actions.dg-actions-expand.dg-actions-more{width:100%}data-grid .dg-actions.dg-actions-expand.dg-actions-more button{display:inline-block}data-grid tr.dg-actionable{cursor:pointer}data-grid tr.dg-actionable:hover td{background-color:var(--highlight-color)}data-grid .dg-resizer{position:absolute;top:0;right:0;width:6px;z-index:2;cursor:col-resize;-webkit-user-select:none;-moz-user-select:none;user-select:none}data-grid .dg-resizer:before{content:"";display:block;position:absolute;top:var(--padding-y-header);height:1.5rem;right:0;width:2px;background:var(--body-color);opacity:.2}data-grid .dg-resizer:hover:before{opacity:.6}data-grid .dg-resizer.dg-resizer-active{border-right:1px dashed var(--color)}data-grid .dg-resizer.dg-resizer-active:before{opacity:.6}data-grid .dg-responsive-toggle{padding:0;text-align:center}data-grid .dg-responsive-child-row>td{padding:0}data-grid .dg-responsive-table{table-layout:auto;border:0}data-grid .dg-responsive-table td,data-grid .dg-responsive-table th{white-space:normal}data-grid .dg-responsive-table th{max-width:40%}@media only screen and (max-width: 767px){data-grid[responsive] .dg-resizer{display:none}data-grid[responsive] .dg-meta{display:none}data-grid[responsive] .dg-input-page{display:none}data-grid[responsive] table,data-grid[responsive] tbody,data-grid[responsive] tfoot,data-grid[responsive] th,data-grid[responsive] td,data-grid[responsive] tr:not([hidden]){display:block}data-grid[responsive] thead{display:flex;border-bottom:2px solid var(--header-background)}data-grid[responsive] thead>tr{flex-grow:1}data-grid[responsive] thead th{width:auto}data-grid[responsive] tbody tr{padding:0;border:1px solid var(--header-background)}data-grid[responsive] tbody td{border:none;border-bottom:1px solid var(--row-border-color);position:relative;padding-left:calc(100% - var(--responsive-width) - var(--padding)*2)}data-grid[responsive] tbody td:last-child{border:0}data-grid[responsive] tbody td:before{position:absolute;top:0;left:0;padding:var(--padding);width:calc(100% - var(--responsive-width) - var(--padding)*4);content:attr(data-name);display:block;font-weight:bold;background-color:var(--header-background)}data-grid[responsive] tbody td[role=gridcell]{padding-left:calc(100% - var(--responsive-width) - var(--padding)*4 + .5rem)}data-grid[responsive] .dg-selectable{height:28px;margin:2px 1px 2px}data-grid[responsive] td.dg-selectable::before,data-grid[responsive] td.dg-actions::before{padding:0}data-grid[responsive] td.dg-selectable label{padding:5px}data-grid[responsive] td[role=gridcell]{min-height:35px;width:auto}data-grid[responsive] td[data-name]::before{height:100%}data-grid[responsive] td.dg-actions{padding-left:inherit;width:inherit}data-grid[responsive] .dg-actions button{width:inherit !important}data-grid[responsive] tr.dg-head-columns{padding:0;width:calc(100% - var(--responsive-width) - var(--padding)*4)}data-grid[responsive] tr.dg-head-columns th[role="columnheader button"]{padding:.36em 1.3em .36em .75em}data-grid[responsive] tr.dg-head-filters{background:rgba(0,0,0,0);vertical-align:top;padding:0;width:calc(100% - (100% - var(--responsive-width) - var(--padding)*4))}data-grid[responsive] .dg-head-filters th input:not([type=checkbox],[type=radio]){height:2.25em}data-grid[responsive] .dg-head-filters th.dg-selectable{background:rgba(0,0,0,0)}data-grid[responsive] .dg-head-filters th.dg-selectable label::before{content:"Column Filters"}data-grid[responsive] tfoot .dg-page-nav{min-width:revert}data-grid[data-responsive=true] tfoot .dg-page-nav{min-width:revert}}
+@keyframes dataGridShow{0%{opacity:1}100%{opacity:.5}}data-grid{--padding: 0.5rem;--padding-x: 0.75rem;--padding-y: 0.5rem;--padding-y-header: 0.75rem;--padding-half: calc(var(--padding) / 2);--color-rgb: var(--bs-primary-rgb, 13, 110, 253);--color: rgb(var(--color-rgb));--highlight-color: #fffcee;--selected-bgcolor: var(--bs-primary-bg-subtle, #cfe2ff);--body-background: var(--bs-table-bg, #fff);--striped-background: rgba(0, 0, 0, 0.05);--header-background: var(--bs-gray-200, #e9ecef);--header-color: var(--bs-dark, #212529);--input-background: var(--bs-body-bg, #ffffff);--input-border-color: var(--bs-border-color, #e9ecef);--btn-background: var(--bs-body-bg, #ffffff);--btn-color: var(--color);--btn-border-color: var(--bs-border-color, #e9ecef);--body-bg: var(--bs-body-bg, #212529);--body-color: var(--bs-body-color, #212529);--icon-scale: 1;--border-radius: 0.25rem;--row-border-color: #f2f2f2;--responsive-width: 60%;--black: var(--bs-black, #000);--white: var(--bs-white, #fff);--gray: var(--bs-gray, #6c757d);--gray-dark: var(--bs-gray-dark, #343a40);--gray-100: var(--bs-gray-100, #f8f9fa);--gray-200: var(--bs-gray-200, #e9ecef);--gray-300: var(--bs-gray-300, #dee2e6);--gray-400: var(--bs-gray-400, #ced4da);--gray-500: var(--bs-gray-500, #adb5bd);--gray-600: var(--bs-gray-600, #6c757d);--gray-700: var(--bs-gray-700, #495057);--gray-800: var(--bs-gray-800, #343a40);--gray-900: var(--bs-gray-900, #212529);display:block;min-height:6rem;position:relative}data-grid{--scroller-color: 0, 0%;--scroller-color-lightness: 80%;--scroller-hover-factor: 0.8;--scroller-thumb: hsl(var(--scroller-color), var(--scroller-color-lightness));--scroller-thumb-hover: hsl(var(--scroller-color), calc(var(--scroller-color-lightness) * var(--scroller-hover-factor)));--scroller-background: transparent;scrollbar-color:var(--scroller-thumb) var(--scroller-background);scrollbar-width:thin}data-grid::-webkit-scrollbar{width:8px;height:8px}data-grid::-webkit-scrollbar-track{background:rgba(0,0,0,0)}data-grid::-webkit-scrollbar-thumb{background:var(--scroller-thumb)}data-grid::-webkit-scrollbar-thumb:hover{background:var(--scroller-thumb-hover)}data-grid>table[role=grid] tr.dg-head-columns:is(:empty,:has(>:first-child:not([scope=col]))){display:none}data-grid img{border:none;height:auto;max-width:100%;vertical-align:middle}data-grid [hidden]{display:none}data-grid table{display:table;table-layout:fixed;width:100%;max-width:100%;white-space:normal;background:var(--body-background)}data-grid thead,data-grid tfoot{background-color:var(--header-background);color:var(--header-color)}data-grid.dg-loading:not(.dg-initialized) thead,data-grid.dg-loading:not(.dg-initialized) tfoot{background:none}data-grid.dg-loading tbody{animation-name:dataGridShow;animation-timing-function:ease-in;animation-fill-mode:forwards;animation-duration:.3s;pointer-events:none}data-grid.dg-loading:not(:has(th)) tfoot{display:none}data-grid tr{position:relative}data-grid th,data-grid td{empty-cells:show;padding:var(--padding-y) var(--padding-x);text-align:left}data-grid th[tabindex],data-grid td[tabindex]{outline:none;word-break:normal}data-grid th{font-weight:bold;padding:var(--padding-y-header) var(--padding-x)}data-grid th,data-grid td{position:relative;overflow:hidden;text-align:left;text-overflow:ellipsis;white-space:nowrap}data-grid th.dg-wrap,data-grid td.dg-wrap{white-space:normal;word-break:break-all}data-grid .dg-expandable{cursor:pointer}data-grid .dg-expandable.dg-expanded td{white-space:normal;word-break:break-all}data-grid .dg-selectable{font-size:1em}data-grid .dg-selectable label{display:flex;align-items:center;margin:0}data-grid .dg-clickable-cell{margin:0;position:absolute;top:0;left:0;width:100%;height:100%;cursor:pointer;display:flex;align-items:center;justify-content:center}data-grid[sticky] table thead,data-grid[sticky] table tfoot{z-index:2;position:sticky;margin:0;border:0}data-grid[sticky] table thead{inset-block-start:-1px}data-grid[sticky] table tfoot{inset-block-end:-1px}data-grid .dg-nav-icon,data-grid .dg-skip-icon{width:22px;height:22px;box-sizing:border-box;position:absolute;display:block;top:50%;left:50%;transform:translate(-50%, -50%) scale(var(--icon-scale, 1))}data-grid .dg-nav-icon:before,data-grid .dg-nav-icon:after,data-grid .dg-skip-icon:before,data-grid .dg-skip-icon:after{content:"";display:block;box-sizing:border-box;position:absolute}data-grid .dg-nav-icon::before{width:0;height:10px;border-top:5px solid rgba(0,0,0,0);border-bottom:5px solid rgba(0,0,0,0);border-left:6px solid;top:6px;left:9px}data-grid .dg-skip-icon::before{width:3px;height:10px;background:currentColor;top:6px;left:14px}data-grid .dg-skip-icon::after{width:0;height:10px;border-top:5px solid rgba(0,0,0,0);border-bottom:5px solid rgba(0,0,0,0);border-left:6px solid;top:6px;left:7px}data-grid .dg-rotate{transform:rotate(-180deg)}data-grid button{background-color:var(--btn-background);border:solid 1px var(--btn-border-color);border-radius:var(--border-radius);color:var(--body-color);height:2rem;margin:0 .2rem;padding:0 .5rem;pointer-events:all;text-align:center;cursor:pointer}data-grid button:hover{opacity:.7}data-grid button:disabled:hover{background-color:inherit;border-color:inherit}data-grid input[type=checkbox]{margin:0;padding:0}data-grid input:not([type=checkbox],[type=radio]),data-grid select{background-color:var(--input-background, "#fff");color:currentColor;box-sizing:border-box;border:1px solid var(--input-border-color, "#f0f0f0");border-radius:var(--border-radius);height:2rem;margin:0 .2rem;padding:0 var(--padding);max-width:none}data-grid input:not([type=checkbox]):focus,data-grid select:focus,data-grid button:focus{box-shadow:0 0 0 var(--padding-half) rgba(var(--color-rgb), 0.25);outline:0}data-grid input:not([type=checkbox])[disabled],data-grid input:not([type=checkbox]):disabled,data-grid select[disabled],data-grid select:disabled,data-grid button[disabled],data-grid button:disabled{opacity:.35;pointer-events:none}data-grid thead tr:nth-child(2) th{padding:0 2px 0 0;background-color:rgba(0,0,0,0)}data-grid thead tr:nth-child(2) th>*{width:100%;border-radius:0;margin:0}data-grid thead tr:nth-child(2) th input:focus{box-shadow:inset 0px 0px 0px 1px var(--color)}data-grid tbody td.dg-editable-col{padding:0;height:0}data-grid tbody td input.dg-editable{width:100%;background:rgba(0,0,0,0);border:0;border-radius:0;margin:0;box-shadow:none;height:100%}data-grid tbody td input.dg-editable:focus{box-shadow:inset 0px 0px 0px 1px var(--color)}data-grid tbody tr:has(.dg-selectable [type=radio]:checked){background-color:var(--selected-bgcolor)}data-grid.dg-empty tbody{height:4rem;position:relative}data-grid.dg-empty tbody:before{position:absolute;top:50%;left:50%;content:attr(data-empty);transform:translate(-50%, -50%);opacity:.5;font-size:1.5rem;text-align:center;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;width:90%}data-grid.dg-empty tr.dg-fake-row{height:4rem;border:none}data-grid.dg-empty.dg-network-error table{color:#842029;background-color:#f8d7da;border:1px solid #f5c2c7}data-grid.dg-empty.dg-network-error tbody{height:auto}data-grid.dg-empty.dg-network-error tbody:before{font-size:1.2rem}data-grid.dg-empty.dg-network-error tbody tr:not(.dg-fake-row){display:none}data-grid tbody tr{border-bottom:solid 1px var(--row-border-color)}data-grid tbody tr:nth-child(even){background-color:var(--striped-background)}data-grid tbody tr:hover{background-color:var(--highlight-color) !important}data-grid tbody tr:focus{background-color:var(--highlight-color) !important;border-bottom-color:var(--highlight-color) !important;outline:none}data-grid tfoot{min-width:280px}data-grid tfoot td{padding:var(--padding-y-header) var(--padding-x)}data-grid tfoot .dg-page-nav{display:flex;align-items:center}data-grid tfoot .dg-input-page{width:4rem}data-grid tfoot .dg-footer{display:flex;align-items:center;flex-direction:row;justify-content:space-between}data-grid tfoot .dg-pagination{display:flex;text-align:center}data-grid tfoot .dg-pagination button{position:relative;width:2rem}data-grid tfoot .dg-meta{text-align:right}data-grid tfoot.dg-footer-compact .dg-meta{display:none}data-grid tfoot.dg-footer-compact .dg-input-page{display:none}data-grid [aria-sort]{cursor:pointer;padding-right:1.5rem}data-grid [aria-sort=none]:after,data-grid [aria-sort=none]:before,data-grid [aria-sort=ascending]:before,data-grid [aria-sort=descending]:after{right:.5rem;top:calc(50% - .5rem);border:solid rgba(0,0,0,0);content:" ";height:0;width:0;position:absolute;border-color:rgba(0,0,0,0);border-width:.25rem;margin-left:-0.25rem}data-grid [aria-sort=none]:before{border-bottom-color:currentColor;opacity:.25;top:calc(50% - .6rem)}data-grid [aria-sort=none]:after{border-top-color:currentColor;opacity:.25;bottom:calc(50% - .5rem);top:auto}data-grid [aria-sort=ascending]:before{border-bottom-color:var(--body-color);opacity:.75}data-grid [aria-sort=descending]:after{border-top-color:var(--body-color);opacity:.75;bottom:calc(50% - .5rem);top:auto}[data-bs-theme=dark] data-grid{--scroller-color-lightness: 20%;--highlight-color: #43423e;--selected-bgcolor: var(--bs-primary-bg-subtle, #031633);--body-background: #212529;--striped-background: #2c3034;--header-background: var(--bs-gray-800, #34373b);--header-color: var(--bs-light, #e9ecef);--body-color: var(--bs-body-color, #494e53);--row-border-color: var(--bs-gray-900, #212325)}data-grid[dir=rtl] th,data-grid[dir=rtl] td{text-align:right}data-grid[dir=rtl] [aria-sort]{padding-left:1rem;padding-right:.5rem}data-grid[dir=rtl] [aria-sort=none]:after,data-grid[dir=rtl] [aria-sort=none]:before,data-grid[dir=rtl] [aria-sort=ascending]:before,data-grid[dir=rtl] [aria-sort=descending]:after{left:.75rem;right:auto}data-grid[dir=rtl] tfoot .dg-meta{text-align:left}data-grid .dg-menu{position:absolute;z-index:3;background:var(--body-bg);list-style:none;max-width:150px;margin:0;padding:var(--padding);box-shadow:0 0 1rem rgba(0,0,0,.25);border-radius:var(--border-radius)}data-grid .dg-menu li{margin:0;padding:0}data-grid .dg-menu label{display:flex;align-items:center;margin-bottom:.25em}data-grid .dg-menu input{margin-right:.5em}data-grid .dg-actions{text-overflow:initial;width:100px;text-align:right;white-space:nowrap !important}data-grid .dg-actions button{margin:0}data-grid .dg-actions button+button{margin-left:.25rem}data-grid .dg-actions .dg-actions-toggle{display:none;width:calc(100px - var(--padding-x)*2)}data-grid .dg-actions.dg-actions-1{width:100%}data-grid .dg-actions.dg-actions-2 button{width:calc(50% - .25rem)}data-grid .dg-actions.dg-actions-more button{display:none}data-grid .dg-actions.dg-actions-more button.dg-actions-toggle{display:inline-block}data-grid .dg-actions.dg-actions-expand{position:absolute;right:0;display:flex;align-items:center;justify-content:flex-end;width:100%;height:100%}data-grid .dg-actions.dg-actions-expand.dg-actions-more{width:100%}data-grid .dg-actions.dg-actions-expand.dg-actions-more button{display:inline-block}data-grid tr.dg-actionable{cursor:pointer}data-grid tr.dg-actionable:hover td{background-color:var(--highlight-color)}data-grid .dg-resizer{position:absolute;top:0;right:0;width:6px;z-index:2;cursor:col-resize;-webkit-user-select:none;-moz-user-select:none;user-select:none}data-grid .dg-resizer:before{content:"";display:block;position:absolute;top:var(--padding-y-header);height:1.5rem;right:0;width:2px;background:var(--body-color);opacity:.2}data-grid .dg-resizer:hover:before{opacity:.6}data-grid .dg-resizer.dg-resizer-active{border-right:1px dashed var(--color)}data-grid .dg-resizer.dg-resizer-active:before{opacity:.6}data-grid .dg-responsive-toggle{padding:0;text-align:center}data-grid .dg-responsive-child-row>td{padding:0}data-grid .dg-responsive-table{table-layout:auto;border:0}data-grid .dg-responsive-table td,data-grid .dg-responsive-table th{white-space:normal}data-grid .dg-responsive-table th{max-width:40%}@media only screen and (max-width: 767px){data-grid[responsive] .dg-resizer{display:none}data-grid[responsive] .dg-meta{display:none}data-grid[responsive] .dg-input-page{display:none}data-grid[responsive] table,data-grid[responsive] tbody,data-grid[responsive] tfoot,data-grid[responsive] th,data-grid[responsive] td,data-grid[responsive] tr:not([hidden]){display:block}data-grid[responsive] thead{display:flex;border-bottom:2px solid var(--header-background)}data-grid[responsive] thead>tr{flex-grow:1}data-grid[responsive] thead th{width:auto}data-grid[responsive] tbody tr{padding:0;border:1px solid var(--header-background)}data-grid[responsive] tbody td{border:none;border-bottom:1px solid var(--row-border-color);position:relative;padding-left:calc(100% - var(--responsive-width) - var(--padding)*2)}data-grid[responsive] tbody td:last-child{border:0}data-grid[responsive] tbody td:before{position:absolute;top:0;left:0;padding:var(--padding);width:calc(100% - var(--responsive-width) - var(--padding)*4);content:attr(data-name);display:block;font-weight:bold;background-color:var(--header-background)}data-grid[responsive] tbody td[role=gridcell]{padding-left:calc(100% - var(--responsive-width) - var(--padding)*4 + .5rem)}data-grid[responsive] .dg-selectable{height:28px;margin:2px 1px 2px}data-grid[responsive] td.dg-selectable::before,data-grid[responsive] td.dg-actions::before{padding:0}data-grid[responsive] td.dg-selectable label{padding:5px}data-grid[responsive] td[role=gridcell]{min-height:35px;width:auto}data-grid[responsive] td[data-name]::before{height:100%}data-grid[responsive] td.dg-actions{padding-left:inherit;width:inherit}data-grid[responsive] .dg-actions button{width:inherit !important}data-grid[responsive] tr.dg-head-columns{padding:0;width:calc(100% - var(--responsive-width) - var(--padding)*4)}data-grid[responsive] tr.dg-head-columns th[role="columnheader button"]{padding:.36em 1.3em .36em .75em}data-grid[responsive] tr.dg-head-filters{background:rgba(0,0,0,0);vertical-align:top;padding:0;width:calc(100% - (100% - var(--responsive-width) - var(--padding)*4))}data-grid[responsive] .dg-head-filters th input:not([type=checkbox],[type=radio]){height:2.25em}data-grid[responsive] .dg-head-filters th.dg-selectable{background:rgba(0,0,0,0)}data-grid[responsive] .dg-head-filters th.dg-selectable label::before{content:"Column Filters"}data-grid[responsive] tfoot .dg-page-nav{min-width:revert}data-grid[data-responsive=true] tfoot .dg-page-nav{min-width:revert}}
-/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3Njc3MvX2NvcmUuc2NzcyIsIi4uL3Njc3MvX3J0bC5zY3NzIiwiLi4vc2Nzcy9fbWVudS5zY3NzIiwiLi4vc2Nzcy9fYWN0aW9ucy5zY3NzIiwiLi4vc2Nzcy9fcmVzaXplci5zY3NzIiwiLi4vc2Nzcy9fcmVzcG9uc2l2ZS5zY3NzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUtBLHdCQUNFLEdBQ0UsU0FBQSxDQUdGLEtBQ0UsVUFBQSxDQUFBLENBSUosVUFDRSxpQkFBQSxDQUNBLG9CQUFBLENBQ0EsbUJBQUEsQ0FDQSwyQkFBQSxDQUNBLHdDQUFBLENBQ0EsZ0RBQUEsQ0FDQSw4QkFBQSxDQUVBLDBCQUFBLENBQ0EsMkNBQUEsQ0FDQSx5Q0FBQSxDQUNBLGdEQUFBLENBQ0EsdUNBQUEsQ0FDQSw4Q0FBQSxDQUNBLHFEQUFBLENBQ0EsNENBQUEsQ0FDQSx5QkFBQSxDQUNBLG1EQUFBLENBQ0EscUNBQUEsQ0FDQSwyQ0FBQSxDQUNBLGVBQUEsQ0FDQSx3QkFBQSxDQUNBLDJCQUFBLENBQ0EsdUJBQUEsQ0FFQSw4QkFBQSxDQUNBLDhCQUFBLENBQ0EsK0JBQUEsQ0FDQSx5Q0FBQSxDQUNBLHVDQUFBLENBQ0EsdUNBQUEsQ0FDQSx1Q0FBQSxDQUNBLHVDQUFBLENBQ0EsdUNBQUEsQ0FDQSx1Q0FBQSxDQUNBLHVDQUFBLENBQ0EsdUNBQUEsQ0FDQSx1Q0FBQSxDQUVBLGFBQUEsQ0FDQSxlQUFBLENBQ0EsaUJBQUEsQ0FHQSxVQUNFLHVCQUFBLENBQ0EsK0JBQUEsQ0FDQSw0QkFBQSxDQUNBLDZFQUFBLENBRUEsd0hBQUEsQ0FDQSxrQ0FBQSxDQUNBLGdFQUFBLENBQ0Esb0JBQUEsQ0FFQSw2QkFDRSxTQUFBLENBQ0EsVUFBQSxDQUdGLG1DQUNFLHdCQUFBLENBR0YsbUNBQ0UsZ0NBQUEsQ0FHRix5Q0FDRSxzQ0FBQSxDQU9BLDhGQUNFLFlBQUEsQ0FLTixjQUNFLFdBQUEsQ0FDQSxXQUFBLENBQ0EsY0FBQSxDQUNBLHFCQUFBLENBR0YsbUJBQ0Us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 */
\ No newline at end of file
+/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3Njc3MvX2NvcmUuc2NzcyIsIi4uL3Njc3MvX3J0bC5zY3NzIiwiLi4vc2Nzcy9fbWVudS5zY3NzIiwiLi4vc2Nzcy9fYWN0aW9ucy5zY3NzIiwiLi4vc2Nzcy9fcmVzaXplci5zY3NzIiwiLi4vc2Nzcy9fcmVzcG9uc2l2ZS5zY3NzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUtBLHdCQUNFLEdBQ0UsU0FBQSxDQUdGLEtBQ0UsVUFBQSxDQUFBLENBSUosVUFDRSxpQkFBQSxDQUNBLG9CQUFBLENBQ0EsbUJBQUEsQ0FDQSwyQkFBQSxDQUNBLHdDQUFBLENBQ0EsZ0RBQUEsQ0FDQSw4QkFBQSxDQUVBLDBCQUFBLENBQ0Esd0RBQUEsQ0FDQSwyQ0FBQSxDQUNBLHlDQUFBLENBQ0EsZ0RBQUEsQ0FDQSx1Q0FBQSxDQUNBLDhDQUFBLENBQ0EscURBQUEsQ0FDQSw0Q0FBQSxDQUNBLHlCQUFBLENBQ0EsbURBQUEsQ0FDQSxxQ0FBQSxDQUNBLDJDQUFBLENBQ0EsZUFBQSxDQUNBLHdCQUFBLENBQ0EsMkJBQUEsQ0FDQSx1QkFBQSxDQUVBLDhCQUFBLENBQ0EsOEJBQUEsQ0FDQSwrQkFBQSxDQUNBLHlDQUFBLENBQ0EsdUNBQUEsQ0FDQSx1Q0FBQSxDQUNBLHVDQUFBLENBQ0EsdUNBQUEsQ0FDQSx1Q0FBQSxDQUNBLHVDQUFBLENBQ0EsdUNBQUEsQ0FDQSx1Q0FBQSxDQUNBLHVDQUFBLENBRUEsYUFBQSxDQUNBLGVBQUEsQ0FDQSxpQkFBQSxDQUdBLFVBQ0UsdUJBQUEsQ0FDQSwrQkFBQSxDQUNBLDRCQUFBLENBQ0EsNkVBQUEsQ0FFQSx3SEFBQSxDQUNBLGtDQUFBLENBQ0EsZ0VBQUEsQ0FDQSxvQkFBQSxDQUVBLDZCQUNFLFNBQUEsQ0FDQSxVQUFBLENBR0YsbUNBQ0Usd0JBQUEsQ0FHRixtQ0FDRSxnQ0FBQSxDQUdGLHlDQUNFLHNDQUFBLENBT0EsOEZBQ0UsWUFBQSxDQUtOLGNBQ0UsV0FBQSxDQUNBLFdBQUEsQ0FDQSxjQUFBLENBQ0EscUJBQUEs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 */
\ No newline at end of file
diff --git a/dist/data-grid.min.css.map b/dist/data-grid.min.css.map
index e43e0ff..603aa91 100644
--- a/dist/data-grid.min.css.map
+++ b/dist/data-grid.min.css.map
@@ -1 +1 @@
-{"version":3,"sourceRoot":"","sources":["../scss/_core.scss","../scss/_rtl.scss","../scss/_menu.scss","../scss/_actions.scss","../scss/_resizer.scss","../scss/_responsive.scss"],"names":[],"mappings":"AAKA,wBACE,GACE,UAGF,KACE,YAIJ,UACE,kBACA,qBACA,oBACA,4BACA,yCACA,iDACA,+BAEA,2BACA,4CACA,0CACA,iDACA,wCACA,+CACA,sDACA,6CACA,0BACA,oDACA,sCACA,4CACA,gBACA,yBACA,4BACA,wBAEA,+BACA,+BACA,gCACA,0CACA,wCACA,wCACA,wCACA,wCACA,wCACA,wCACA,wCACA,wCACA,wCAEA,cACA,gBACA,kBAGA,UACE,wBACA,gCACA,6BACA,8EAEA,yHACA,mCACA,iEACA,qBAEA,6BACE,UACA,WAGF,mCACE,yBAGF,mCACE,iCAGF,yCACE,uCAOA,8FACE,aAKN,cACE,YACA,YACA,eACA,sBAGF,mBACE,aAGF,gBACE,cAGA,mBACA,WACA,eACA,mBAEA,kCAGF,gCAEE,0CACA,0BAME,gGAEE,gBAIJ,2BACE,4BACA,kCACA,6BACA,uBACA,oBAIA,yCACE,aAKN,aACE,kBAGF,0BAEE,iBACA,0CACA,gBAEA,8CACE,aACA,kBAIJ,aACE,iBACA,iDAIF,0BAEE,kBACA,gBACA,gBAEA,uBACA,mBAGA,0CACE,mBACA,qBAKJ,yBACE,eAEA,wCACE,mBACA,qBAKF,+BACE,aACA,mBACA,SAIJ,6BACE,SACA,kBACA,MACA,OACA,WACA,YACA,eACA,aACA,mBACA,uBAOA,4DAEE,UACA,gBACA,SACA,SAIF,8BACE,uBAGF,8BACE,qBAKJ,+CAEE,WACA,YACA,sBACA,kBACA,cACA,QACA,SACA,4DAEA,wHAEE,WACA,cACA,sBACA,kBAIJ,+BACE,QACA,YACA,mCACA,sCACA,sBACA,QACA,SAIA,gCACE,UACA,YACA,wBACA,QACA,UAGF,+BACE,QACA,YACA,mCACA,sCACA,sBACA,QACA,SAIJ,qBACE,0BAIF,iBACE,uCACA,yCACA,mCACA,wBACA,YACA,eACA,gBACA,mBACA,kBACA,eAEA,uBACE,WAGF,gCACE,yBACA,qBAKJ,+BACE,SACA,UAGF,sDAEE,iDACA,mBACA,sBACA,sDACA,mCACA,YACA,eACA,yBACA,eAMA,yFACE,kEACA,UAGF,uMAEE,YACA,oBAKJ,mCACE,kBACA,+BAEA,qCACE,WACA,gBACA,SAIA,+CACE,8CAMN,mCACE,UACA,SAGF,qCACE,WACA,yBACA,SACA,gBACA,SACA,gBACA,YAEA,2CACE,8CAMF,yBACE,YACA,kBAEA,gCACE,kBACA,QACA,SACA,yBACA,gCACA,WACA,iBACA,kBACA,mBACA,uBACA,gBACA,UAKF,kCACE,YACA,YAKF,0CACE,cACA,yBACA,yBAGF,0CACE,YAEA,iDACE,iBAGF,+DACE,aAOR,mBAKE,gDAJA,mCACE,2CAKF,yBACE,mDAGF,yBACE,mDACA,sDACA,aAKJ,gBACE,gBAEA,mBACE,iDAGF,6BACE,aACA,mBAIF,+BACE,WAGF,2BACE,aACA,mBACA,mBACA,8BAGF,+BACE,aACA,kBAEA,sCAEE,kBACA,WAIJ,yBAGE,iBAIA,2CACE,aAGF,iDACE,aAMN,sBACE,eACA,qBAGF,iJAIE,YACA,sBACA,2BACA,YACA,SACA,QACA,kBACA,2BACA,oBACA,qBAIA,kCACE,iCACA,YACA,sBAGF,iCACE,8BACA,YACA,yBACA,SAIJ,uCACE,sCACA,YAGF,uCACE,mCACA,YACA,yBACA,SAIJ,+BACE,gCACA,2BACA,2BACA,8BACA,iDACA,yCACA,4CACA,gDC1jBE,4CAEE,iBAEF,+BACE,kBACA,oBAEF,qLAIE,YACA,WAEF,kCACE,gBCjBJ,mBACE,kBACA,UACA,0BACA,gBACA,gBACA,SACA,uBACA,oCACA,mCAEA,sBACE,SACA,UAEF,yBACE,aACA,mBACA,oBAEF,yBACE,kBCrBJ,sBACE,sBACA,YACA,iBACA,8BAEA,6BACE,SAEA,oCACE,mBAGJ,yCACE,aACA,uCAEF,mCACE,WAGF,0CACE,yBAEF,6CACE,aAEA,+DACE,qBAGJ,wCACE,kBACA,QACA,aACA,mBACA,yBACA,WACA,YAEF,wDACE,WAEA,+DACE,qBAIN,2BACE,eAEA,oCACE,wCCpDJ,sBACE,kBACA,MACA,QACA,UACA,UACA,kBACA,iBAEA,6BACE,WACA,cACA,kBACA,4BACA,cACA,QACA,UACA,6BACA,WAEF,mCACE,WAEF,wCACE,qCAEA,+CACE,WC3BN,gCACE,UACA,kBAEF,sCACE,UAEF,+BACE,kBACA,SAEA,oEAEE,mBAGF,kCACE,cAMN,0CAGI,kCACE,aAIF,+BACE,aAEF,qCACE,aAIF,6KAME,cAIF,4BACE,aASA,iDAPA,+BACE,YAEF,+BACE,WAQF,+BACE,UACA,0CAEF,+BACE,YACA,gDACA,kBACA,qEAEA,0CACE,SAEF,sCACE,kBACA,MACA,OACA,uBACA,8DACA,wBACA,cACA,iBACA,0CAEF,8CACE,6EAMN,qCACE,YACA,mBAIA,2FAEE,UAEF,6CACE,YAEF,wCACE,gBACA,WAEF,4CACE,YAEF,oCACE,qBACA,cAGJ,yCACE,yBAGA,yCACE,UACA,8DAEA,wEACE,gCAGJ,yCACE,yBACA,mBACA,UACA,uEAGJ,kFACE,cAEF,wDACE,yBAEF,sEACE,yBAGF,yCACE,iBAKF,mDACE","file":"data-grid.min.css"}
\ No newline at end of file
+{"version":3,"sourceRoot":"","sources":["../scss/_core.scss","../scss/_rtl.scss","../scss/_menu.scss","../scss/_actions.scss","../scss/_resizer.scss","../scss/_responsive.scss"],"names":[],"mappings":"AAKA,wBACE,GACE,UAGF,KACE,YAIJ,UACE,kBACA,qBACA,oBACA,4BACA,yCACA,iDACA,+BAEA,2BACA,yDACA,4CACA,0CACA,iDACA,wCACA,+CACA,sDACA,6CACA,0BACA,oDACA,sCACA,4CACA,gBACA,yBACA,4BACA,wBAEA,+BACA,+BACA,gCACA,0CACA,wCACA,wCACA,wCACA,wCACA,wCACA,wCACA,wCACA,wCACA,wCAEA,cACA,gBACA,kBAGA,UACE,wBACA,gCACA,6BACA,8EAEA,yHACA,mCACA,iEACA,qBAEA,6BACE,UACA,WAGF,mCACE,yBAGF,mCACE,iCAGF,yCACE,uCAOA,8FACE,aAKN,cACE,YACA,YACA,eACA,sBAGF,mBACE,aAGF,gBACE,cAGA,mBACA,WACA,eACA,mBAEA,kCAGF,gCAEE,0CACA,0BAME,gGAEE,gBAIJ,2BACE,4BACA,kCACA,6BACA,uBACA,oBAIA,yCACE,aAKN,aACE,kBAGF,0BAEE,iBACA,0CACA,gBAEA,8CACE,aACA,kBAIJ,aACE,iBACA,iDAIF,0BAEE,kBACA,gBACA,gBAEA,uBACA,mBAGA,0CACE,mBACA,qBAKJ,yBACE,eAEA,wCACE,mBACA,qBAIJ,yBACE,cACA,+BACE,aACA,mBACA,SAIJ,6BACE,SACA,kBACA,MACA,OACA,WACA,YACA,eACA,aACA,mBACA,uBAOA,4DAEE,UACA,gBACA,SACA,SAIF,8BACE,uBAGF,8BACE,qBAKJ,+CAEE,WACA,YACA,sBACA,kBACA,cACA,QACA,SACA,4DAEA,wHAEE,WACA,cACA,sBACA,kBAIJ,+BACE,QACA,YACA,mCACA,sCACA,sBACA,QACA,SAIA,gCACE,UACA,YACA,wBACA,QACA,UAGF,+BACE,QACA,YACA,mCACA,sCACA,sBACA,QACA,SAIJ,qBACE,0BAIF,iBACE,uCACA,yCACA,mCACA,wBACA,YACA,eACA,gBACA,mBACA,kBACA,eAEA,uBACE,WAGF,gCACE,yBACA,qBAKJ,+BACE,SACA,UAGF,mEAEE,iDACA,mBACA,sBACA,sDACA,mCACA,YACA,eACA,yBACA,eAMA,yFACE,kEACA,UAGF,uMAEE,YACA,oBAKJ,mCACE,kBACA,+BAEA,qCACE,WACA,gBACA,SAIA,+CACE,8CAOJ,mCACE,UACA,SAGF,qCACE,WACA,yBACA,SACA,gBACA,SACA,gBACA,YAEA,2CACE,8CAIJ,4DACE,yCAMF,yBACE,YACA,kBAEA,gCACE,kBACA,QACA,SACA,yBACA,gCACA,WACA,iBACA,kBACA,mBACA,uBACA,gBACA,UAKF,kCACE,YACA,YAKF,0CACE,cACA,yBACA,yBAGF,0CACE,YAEA,iDACE,iBAGF,+DACE,aAOR,mBAKE,gDAJA,mCACE,2CAKF,yBACE,mDAGF,yBACE,mDACA,sDACA,aAKJ,gBACE,gBAEA,mBACE,iDAGF,6BACE,aACA,mBAIF,+BACE,WAGF,2BACE,aACA,mBACA,mBACA,8BAGF,+BACE,aACA,kBAEA,sCAEE,kBACA,WAIJ,yBAGE,iBAIA,2CACE,aAGF,iDACE,aAMN,sBACE,eACA,qBAGF,iJAIE,YACA,sBACA,2BACA,YACA,SACA,QACA,kBACA,2BACA,oBACA,qBAIA,kCACE,iCACA,YACA,sBAGF,iCACE,8BACA,YACA,yBACA,SAIJ,uCACE,sCACA,YAGF,uCACE,mCACA,YACA,yBACA,SAIJ,+BACE,gCACA,2BACA,yDACA,2BACA,8BACA,iDACA,yCACA,4CACA,gDCnkBE,4CAEE,iBAEF,+BACE,kBACA,oBAEF,qLAIE,YACA,WAEF,kCACE,gBCjBJ,mBACE,kBACA,UACA,0BACA,gBACA,gBACA,SACA,uBACA,oCACA,mCAEA,sBACE,SACA,UAEF,yBACE,aACA,mBACA,oBAEF,yBACE,kBCrBJ,sBACE,sBACA,YACA,iBACA,8BAEA,6BACE,SAEA,oCACE,mBAGJ,yCACE,aACA,uCAEF,mCACE,WAGF,0CACE,yBAEF,6CACE,aAEA,+DACE,qBAGJ,wCACE,kBACA,QACA,aACA,mBACA,yBACA,WACA,YAEF,wDACE,WAEA,+DACE,qBAIN,2BACE,eAEA,oCACE,wCCpDJ,sBACE,kBACA,MACA,QACA,UACA,UACA,kBACA,iBAEA,6BACE,WACA,cACA,kBACA,4BACA,cACA,QACA,UACA,6BACA,WAEF,mCACE,WAEF,wCACE,qCAEA,+CACE,WC3BN,gCACE,UACA,kBAEF,sCACE,UAEF,+BACE,kBACA,SAEA,oEAEE,mBAGF,kCACE,cAMN,0CAGI,kCACE,aAIF,+BACE,aAEF,qCACE,aAIF,6KAME,cAIF,4BACE,aASA,iDAPA,+BACE,YAEF,+BACE,WAQF,+BACE,UACA,0CAEF,+BACE,YACA,gDACA,kBACA,qEAEA,0CACE,SAEF,sCACE,kBACA,MACA,OACA,uBACA,8DACA,wBACA,cACA,iBACA,0CAEF,8CACE,6EAMN,qCACE,YACA,mBAIA,2FAEE,UAEF,6CACE,YAEF,wCACE,gBACA,WAEF,4CACE,YAEF,oCACE,qBACA,cAGJ,yCACE,yBAGA,yCACE,UACA,8DAEA,wEACE,gCAGJ,yCACE,yBACA,mBACA,UACA,uEAGJ,kFACE,cAEF,wDACE,yBAEF,sEACE,yBAGF,yCACE,iBAKF,mDACE","file":"data-grid.min.css"}
\ No newline at end of file
diff --git a/dist/data-grid.min.js b/dist/data-grid.min.js
index 659d5e4..c93242d 100644
--- a/dist/data-grid.min.js
+++ b/dist/data-grid.min.js
@@ -1,4 +1,4 @@
-function F(n){return n.toLowerCase().replace(/[^a-zA-Z0-9]+(.)/g,(t,e)=>e.toUpperCase())}function V(n){if(n==="true")return!0;if(n==="false")return!1;if(n===""||n==="null")return null;if(n===Number(n).toString())return Number(n);if(n&&["[","{"].includes(n.substring(0,1)))try{let t=n;return t.indexOf('"')===-1&&(t=t.replace(/'/g,'"')),JSON.parse(decodeURIComponent(t))}catch{return console.error(`Failed to parse ${n}`),{}}return n}var Ot=["scroll","wheel","touchstart","touchmove","touchenter","touchend","touchleave","mouseout","mouseleave","mouseup","mousedown","mousemove","mouseenter","mousewheel","mouseover"];function mt(n){return Ot.includes(n)?{passive:!0}:{}}function D(n,t){return n.getAttribute(t)}function U(n,t){return n.hasAttribute(t)}function c(n,t,e="",i=!1){i&&U(n,t)||n.setAttribute(t,`${e}`)}function L(n,t){U(n,t)&&n.removeAttribute(t)}function A(n,t,e){n.addEventListener(t,e,mt(t))}function O(n,t,e){n.removeEventListener(t,e,mt(t))}function v(n,t,e={},i=!1){let o={};i&&(o.bubbles=!0),e&&(o.detail=e),n.dispatchEvent(new CustomEvent(t,o))}function T(n,t){return n.classList.contains(t)}function E(n,t){n.classList.add(...t.split(" "))}function W(n,t){n.classList.remove(...t.split(" "))}function bt(n,t){n.classList.toggle(t)}function I(n,t=document){return n instanceof HTMLElement?n:t.querySelector(n)}function zt(n,t=document){return Array.from(t.querySelectorAll(n))}function N(n,t){return I(t,n)}function g(n,t){return zt(t,n)}function x(n,t=null){let e=document.createElement(n);return t&&t.appendChild(e),e}function vt(n,t){t.parentNode.insertBefore(n,t.nextSibling)}var Y=class extends HTMLElement{constructor(t={}){super(),this.options=Object.assign({},this.defaultOptions,this.normalizedDataset,t),this.log("constructor"),this.setup=!1,this.fireEvents=!0,this._ready(),this.log("ready")}get defaultOptions(){return{}}getOption(t){return this.options[t]}setOption(t,e){c(this,`data-${t}`,e)}toggleOption(t){c(this,`data-${t}`,!this.getOption(t))}get normalizedDataset(){let t=this.dataset.config?JSON.parse(this.dataset.config):{},e={...this.dataset};for(let i in e)i!=="config"&&(e[i]=V(e[i]));return Object.assign(e,t),e}static template(){return""}_ready(){}log(...t){this.options.debug&&console.log(`[${D(this,"id")}] `,...t)}handleEvent(t){this[`on${t.type}`]&&this[`on${t.type}`](t)}_connected(){}connectedCallback(){this.setup||(this.setup=!0,setTimeout(()=>{this.log("connectedCallback");let t=document.createElement("template");t.innerHTML=this.constructor.template(),this.appendChild(t.content.cloneNode(!0)),this._connected(),v(this,"connected")},0))}_disconnected(){}disconnectedCallback(){setTimeout(()=>{!this.isConnected&&this.setup&&(this.log("disconnectedCallback"),this._disconnected(),v(this,"disconnected"),this.setup=!1)},0)}get transformAttributes(){return{}}attributeChangedCallback(t,e,i){if(e===i)return;this.log(`attributeChangedCallback: ${t}`);let o=!1,r=this.transformAttributes[t]??V,s=t;s.indexOf("data-")===0&&(s=s.slice(5),o=!0),s=F(s),o?this.options[s]=r(i):this[s]=r(i),this.fireEvents&&this[`${s}Changed`]&&this[`${s}Changed`]()}},yt=Y;function J(n,t,e,i=!1){let o=document.createElement("option");o.value=`${t}`,i&&(o.selected=!0),o.label=e,n.appendChild(o)}function Z(n,t={}){for(let e of Object.keys(t))if(Array.isArray(t[e]))for(let i of Object.keys(t[e]))n.searchParams.append(isNaN(i)?`${e}[${i}]`:e,t[e][i]);else n.searchParams.append(e,t[e])}function X(n){if(typeof n=="string"){if(n[0]==="["){let t=n;return t.indexOf('"')===-1&&(t=t.replace(/'/g,'"')),JSON.parse(t)}return n.split(",")}return Array.isArray(n)?n:(console.error("Invalid array",n),[])}function Q(n){let t=n.getBoundingClientRect(),e=window.pageXOffset||document.documentElement.scrollLeft,i=window.pageYOffset||document.documentElement.scrollTop;return{top:t.top+i,left:t.left+e}}function M(n,t){return n.replace(/\{([^}]+)?\}/g,(e,i)=>t[i])}var tt;function _(n,t=document.body,e=!1){let i=window.getComputedStyle(t||document.createElement("div")),o=i.getPropertyValue("font-weight")||"normal",r=i.getPropertyValue("font-size")||"1rem",s=i.getPropertyValue("font-family")||"Arial",l=0;if(e){let u=i.getPropertyValue("padding-left")||"0",h=i.getPropertyValue("padding-right")||"0";l=Number.parseInt(u)+Number.parseInt(h)}tt||(tt=document.createElement("canvas"));let a=tt.getContext("2d");a.font=`${o} ${r} ${s}`;let d=a.measureText(n);return Number.parseInt(d.width)+l}function G(n){return Math.random().toString(36).replace("0.",n||"")}function q(n,t=300){let e=null;return(...i)=>{clearTimeout(e),e=setTimeout(()=>{e=null,n(...i)},t)}}var B={},C={itemsPerPage:"Items per page",gotoPage:"Go to page",gotoFirstPage:"Go to first page",gotoPrevPage:"Go to previous page",gotoNextPage:"Go to next page",gotoLastPage:"Go to last page",of:"of",items:"items",resizeColumn:"Resize column",noData:"No data",areYouSure:"Are you sure?",networkError:"Network response error"};function xt(n,t){t.width&&c(n,"width",t.width),t.class&&E(n,t.class),t.hidden&&(c(n,"hidden",""),t.responsiveHidden&&E(n,"dg-responsive-hidden"))}var et=class n extends yt{_filterSelector="[id^=dg-filter]";_excludedKeys=[37,39,38,40,45,36,35,33,34,27,20,16,17,91,92,18,93,144,231,"ArrowLeft","ArrowRight","ArrowUp","ArrowDown","Insert","Home","End","PageUp","PageDown","Escape","CapsLock","Shift","Control","Meta","Alt","ContextMenu","NumLock","Unidentified"];_ready(){c(this,"id",this.options.id??G("el-"),!0),this.data=[],this.originalData,this.options=this.options||this.defaultOptions,this.fireEvents=!1,this.page=this.options.defaultPage||1,this.pages=0,this.meta,this.plugins={};for(let[t,e]of Object.entries(B))this.plugins[t]=new e(this);for(let t of n.observedAttributes)t.indexOf("data-")===0&&c(this,t,this.options[F(t.slice(5))])}static template(){return`
+function F(r){return r.toLowerCase().replace(/[^a-zA-Z0-9]+(.)/g,(t,e)=>e.toUpperCase())}function V(r){if(r==="true")return!0;if(r==="false")return!1;if(r===""||r==="null")return null;if(r===Number(r).toString())return Number(r);if(r&&typeof r.substring=="function"&&["[","{"].includes(r.substring(0,1)))try{let t=r;return t.indexOf('"')===-1&&(t=t.replace(/'/g,'"')),JSON.parse(decodeURIComponent(t))}catch{return console.error(`Failed to parse ${r}`),{}}return r}var zt=["scroll","wheel","touchstart","touchmove","touchenter","touchend","touchleave","mouseout","mouseleave","mouseup","mousedown","mousemove","mouseenter","mousewheel","mouseover"];function vt(r){return zt.includes(r)?{passive:!0}:{}}function D(r,t){return r.getAttribute(t)}function U(r,t){return r.hasAttribute(t)}function c(r,t,e="",i=!1){i&&U(r,t)||r.setAttribute(t,`${e}`)}function k(r,t){U(r,t)&&r.removeAttribute(t)}function A(r,t,e){r.addEventListener(t,e,vt(t))}function O(r,t,e){r.removeEventListener(t,e,vt(t))}function y(r,t,e={},i=!1){let o={};i&&(o.bubbles=!0),e&&(o.detail=e),r.dispatchEvent(new CustomEvent(t,o))}function T(r,t){return r.classList.contains(t)}function E(r,t){r.classList.add(...t.split(" "))}function W(r,t){r.classList.remove(...t.split(" "))}function yt(r,t){r.classList.toggle(t)}function I(r,t=document){return r instanceof HTMLElement?r:t.querySelector(r)}function Y(r,t=document){return Array.from(t.querySelectorAll(r))}function N(r,t){return I(t,r)}function g(r,t){return Y(t,r)}function x(r,t=null){let e=document.createElement(r);return t&&t.appendChild(e),e}function xt(r,t){t.parentNode.insertBefore(r,t.nextSibling)}var J=class extends HTMLElement{constructor(t={}){super(),this.options=Object.assign({},this.defaultOptions,this.normalizedDataset,t),this.log("constructor"),this.setup=!1,this.fireEvents=!0,this._ready(),this.log("ready")}get defaultOptions(){return{}}getOption(t){return this.options[t]}setOption(t,e){c(this,`data-${t}`,e)}toggleOption(t){c(this,`data-${t}`,!this.getOption(t))}get normalizedDataset(){let t=this.dataset.config?JSON.parse(this.dataset.config):{},e={...this.dataset};for(let i in e)i==="config"||!e.hasOwnProperty(i)||typeof e[i]=="function"||(e[i]=V(e[i]));return Object.assign(e,t),e}static template(){return""}_ready(){}log(...t){this.options.debug&&console.log(`[${D(this,"id")}] `,...t)}handleEvent(t){this[`on${t.type}`]&&this[`on${t.type}`](t)}_connected(){}connectedCallback(){this.setup||(this.setup=!0,setTimeout(async()=>{this.log("connectedCallback");let t=document.createElement("template");t.innerHTML=this.constructor.template(),this.appendChild(t.content.cloneNode(!0)),await this._connected(),y(this,"connected")},0))}_disconnected(){}disconnectedCallback(){setTimeout(()=>{!this.isConnected&&this.setup&&(this.log("disconnectedCallback"),this._disconnected(),y(this,"disconnected"),this.setup=!1)},0)}get transformAttributes(){return{}}attributeChangedCallback(t,e,i){if(e===i)return;this.log(`attributeChangedCallback: ${t}`);let o=!1,n=this.transformAttributes[t]??V,s=t;s.indexOf("data-")===0&&(s=s.slice(5),o=!0),s=F(s),o?this.options[s]=n(i):this[s]=n(i),this.fireEvents&&this[`${s}Changed`]&&this[`${s}Changed`]()}},Ct=J;function Z(r,t,e,i=!1){let o=document.createElement("option");o.value=`${t}`,i&&(o.selected=!0),o.label=e,r.appendChild(o)}function Q(r,t={}){for(let e of Object.keys(t))if(Array.isArray(t[e]))for(let i of Object.keys(t[e]))r.searchParams.append(isNaN(i)?`${e}[${i}]`:e,t[e][i]);else r.searchParams.append(e,t[e])}function X(r){if(typeof r=="string"){if(r[0]==="["){let t=r;return t.indexOf('"')===-1&&(t=t.replace(/'/g,'"')),JSON.parse(t)}return r.split(",")}return Array.isArray(r)?r:(console.error("Invalid array",r),[])}function tt(r){let t=r.getBoundingClientRect(),e=window.pageXOffset||document.documentElement.scrollLeft,i=window.pageYOffset||document.documentElement.scrollTop;return{top:t.top+i,left:t.left+e}}function M(r,t){return r.replace(/\{([^}]+)?\}/g,(e,i)=>t[i])}var et;function _(r,t=document.body,e=!1){let i=window.getComputedStyle(t||document.createElement("div")),o=i.getPropertyValue("font-weight")||"normal",n=i.getPropertyValue("font-size")||"1rem",s=i.getPropertyValue("font-family")||"Arial",l=0;if(e){let u=i.getPropertyValue("padding-left")||"0",h=i.getPropertyValue("padding-right")||"0";l=Number.parseInt(u)+Number.parseInt(h)}et||(et=document.createElement("canvas"));let a=et.getContext("2d");a.font=`${o} ${n} ${s}`;let d=a.measureText(r);return Number.parseInt(d.width)+l}function q(r){return Math.random().toString(36).replace("0.",r||"")}function G(r,t=300){let e=null;return(...i)=>{clearTimeout(e),e=setTimeout(()=>{e=null,r(...i)},t)}}var B={},C={itemsPerPage:"Items per page",gotoPage:"Go to page",gotoFirstPage:"Go to first page",gotoPrevPage:"Go to previous page",gotoNextPage:"Go to next page",gotoLastPage:"Go to last page",of:"of",items:"items",resizeColumn:"Resize column",noData:"No data",areYouSure:"Are you sure?",networkError:"Network response error"};function wt(r,t){t.width&&c(r,"width",t.width),t.class&&E(r,t.class),t.hidden&&(c(r,"hidden",""),t.responsiveHidden&&E(r,"dg-responsive-hidden"))}var it=class r extends Ct{_filterSelector="[id^=dg-filter]";_excludedRowElementSelector="a,button,input,select,textarea";_excludedKeys=[37,39,38,40,45,36,35,33,34,27,20,16,17,91,92,18,93,144,231,"ArrowLeft","ArrowRight","ArrowUp","ArrowDown","Insert","Home","End","PageUp","PageDown","Escape","CapsLock","Shift","Control","Meta","Alt","ContextMenu","NumLock","Unidentified"];_ready(){c(this,"id",this.options.id??q("el-"),!0),this.data=[],this.originalData,this.options=this.options||this.defaultOptions,this.options.singleSelect&&(this.options.selectable=!0),this.fireEvents=!1,this.page=this.options.defaultPage||1,this.pages=0,this.meta,this.plugins={};for(let[t,e]of Object.entries(B))this.plugins[t]=new e(this);for(let t of r.observedAttributes)t.indexOf("data-")===0&&c(this,t,this.options[F(t.slice(5))])}static template(){return`
|
@@ -36,13 +36,13 @@ function F(n){return n.toLowerCase().replace(/[^a-zA-Z0-9]+(.)/g,(t,e)=>e.toUppe
-`}get labels(){return C}static getLabels(){return C}static setLabels(t){C=Object.assign(C,t)}get defaultColumn(){return{field:"",title:"",width:0,class:"",attr:"",hidden:!1,editable:!1,noSort:!1,responsive:1,responsiveHidden:!1,format:"",transform:"",filterType:"text",firstFilterOption:{value:"",text:""}}}get defaultOptions(){return{id:null,url:null,perPage:10,debug:!1,filter:!1,menu:!1,sort:!1,server:!1,serverParams:{start:"start",length:"length",search:"search",sort:"sort",sortDir:"sortDir",dataKey:"data",metaKey:"meta",metaTotalKey:"total",metaFilteredKey:"filtered",optionsKey:"options",paramsKey:"params"},defaultSort:"",reorder:!1,dir:"ltr",perPageValues:[10,25,50,100,250],hidePerPage:!1,columns:[],actions:[],collapseActions:!1,selectable:!1,selectVisibleOnly:!0,defaultPage:1,resizable:!1,autosize:!0,expand:!1,autoheight:!0,autohidePager:!1,responsive:!1,responsiveToggle:!0,filterOnEnter:!0,filterKeypressDelay:500,spinnerClass:"",saveState:!1,errorMessage:""}}get isInit(){return this.classList.contains("dg-initialized")}get hasDataError(){return this.classList.contains("dg-network-error")}static registerPlugins(t){B=t}static unregisterPlugins(t=null){t===null?B={}:delete B[t]}static registeredPlugins(){return B}convertColumns(t){let e=[];if(typeof t=="object"&&!Array.isArray(t))for(let i of Object.keys(t)){let o=Object.assign({},this.defaultColumn);o.title=t[i],o.field=i,e.push(o)}else for(let i of t){let o=Object.assign({},this.defaultColumn);typeof i=="string"?(o.title=i,o.field=i):typeof i=="object"?(o=Object.assign(o,i),o.field||console.error("Invalid column definition",i),o.title||(o.title=o.field)):console.error("Column definition must be a string or an object"),e.push(o)}return e}static get observedAttributes(){return["page","data-filter","data-sort","data-debug","data-reorder","data-menu","data-selectable","data-url","data-per-page","data-responsive"]}get transformAttributes(){return{columns:t=>this.convertColumns(X(t)),actions:t=>X(t),defaultPage:t=>Number.parseInt(t),perPage:t=>Number.parseInt(t)}}get thead(){return I("thead",this)}get tbody(){return I("tbody",this)}get tfoot(){return I("tfoot",this)}get page(){return Number.parseInt(this.getAttribute("page"))}set page(t){c(this,"page",this.constrainPageValue(t))}urlChanged(t=!1){t&&!this.isInit||(this.reconfig(),this.loadData().then(()=>{this.configureUi()}))}reconfig(){let t=this.options.columns;this.options.columns=[],this.configureUi(),this.options.columns=t}constrainPageValue(t){let e=t;return this.pages1&&this.page*this.options.perPage>this.totalRecords();)t--;t!==this.page?this.page=t:this.reload(()=>{(!this.plugins.FixedHeight||!this.plugins.FixedHeight.hasFixedHeight)&&this.selectPerPage.scrollIntoView()})}dirChanged(){c(this,"dir",this.options.dir)}defaultSortChanged(){this.sortChanged()}perPageValuesChanged(){if(this.selectPerPage){for(;this.selectPerPage.lastChild;)this.selectPerPage.removeChild(this.selectPerPage.lastChild);for(let t of this.options.perPageValues)J(this.selectPerPage,t,t,t===this.options.perPage)}}_connected(){this.table=this.querySelector("table"),this.btnFirst=this.querySelector(".dg-btn-first"),this.btnPrev=this.querySelector(".dg-btn-prev"),this.btnNext=this.querySelector(".dg-btn-next"),this.btnLast=this.querySelector(".dg-btn-last"),this.selectPerPage=this.querySelector(".dg-select-per-page"),this.inputPage=this.querySelector(".dg-input-page"),this.getFirst=this.getFirst.bind(this),this.getPrev=this.getPrev.bind(this),this.getNext=this.getNext.bind(this),this.getLast=this.getLast.bind(this),this.changePerPage=this.changePerPage.bind(this),this.gotoPage=this.gotoPage.bind(this),this.btnFirst.addEventListener("click",this.getFirst),this.btnPrev.addEventListener("click",this.getPrev),this.btnNext.addEventListener("click",this.getNext),this.btnLast.addEventListener("click",this.getLast),this.selectPerPage.addEventListener("change",this.changePerPage),this.selectPerPage.toggleAttribute("hidden",this.options.hidePerPage),this.inputPage.addEventListener("input",this.gotoPage);for(let t of Object.values(this.plugins))t.connected();this.dirChanged(),this.perPageValuesChanged(),setTimeout(()=>{this.loadData().finally(()=>{this.configureUi(),this.sortChanged(),this.classList.add("dg-initialized"),this.filterChanged(),this.reorderChanged(),this.dirChanged(),this.perPageValuesChanged(),this.pageChanged(),this.fireEvents=!0,this.log("initialized")})},0)}_disconnected(){this.btnFirst?.removeEventListener("click",this.getFirst),this.btnPrev?.removeEventListener("click",this.getPrev),this.btnNext?.removeEventListener("click",this.getNext),this.btnLast?.removeEventListener("click",this.getLast),this.selectPerPage?.removeEventListener("change",this.changePerPage),this.inputPage?.removeEventListener("input",this.gotoPage);for(let t of Object.values(this.plugins))t.disconnected()}getCol(t){let e=null;for(let i of this.options.columns)i.field===t&&(e=i);return e}getColProp(t,e){let i=this.getCol(t);return i?i[e]:null}setColProp(t,e,i){let o=this.getCol(t);o&&(o[e]=i)}visibleColumns(){return this.options.columns.filter(t=>!t.hidden)}hiddenColumns(){return this.options.columns.filter(t=>t.hidden===!0)}showColumn(t,e=!0){this.setColProp(t,"hidden",!1),e&&this.renderTable(),v(this,"columnVisibility",{col:t,visibility:"visible"})}hideColumn(t,e=!0){this.setColProp(t,"hidden",!0),e&&this.renderTable(),v(this,"columnVisibility",{col:t,visibility:"hidden"})}startColIndex(){let t=1;return this.options.selectable&&this.plugins.SelectableRows&&t++,this.options.responsive&&this.plugins.ResponsiveGrid&&this.plugins.ResponsiveGrid.hasHiddenColumns()&&t++,t}isSticky(){return this.hasAttribute("sticky")}columnsLength(t=!1){let e=0;for(let i of this.options.columns)t&&i.hidden||i.attr||e++;return this.options.selectable&&this.plugins.SelectableRows&&e++,this.options.actions.length&&this.plugins.RowActions&&e++,this.options.responsive&&this.plugins.ResponsiveGrid&&this.plugins.ResponsiveGrid.hasHiddenColumns()&&e++,e}configureUi(){if(this.table.style.visibility="hidden",this.renderTable(),this.options.responsive&&this.plugins.ResponsiveGrid||(this.table.style.visibility="visible"),!this.rowHeight){let t=N(this,"tbody tr")||N(this,"table tr");t&&(this.rowHeight=t.offsetHeight)}this.fixPage()}filterChanged(){let t=this.querySelector("thead tr.dg-head-filters");this.options.filter?L(t,"hidden"):(this.clearFilters(),c(t,"hidden",""))}reorderChanged(){let t=g(this,"thead tr.dg-head-columns th");for(let e of t)e.classList.contains("dg-selectable")||e.classList.contains("dg-actions")||(this.options.reorder&&this.plugins.DraggableHeaders?e.draggable=!0:e.removeAttribute("draggable"))}sortChanged(){this.log("toggle sort");let t=g(this,"thead tr.dg-head-columns th");for(let e of t){let i=e.getAttribute("field");if(e.classList.contains("dg-not-sortable")||!this.fireEvents&&i===this.options.defaultSort)return;this.options.sort&&!this.getColProp(i,"noSort")?c(e,"aria-sort","none"):L(e,"aria-sort")}}selectableChanged(){this.renderTable()}addRow(t){Array.isArray(this.originalData)&&(this.log("add row"),this.originalData.push(t),this.data=this.originalData.slice(),this.sortData())}removeRow(t=null,e=null){if(!Array.isArray(this.originalData))return;let i=t,o=e;o===null&&(o=this.options.columns[0].field),i===null&&(i=this.originalData[this.originalData.length-1][o]),this.log(`remove row ${o}:${i}`);for(let r=0;r{this.hasDataError||(this.options.server||e?this.renderBody():this.paginate(),t&&t())})}loadData(){let t=()=>!this.data.length&&this.classList.add("dg-empty"),e=this.tbody;return(this.meta||this.originalData||this.isInit)&&(!this.options.server||this.options.server&&!this.fireEvents)?(this.log("skip loadData"),t(),new Promise(i=>{i()})):(this.log("loadData"),this.loading=!0,this.classList.add("dg-loading"),this.classList.remove("dg-empty","dg-network-error"),this.fetchData().then(i=>{if(Array.isArray(i))this.data=i;else{if(!i[this.options.serverParams.dataKey]){console.error("Invalid response, it should contain a data key with an array or be a plain array",i),this.options.url=null;return}this.options=Object.assign(this.options,i[this.options.serverParams.optionsKey]??{}),this.meta=i[this.options.serverParams.metaKey]??{},this.data=i[this.options.serverParams.dataKey]}this.originalData=this.data.slice(),this.fixPage(),this.options.columns.length===0&&this.originalData.length?this.options.columns=this.convertColumns(Object.keys(this.originalData[0])):this.options.columns=this.convertColumns(this.options.columns)}).catch(i=>{this.log(i),e.setAttribute("data-empty",this.options.errorMessage||i.message?.replace(/^\s+|\r\n|\n|\r$/g,"")||C.networkError),this.classList.add("dg-empty","dg-network-error"),v(this,"loadDataFailed",i)}).finally(()=>{t(),!this.hasDataError&&e.getAttribute("data-empty")!==this.labels.noData&&e.setAttribute("data-empty",this.labels.noData),this.classList.remove("dg-loading"),c(this.table,"aria-rowcount",this.data.length),this.loading=!1}))}getFirst(){this.loading||(this.page=1)}getLast(){this.loading||(this.page=this.pages)}getPrev(){this.loading||(this.page=this.page-1)}getNext(){this.loading||(this.page=this.page+1)}gotoPage(t){if(t.type==="keypress"){let e=t.keyCode||t.key;if(e===13||e==="Enter")t.preventDefault();else return}this.page=Number.parseInt(this.inputPage.value)}getSort(){let t=this.querySelector("thead tr.dg-head-columns th[aria-sort$='scending']");return t?t.getAttribute("field"):this.options.defaultSort}getSortDir(){let t=this.querySelector("thead tr.dg-head-columns th[aria-sort$='scending']");return t&&t.getAttribute("aria-sort")||""}getFilters(){let t=[],e=g(this,this._filterSelector);for(let i of e)t[i.dataset.name]=i.value;return t}clearFilters(){let t=g(this,this._filterSelector);for(let e of t)e.value="";this.filterData()}filterData(){if(this.log("filter data"),this.page=1,this.options.server)this.reload();else{this.data=this.originalData?.slice()??[];let t=g(this,this._filterSelector);for(let i of t){let o=i.value;if(o){let r=i.dataset.name;this.data=this.data.filter(s=>`${s[r]}`.toLowerCase().indexOf(o.toLowerCase())!==-1)}}this.pageChanged();let e=this.querySelector("thead tr.dg-head-columns th[aria-sort$='scending']");this.options.sort&&e?this.sortData():this.renderBody()}}sortData(t=null){this.log("sort data");let e=t;if(e&&this.getColProp(e.getAttribute("field"),"noSort")){this.log("sorting prevented because column is not sortable");return}if(this.plugins.ColumnResizer?.isResizing){this.log("sorting prevented because resizing");return}if(this.loading){this.log("sorting prevented because loading");return}if(e!==null){let i=r=>["dg-selectable","dg-actions","dg-responsive-toggle"].includes(r),o=g(this,"thead tr:first-child th");for(let r of o)[...r.classList].some(i)||r!==e&&r.setAttribute("aria-sort","none");!e.hasAttribute("aria-sort")||e.getAttribute("aria-sort")==="none"?e.setAttribute("aria-sort","ascending"):e.getAttribute("aria-sort")==="ascending"?e.setAttribute("aria-sort","descending"):e.getAttribute("aria-sort")==="descending"&&e.setAttribute("aria-sort","none")}else e=this.querySelector("thead tr.dg-head-columns th[aria-sort$='scending']");if(this.options.server)this.loadData().finally(()=>{this.renderBody()});else{let i=e?e.getAttribute("aria-sort"):"none";if(i==="none"){let o=[];this.originalData?.some(r=>(this.data.some(s=>JSON.stringify(r)===JSON.stringify(s)?(o.push(s),!0):!1),o.length===this.data.length)),this.data=o}else{let o=e.getAttribute("field");this.data.sort((r,s)=>{if(!isNaN(r[o])&&!isNaN(s[o]))return i==="ascending"?r[o]-s[o]:s[o]-r[o];let l=i==="ascending"?r[o].toUpperCase():s[o].toUpperCase(),a=i==="ascending"?s[o].toUpperCase():r[o].toUpperCase();switch(!0){case l>a:return 1;case lthis._sort(t,"ascending");sortDesc=t=>this._sort(t,"descending");sortNone=t=>this._sort(t,"none");fetchData(){if(!this.options.url)return new Promise((o,r)=>r("No url set"));let t=window.location.href;t.split("/").pop().includes(".")||(t+=t.endsWith("/")?"":"/");let e=new URL(this.options.url,t),i={r:Date.now()};return this.options.server&&(i[this.options.serverParams.start]=this.page-1,i[this.options.serverParams.length]=this.options.perPage,this.options.filter&&(i[this.options.serverParams.search]=this.getFilters()),i[this.options.serverParams.sort]=this.getSort()||"",i[this.options.serverParams.sortDir]=this.getSortDir(),this.meta?.[this.options.serverParams.paramsKey]&&(i=Object.assign(i,this.meta[this.options.serverParams.paramsKey]))),Z(e,i),fetch(e).then(o=>{let r=new Error(o.statusText||C.networkError);if(!o.ok)throw r.response=o,r;return o.clone().json().catch(s=>{let l=s;throw this.options.debug||(l=r),l.response=o,l})})}renderTable(){this.log("render table"),this.options.menu&&this.plugins.ContextMenu&&this.plugins.ContextMenu.createMenu();let t;this.renderHeader(),this.options.defaultSort&&(t=this.querySelector(`thead tr.dg-head-columns th[field="${this.options.defaultSort}"]`)),t?this.sortData(t):this.renderBody(),this.renderFooter()}renderHeader(){this.log("render header");let t=this.thead;this.createColumnHeaders(t),this.createColumnFilters(t),this.options.resizable&&this.plugins.ColumnResizer&&this.plugins.ColumnResizer.renderResizer(C.resizeColumn),v(this,"headerRendered")}renderFooter(){this.log("render footer");let t=this.tfoot,e=t.querySelector("td");t.removeAttribute("hidden"),c(e,"colspan",this.columnsLength(!0)),t.style.display=""}createColumnHeaders(t){let e=this.clientWidth,i=Math.round(e/this.columnsLength(!0)*2),o=0,r;r=x("tr"),this.headerRow=r,r.setAttribute("role","row"),r.setAttribute("aria-rowindex","1"),r.setAttribute("class","dg-head-columns");let s=t.querySelector("tr.dg-head-columns th");this.log("createColumnHeaders - sampleTh",s),s||(s=x("th"),t.querySelector("tr").appendChild(s)),this.options.selectable&&this.plugins.SelectableRows&&this.plugins.SelectableRows.createHeaderCol(r),this.options.responsive&&this.plugins.ResponsiveGrid&&this.plugins.ResponsiveGrid.hasHiddenColumns()&&this.plugins.ResponsiveGrid.createHeaderCol(r),o=0;let l=0;this.log("createColumnHeaders - columns",this.options.columns);for(let d of this.options.columns){if(d.attr)continue;let u=o+this.startColIndex(),h=x("th");h.setAttribute("scope","col"),h.setAttribute("role","columnheader button"),h.setAttribute("aria-colindex",`${u}`),h.setAttribute("id",G("dg-col-")),this.options.sort&&h.setAttribute("aria-sort","none"),h.setAttribute("field",d.field),this.plugins.ResponsiveGrid&&this.options.responsive&&c(h,"data-responsive",d.responsive||"");let p=_(d.title,s,!0)+20;h.dataset.minWidth=`${p}`,xt(h,d),h.tabIndex=0,h.textContent=d.title;let f=0;if(this.options.autosize&&this.plugins.AutosizeColumn){let b=Math.min(e-l,i);f=this.plugins.AutosizeColumn.computeSize(h,d,Number.parseInt(h.dataset.minWidth),b)}else f=Math.max(Number.parseInt(h.dataset.minWidth),Number.parseInt(h.getAttribute("width")));c(h,"width",f),d.hidden?h.setAttribute("hidden",""):l+=f,this.options.reorder&&this.plugins.DraggableHeaders&&this.plugins.DraggableHeaders.makeHeaderDraggable(h),r.appendChild(h),o++}if(le){this.log(`adjust width to fix size, ${t.offsetWidth} > ${e}`);let d=this.offsetWidth-this.clientWidth,u=t.offsetWidth-e-d;this.options.responsive&&this.plugins.ResponsiveGrid&&(u+=d);let h=g(r,"th[width]");for(let p of h){if(T(p,"dg-not-resizable")||u<=0)continue;let f=Number.parseInt(p.getAttribute("width")),b=p.dataset.minWidth?Number.parseInt(p.dataset.minWidth):0;if(f>b){let S=f-u;Sthis.sortData(d));c(this.table,"aria-colcount",this.columnsLength(!0))}createColumnFilters(t){let e=0,i;i=x("tr"),this.filterRow=i,i.setAttribute("role","row"),i.setAttribute("aria-rowindex","2"),i.setAttribute("class","dg-head-filters"),this.options.filter||i.setAttribute("hidden",""),this.options.selectable&&this.plugins.SelectableRows&&this.plugins.SelectableRows.createFilterCol(i),this.options.responsive&&this.plugins.ResponsiveGrid&&this.plugins.ResponsiveGrid.hasHiddenColumns()&&this.plugins.ResponsiveGrid.createFilterCol(i),this.log("createColumnFilters - columns",this.options.columns);for(let r of this.options.columns){if(r.attr)continue;let s=e+this.startColIndex(),l=t.querySelector(`tr.dg-head-columns th[aria-colindex="${s}"]`);if(!l){console.warn("Related th not found",s);continue}let a=x("th");a.setAttribute("aria-colindex",`${s}`);let d=this.createFilterElement(r,l);this.options.filter?d.tabIndex=0:a.tabIndex=0,r.hidden&&a.setAttribute("hidden",""),a.appendChild(d),i.appendChild(a),e++}this.options.actions.length&&this.plugins.RowActions&&this.plugins.RowActions.makeActionFilter(i),t.replaceChild(i,t.querySelector("tr.dg-head-filters")),(typeof this.options.filterKeypressDelay!="number"||this.options.filterOnEnter)&&(this.options.filterKeypressDelay=0);let o=g(i,this._filterSelector);for(let r of o){let s=/select/i.test(r.tagName)?"change":"keyup",l=q(a=>{let d=a.keyCode||a.key,u=!this.options.filterOnEnter&&!this._excludedKeys.some(h=>h===d);(d===13||d==="Enter"||u||a.type==="change")&&this.filterData.call(this)},this.options.filterKeypressDelay);r.addEventListener(s,l)}}createFilterElement(t,e){let i=t.filterType==="select",o=i?x("select"):x("input");if(i){if(!Array.isArray(t.filterList)){let r=[...new Set((this.data??[]).map(s=>s[t.field]))].filter(s=>s).sort();t.filterList=[t.firstFilterOption||this.defaultColumn.firstFilterOption].concat(r.map(s=>({value:s,text:s})))}for(let r of t.filterList){let s=x("option");s.value=r.value,s.text=r.text,o instanceof HTMLSelectElement&&o.add(s)}}else o.type="text",o.inputMode="search",o.autocomplete="off",o.spellcheck=!1;return o.dataset.name=t.field,o.id=G("dg-filter-"),o.setAttribute("aria-labelledby",e.getAttribute("id")),o}renderBody(){this.log("render body");let t,e,i,o=x("tbody");this.data.forEach((s,l)=>{t=x("tr"),c(t,"role","row"),c(t,"hidden",""),c(t,"aria-rowindex",l+1),t.tabIndex=0,this.options.selectable&&this.plugins.SelectableRows&&this.plugins.SelectableRows.createDataCol(t),this.options.responsive&&this.plugins.ResponsiveGrid&&this.plugins.ResponsiveGrid.hasHiddenColumns()&&this.plugins.ResponsiveGrid.createDataCol(t),this.options.expand&&(t.classList.add("dg-expandable"),A(t,"click",a=>{this.plugins.ResponsiveGrid&&this.plugins.ResponsiveGrid.blockObserver(),bt(a.currentTarget,"dg-expanded"),this.plugins.ResponsiveGrid&&this.plugins.ResponsiveGrid.unblockObserver()})),i=0;for(let a of this.options.columns){if(a||console.error("Empty column found!",this.options.columns),a.attr){s[a.field]&&(a.attr==="class"?E(t,s[a.field]):t.setAttribute(a.attr,s[a.field]));return}if(e=x("td"),e.setAttribute("role","gridcell"),e.setAttribute("aria-colindex",`${i}${this.startColIndex()}`),xt(e,a),e.setAttribute("data-name",a.title),e.tabIndex=-1,a.editable&&this.plugins.EditableColumn)E(e,"dg-editable-col"),this.plugins.EditableColumn.makeEditableInput(e,a,s,l);else{let d=s[a.field]??"",u;switch(a.transform){case"uppercase":u=d.toUpperCase();break;case"lowercase":u=d.toLowerCase();break;default:u=d;break}if(a.format){if(a.defaultFormatValue!==void 0&&(u===""||u===null)&&(u=`${a.defaultFormatValue}`),typeof a.format=="string"&&u)e.innerHTML=M(a.format,Object.assign({_v:d,_tv:u},s));else if(a.format instanceof Function){let h=a.format.call(this,{column:a,rowData:s,cellData:u,td:e,tr:t});e.innerHTML=h||u||d}}else e.textContent=u}t.appendChild(e),i++}this.options.actions.length&&this.plugins.RowActions&&this.plugins.RowActions.makeActionRow(t,s),o.appendChild(t),v(this,"rowRendered",{rowData:s,tr:t})}),o.setAttribute("role","rowgroup");let r=this.tbody;o.setAttribute("data-empty",r.getAttribute("data-empty")),this.table.replaceChild(o,r),this.plugins.FixedHeight&&this.plugins.FixedHeight.createFakeRow(),this.paginate(),this.plugins.SelectableRows&&this.plugins.SelectableRows.shouldSelectAll(o),this.data.length&&this.classList.remove("dg-empty"),v(this,"bodyRendered")}paginate(){this.log("paginate");let t=this.totalRecords(),e=this.page||1,i=this.tbody,o=this.tfoot,r=g(i,"tr");this.pages=this.totalPages();let s,l=e*this.options.perPage,a=l-this.options.perPage+1;l>t&&(l=t),t||(a=0);for(let d of r){if(this.options.server){L(d,"hidden");continue}s=Number(D(d,"aria-rowindex")),s>l||s=this.pages,this.btnLast.disabled=this.page>=this.pages),o.querySelector(".dg-low").textContent=a.toString(),o.querySelector(".dg-high").textContent=l.toString(),o.querySelector(".dg-total").textContent=`${this.totalRecords()}`,o.toggleAttribute("hidden",this.options.autohidePager&&this.options.perPage>this.totalRecords())}totalPages(){return Math.ceil(this.totalRecords()/this.options.perPage)}totalRecords(){return this.options.server?this.meta?.[this.options.serverParams.metaFilteredKey]||0:this.data.length}},j=et;var it=class{constructor(t){this.grid=t}connected(){}disconnected(){}handleEvent(t){this[`on${t.type}`]&&this[`on${t.type}`](t)}},m=it;var st=class extends m{constructor(t){super(t),this.isResizing=!1}renderResizer(t){let e=this.grid,i=e.table,o=g(e,"thead tr.dg-head-columns th");for(let r of o){if(T(r,"dg-not-resizable"))continue;let s=document.createElement("div");E(s,"dg-resizer"),s.ariaLabel=t,r.appendChild(s);let l=0,a=0,d=0,u=0,h=f=>{if(f.clientX>u)return;let b=a+(f.clientX-l);r.dataset.minWidth&&b>Number.parseInt(r.dataset.minWidth)&&c(r,"width",b)},p=()=>{e.log("resized column"),setTimeout(()=>{this.isResizing=!1},0),W(s,"dg-resizer-active"),e.options.reorder&&(r.draggable=!0),r.style.overflow="hidden",O(document,"mousemove",h),O(document,"mouseup",p),v(e,"columnResized",{col:D(r,"field"),width:D(r,"width")})};A(s,"click",f=>{f.stopPropagation()}),A(s,"mousedown",f=>{f.stopPropagation(),this.isResizing=!0;let b=f.target,P=g(e,"dg-head-columns th").filter(y=>!y.hasAttribute("hidden")),w=P.findIndex(y=>y===b.parentNode);e.log("resize column"),E(s,"dg-resizer-active"),L(r,"draggable"),r.style.overflow="visible",s.style.height=`${i.offsetHeight-1}px`,l=f.clientX,a=r.offsetWidth,d=(P.length-w)*30,u=Q(b).left+e.offsetWidth-d,c(r,"width",a);for(let y=0;yw&&L(o[y],"width");A(document,"mousemove",h),A(document,"mouseup",p)})}}},Ct=st;function K(n,t,e="nodeName"){let i=n;for(;i[e]!==t;)i=i.parentElement;return i}var ot=class extends m{connected(){this.menu=this.grid.querySelector(".dg-menu")}disconnected(){this.grid.headerRow&&O(this.grid.headerRow,"contextmenu",this)}attachContextMenu(){let t=this.grid;A(t.headerRow,"contextmenu",this)}onchange(t){let e=this.grid,i=t.target,o=i.dataset.name;if(i.checked)e.showColumn(o);else{if(e.visibleColumns().length<=1){i.checked=!0;return}e.hideColumn(o)}e.fixPage()}oncontextmenu(t){t.preventDefault();let e=this.grid,i=K(t.target,"THEAD"),o=this.menu,r=i.getBoundingClientRect(),s=t.clientX-r.left,l=t.clientY-r.top;o.style.top=`${l}px`,o.style.left=`${s}px`,L(o,"hidden"),s+150>r.width&&(s-=o.offsetWidth,o.style.left=`${s}px`);let a=d=>{o.contains(d.target)||(c(o,"hidden",""),O(document,"click",a))};A(document,"click",a)}createMenu(){let t=this.grid,e=this.menu;for(;e.lastChild;)e.removeChild(e.lastChild);e.addEventListener("change",this);for(let i of t.options.columns){if(i.attr)continue;let o=document.createElement("li"),r=document.createElement("label"),s=document.createElement("input");c(s,"type","checkbox"),c(s,"data-name",i.field),i.hidden||(s.checked=!0);let l=document.createTextNode(i.title);r.appendChild(s),r.appendChild(l),o.appendChild(r),e.appendChild(o)}}},wt=ot;var rt=class extends m{makeHeaderDraggable(t){let e=this.grid;t.draggable=!0,A(t,"dragstart",i=>{if(e.plugins.ColumnResizer?.isResizing&&i.preventDefault){i.preventDefault();return}e.log("reorder col"),i.dataTransfer.effectAllowed="move",i.dataTransfer.setData("text/plain",i.target.getAttribute("aria-colindex"))}),A(t,"dragover",i=>(i.preventDefault&&i.preventDefault(),i.dataTransfer.dropEffect="move",!1)),A(t,"drop",i=>{i.stopPropagation&&i.stopPropagation();let o=i.target,r=K(o,"TH"),s=Number.parseInt(i.dataTransfer.getData("text/plain")),l=Number.parseInt(r.getAttribute("aria-colindex"));if(s===l){e.log("reordered col stayed the same");return}e.log(`reordered col from ${s} to ${l}`);let a=e.startColIndex(),d=e.options.columns[s-a];e.options.columns[s-a]=e.options.columns[l-a],e.options.columns[l-a]=d;let u=(h,p)=>{let f=p.parentNode.getAttribute("aria-rowindex"),b=e.querySelector(`${h} tr[aria-rowindex="${f}"] [aria-colindex="${l}"]`);c(p,"aria-colindex",l),c(b,"aria-colindex",s);let S=document.createElement("th");p.parentNode.insertBefore(S,p),b.parentNode.replaceChild(p,b),S.parentNode.replaceChild(b,S)};for(let h of g(e,`thead th[aria-colindex="${s}"]`))u("thead",h);for(let h of g(e,`tbody td[aria-colindex="${s}"]`))u("tbody",h);return e.options.columns=g(e,"thead tr.dg-head-columns th[field]").map(h=>e.options.columns.find(p=>p.field===D(h,"field"))),v(e,"columnReordered",{col:d.field,from:s,to:l}),!1})}},Pt=rt;var nt=class extends m{constructor(t){super(t),this.touch=null}connected(){let t=this.grid;t.addEventListener("touchstart",this,{passive:!0}),t.addEventListener("touchmove",this,{passive:!0})}disconnected(){let t=this.grid;t.removeEventListener("touchstart",this),t.removeEventListener("touchmove",this)}ontouchstart(t){this.touch=t.touches[0]}ontouchmove(t){if(!this.touch)return;let e=this.grid,i=this.touch.clientX-t.touches[0].clientX,o=this.touch.clientY-t.touches[0].clientY;Math.abs(i)>Math.abs(o)&&(i>0?e.getNext():e.getPrev()),this.touch=null}},At=nt;var H="dg-selectable",St="dg-select-all",kt="form-check-input",at=class extends m{disconnected(){this.selectAll&&this.selectAll.removeEventListener("change",this)}getSelection(t=null){let e=this.grid,i=[],o=g(e,`tbody .${H} input:checked`);for(let r of o){let s=Number.parseInt(r.dataset.id),l=e.data[s-1];l||console.warn(`Item ${s} not found`),t?i.push(l[t]):i.push(l)}return i}clearCheckboxes(t){if(!this.grid.options.selectVisibleOnly)return;let i=g(t,`tr[hidden] .${H} input`);for(let o of i)o.checked=!1;this.selectAll.checked=!1}colIndex(){return this.grid.startColIndex()-2}createHeaderCol(t){let e=document.createElement("th");c(e,"scope","col"),c(e,"role","columnheader button"),c(e,"aria-colindex",this.colIndex()),e.classList.add(H,"dg-not-resizable","dg-not-sortable"),e.tabIndex=0,this.selectAll=document.createElement("input"),this.selectAll.type="checkbox",this.selectAll.classList.add(St),this.selectAll.classList.add(kt),this.selectAll.addEventListener("change",this);let i=document.createElement("label");i.appendChild(this.selectAll),e.appendChild(i),e.setAttribute("width","40"),t.appendChild(e)}createFilterCol(t){let e=document.createElement("th");c(e,"role","columnheader button"),c(e,"aria-colindex",this.colIndex()),e.classList.add(H),e.tabIndex=0,t.appendChild(e)}shouldSelectAll(t){this.selectAll&&(t.addEventListener("change",this),t.dispatchEvent(new Event("change")))}createDataCol(t){let e=document.createElement("td");c(e,"role","gridcell button"),c(e,"aria-colindex",this.colIndex()),e.classList.add(H);let i=document.createElement("input");i.dataset.id=t.getAttribute("aria-rowindex"),i.type="checkbox",i.classList.add(kt);let o=document.createElement("label");o.classList.add("dg-clickable-cell"),o.appendChild(i),e.appendChild(o),o.addEventListener("click",this),t.appendChild(e)}onclick(t){t.stopPropagation()}onchange(t){let e=this.grid;if(T(t.target,St)){let i=e.options.selectVisibleOnly,o=g(e,`tbody .${H} input`);for(let r of o){if(i&&!r.offsetWidth)return;r.checked=this.selectAll.checked}v(e,"rowsSelected",{selection:this.getSelection()})}else{if(!t.target.closest(`.${H}`))return;let i=g(e,`tbody .${H} input[type=checkbox]`),o=i.filter(r=>r.checked);this.selectAll.checked=o.length===i.length,v(e,"rowsSelected",{selection:e.getSelection()})}}},Lt=at;var lt=class extends m{constructor(t){super(t),this.hasFixedHeight=!1,t.style.height&&(t.style.overflowY="auto",this.hasFixedHeight=!0)}createFakeRow(){let e=this.grid.querySelector("tbody"),i=document.createElement("tr");c(i,"role","row"),c(i,"hidden",""),i.classList.add("dg-fake-row"),i.tabIndex=0,e.appendChild(i)}get fakeRow(){return this.grid.querySelector(".dg-fake-row")}updateFakeRow(){let t=this.grid,e=this.fakeRow;if(!e||t.options.perPage>t.totalRecords()||t.page!==t.totalPages()||!t.options.autoheight)return;let i=t.options.perPage*t.rowHeight,o=t.querySelectorAll("tbody tr:not([hidden])").length,r=o>1?i-o*t.rowHeight:i;r>0?(c(e,"height",r),e.removeAttribute("hidden")):e.removeAttribute("height")}},Et=lt;var dt=class extends m{computeSize(t,e,i,o){let r=this.grid;if(U(t,"width"))return D(t,"width");if(!r.data.length)return;let s=r.data[0],l=r.data[r.data.length-1],a=s[e.field]?s[e.field].toString():"",d=l[e.field]?l[e.field].toString():"";d.length>a.length&&(a=d);let u=0;return a.length<=6?u=i:a.length>50?u=o:u=_(`${a}0000`,t),u>o&&(u=o),u{let i=Number.parseInt(t.dataset.responsive)||1;return(Number.parseInt(e.dataset.responsive)||1)-i})}var Wt=q(n=>{for(let t of n){let e=t.target,i=e.table;if(e.plugins.ResponsiveGrid.observerBlocked)return;let o=Array.isArray(t.contentBoxSize)?t.contentBoxSize[0]:t.contentBoxSize,r=Number.parseInt(o.inlineSize),s=i.offsetWidth,l=g(e.headerRow,"th").reduce((P,w)=>P+w.offsetWidth,0),a=(l||s)-r-1,d=50,u=e.plugins.ResponsiveGrid.prevAction,h=Ft(g(e.headerRow,"th[field]").reverse().filter(P=>P.dataset.responsive!=="0")),p=!1;if(e.log(`table is ${s}/${l} and available size is ${r}. Diff: ${a}`),a>0){if(u==="show")return;e.plugins.ResponsiveGrid.prevAction="hide";let P=a,w=h.filter(y=>!y.hasAttribute("hidden")&&y.hasAttribute("data-responsive"));if(w.length===0&&(w=h.filter(y=>!y.hasAttribute("hidden")),w.length===1))return;for(let y of w){if(P<0)continue;let $=y.offsetWidth,R=y.getAttribute("field");R&&(y.dataset.baseWidth=`${y.offsetWidth}`,e.hideColumn(R,!1),e.setColProp(R,"responsiveHidden",!0),p=!0,P-=$,P=Math.round(P))}}else{if(u==="hide")return;e.plugins.ResponsiveGrid.prevAction="show";let P=h.filter($=>!$.hasAttribute("hidden")).reduce(($,R)=>{let z=R.dataset.minWidth?Number.parseInt(R.dataset.minWidth):R.offsetWidth;return $+z},0)+d,w=r-P,y=h.slice().reverse().filter($=>$.hasAttribute("hidden"));for(let $ of y){if(ww){w=-1;continue}let z=$.getAttribute("field");z&&(e.showColumn(z,!1),e.setColProp(z,"responsiveHidden",!1),p=!0,w-=R,w=Math.round(w))}}let f=N(e.table,"tfoot"),b=g(e.table,".dg-footer > div").reduce((P,w)=>P+w.offsetWidth,0),S=f.offsetWidth-b;b>r?E(f,"dg-footer-compact"):S>250&&W(f,"dg-footer-compact"),p&&e.renderTable(),setTimeout(()=>{e.plugins.ResponsiveGrid.prevAction=null},1e3),e.table.style.visibility="visible"}},100),$t=new ResizeObserver(Wt),ht=class extends m{constructor(t){super(t),this.observerBlocked=!1,this.prevAction=null}connected(){this.grid.options.responsive&&this.observe()}disconnected(){this.unobserve()}observe(){this.grid.options.responsive&&($t.observe(this.grid),this.grid.style.display="block",this.grid.style.overflowX="hidden")}unobserve(){$t.unobserve(this.grid),this.grid.style.display="unset",this.grid.style.overflowX="unset"}blockObserver(){this.observerBlocked=!0,ct&&clearTimeout(ct)}unblockObserver(){ct=setTimeout(()=>{this.observerBlocked=!1},200)}hasHiddenColumns(){let t=!1;for(let e of this.grid.options.columns)e.responsiveHidden&&(t=!0);return t}colIndex(){return this.grid.startColIndex()-1}createHeaderCol(t){if(!this.grid.options.responsiveToggle)return;let e=x("th",t);c(e,"scope","col"),c(e,"role","columnheader button"),c(e,"aria-colindex",this.colIndex()),c(e,"width","40"),e.classList.add(`${k}-toggle`,"dg-not-resizable","dg-not-sortable"),e.tabIndex=0}createFilterCol(t){if(!this.grid.options.responsiveToggle)return;let e=x("th",t);c(e,"role","columnheader button"),c(e,"aria-colindex",this.colIndex()),e.classList.add(`${k}-toggle`),e.tabIndex=0}createDataCol(t){if(!this.grid.options.responsiveToggle)return;let e=document.createElement("td");c(e,"role","gridcell button"),c(e,"aria-colindex",this.colIndex()),e.classList.add(`${k}-toggle`),e.innerHTML=``,t.appendChild(e),e.addEventListener("click",this),e.addEventListener("mousedown",this)}computeLabelWidth(){let t=0,e=0;for(;t<120;){e++;let i=N(this.grid,`.dg-head-columns th[aria-colindex="${e}"]`);if(i)t+=i.offsetWidth;else break}return t}onmousedown(t){t.preventDefault()}onclick(t){t.stopPropagation();let e=t.currentTarget,i=e.parentElement,o=N(e,`.${L}-open`),n=N(e,`.${L}-close`);if(this.blockObserver(),T(i,`${L}-expanded`)){W(i,`${L}-expanded`),o.style.display="unset",n.style.display="none";let l=i.nextElementSibling,a=g(l,`.${L}-hidden`);for(let d of a)i.appendChild(d),c(d,"hidden");l.parentElement.removeChild(l)}else{E(i,`${L}-expanded`),o.style.display="none",n.style.display="unset";let l=x("tr");xt(l,i),E(l,`${L}-child-row`);let a=x("td",l);c(a,"colspan",this.grid.columnsLength(!0));let d=x("table",a);E(d,`${L}-table`);let u=g(i,`.${L}-hidden`),h=this.computeLabelWidth();for(let p of u){let f=x("tr",d),b=p.dataset.name,S=x("th",f);S.style.width=`${h}px`,S.innerHTML=b,f.appendChild(p),k(p,"hidden")}}this.unblockObserver()}},It=gt;var pt=class extends m{hasActions(){return this.grid.options.actions.length>0}makeActionHeader(t){let e=document.createElement("th");c(e,"role","columnheader button"),c(e,"aria-colindex",this.grid.columnsLength(!0)),e.classList.add("dg-actions","dg-not-sortable","dg-not-resizable",this.actionClass),e.tabIndex=0,t.appendChild(e)}makeActionFilter(t){let e=document.createElement("th");e.setAttribute("role","columnheader button"),c(e,"aria-colindex",this.grid.columnsLength(!0)),e.classList.add("dg-actions",this.actionClass),e.tabIndex=0,t.appendChild(e)}makeActionRow(t,e){let i=this.grid.labels,o=document.createElement("td");c(o,"role","gridcell"),c(o,"aria-colindex",this.grid.columnsLength(!0)),o.classList.add("dg-actions",this.actionClass),o.tabIndex=0;let n=document.createElement("button");n.classList.add("dg-actions-toggle"),n.innerHTML="\u2630",o.appendChild(n),A(n,"click",s=>{s.stopPropagation(),s.target.parentElement.classList.toggle("dg-actions-expand")});for(let s of this.grid.options.actions){let l=document.createElement("button");s.html?l.innerHTML=s.html:l.innerText=s.title??s.name,s.title&&(l.title=s.title),s.url&&(l.type="submit",l.formAction=M(s.url,e)),s.class&&l.classList.add(...s.class.split(" "));let a=d=>{if(d.stopPropagation(),s.confirm&&!confirm(i.areYouSure)){d.preventDefault();return}y(this.grid,"action",{data:e,action:s.name})};l.addEventListener("click",a),o.appendChild(l),s.default&&(t.classList.add("dg-actionable"),t.addEventListener("click",a))}t.appendChild(o)}get actionClass(){return this.grid.options.actions.length<3&&!this.grid.options.collapseActions?`dg-actions-${this.grid.options.actions.length}`:"dg-actions-more"}},Tt=pt;var ft=class extends m{makeEditableInput(t,e,i,o){let n=this.grid.getAttribute("id"),s=document.createElement("input");s.type=e.editableType||"text",s.type==="email"&&(s.inputMode="email"),s.type==="decimal"&&(s.type="text",s.inputMode="decimal"),s.autocomplete="off",s.spellcheck=!1,s.tabIndex=0,s.classList.add("dg-editable"),s.name=`${n.replace("-","_")}[${o+1}][${e.field}]`,s.value=i[e.field],s.dataset.field=e.field,s.addEventListener("click",l=>l.stopPropagation()),s.addEventListener("keypress",l=>{if(l.type==="keypress"){let a=l.keyCode||l.key;(a===13||a==="Enter")&&(s.blur(),l.preventDefault())}}),s.addEventListener("blur",()=>{s.value!==i[s.dataset.field]&&(i[s.dataset.field]=s.value,y(this.grid,"edit",{data:i,value:s.value}))}),t.appendChild(s)}},Nt=ft;var mt=class extends m{connected(){this.grid.options.spinnerClass&&this.grid.plugins.SpinnerSupport&&this.add()}add(){let t=this.grid,e=t.options.spinnerClass;if(!e)return;let i=e.split(" ").map(n=>`.${n}`).join(""),o=`
-`;if(!I("#dg-styles")){let r=I("head")??I("body"),s=/head/i.test(r.tagName)?"beforeend":"afterbegin";r.insertAdjacentHTML(s,o)}!I(`i${i}`,t)&&t.insertAdjacentHTML("afterbegin",``)}},Nt=pt;var ft=class extends m{constructor(t){super(t),this.cachedState=null,this.isFilterSortSet=!1,this.isDataLoaded=!1,this.isScrolled=!1,this.log("Init")}connected(){this.log("connected");let t=this.grid;if(this.log(t.options),!t.options.saveState){this.log("disabled");return}this.log("enabled");let e=this._getState();if(e){this.log("hide columns");for(let o of e.columns)if(o.hidden){let r=t.options.columns.find(s=>s.field===o.field);r.hidden=!0}this.log("set: meta, pages"),t.options.perPage=e.perPage,t.options.server&&(t.meta=e.meta,t.pages=e.pages,t.page=e.page)}this.cachedState=e,this.log("cachedState",this.cachedState),setTimeout(()=>{let o=t.loadData;t.loadData=function(...r){return o.apply(this,r).finally(()=>{let s=this.plugins.SaveState;if(s.log("loadData",this.options.columns),!t.classList.contains("dg-initialized")){s.log("not init, loadData skipped");return}if(s.log("loadData finished, set param controls",this.options.columns),s.cachedState&&!s.isFilterSortSet){s.log("set sort and filters");let d=g(t,"thead tr.dg-head-columns th[aria-sort]");for(let h of d)h.setAttribute("aria-sort","none");t.querySelector(`thead tr.dg-head-columns th[field='${s.cachedState.sort}']`)?.setAttribute("aria-sort",s.cachedState.sortDir);let u=g(t.filterRow,"[id^=dg-filter]");s.log("filters",u);for(let h of u)h.value=s?.cachedState?.filters?.[h.dataset.name]??"",s.log({name:h.dataset.name,val:h.value,saveState:s});s.isFilterSortSet=!0}let l={meta:t.meta,pages:t.pages,page:t.page,perPage:t.options.perPage,filters:{},columns:t.options.columns.map(d=>({field:d.field,hidden:d.hidden})),sort:t.getSort(),sortDir:t.getSortDir(),scrollTo:window.scrollY},a=t.getFilters();s.log("filters",a);for(let d of Object.keys(a))l.filters[d]=a[d]??"",s.log({key:d,val:a[d],newState:l,filters:a});s.log("store new state",l),s._setState(l),!t.options.server&&s.cachedState&&!s.isDataLoaded&&(s.isDataLoaded=!0,t.filterData(),t.page=s.cachedState.page,t.pageChanged(),s.log("data loaded"))})}},0);let i=()=>{let o=t.plugins.SaveState,r=o._getState();r&&(r.columns=t.options.columns.map(s=>({field:s.field,hidden:s.hidden})),r.sort=t.getSort(),r.sortDir=t.getSortDir(),r.scrollTo=window.scrollY,o._setState(r))};document.addEventListener("scrollend",i),t.addEventListener("headerRendered",i),t.addEventListener("bodyRendered",o=>{if(!t.classList.contains("dg-initialized")||t.classList.contains("dg-loading"))return;t.options.server||i();let r=t.plugins.SaveState;!r.cachedState||!r.isFilterSortSet||(r.isDataLoaded?r.isScrolled||(r.isScrolled=!0,window.scrollTo({top:r.cachedState.scrollTo,left:0,behavior:"instant"})):(r.isDataLoaded=!0,t.reload(),r.log("***grid reloaded")))})}log(...t){this.grid.log("[Save-State] ",...t)}_getState(){let t;try{t=JSON.parse(sessionStorage.getItem(`gridSaveState_${this.grid.id}`))}catch{}return t}_setState(t){sessionStorage.setItem(`gridSaveState_${this.grid.id}`,JSON.stringify(t))}},Ht=ft;j.registerPlugins({ColumnResizer:Ct,ContextMenu:wt,DraggableHeaders:Pt,TouchSupport:At,SelectableRows:Lt,FixedHeight:Et,AutosizeColumn:Dt,ResponsiveGrid:Rt,RowActions:It,EditableColumn:Tt,SpinnerSupport:Nt,SaveState:Ht});customElements.get("data-grid")||customElements.define("data-grid",j);var yi=j,Mt=typeof globalThis<"u"?globalThis:self;Mt.DataGrid=j;export{yi as default};
+`;if(!I("#dg-styles")){let n=I("head")??I("body"),s=/head/i.test(n.tagName)?"beforeend":"afterbegin";n.insertAdjacentHTML(s,o)}!I(`i${i}`,t)&&t.insertAdjacentHTML("afterbegin",``)}},Ht=mt;var bt=class extends m{constructor(t){super(t),this.cachedState=null,this.isFilterSortSet=!1,this.isDataLoaded=!1,this.isScrolled=!1,this.log("Init")}async connected(){this.log("connected");let t=this.grid;if(this.log(t.options),!t.options.saveState){this.log("disabled");return}this.log("enabled");let e=this._getState();if(e){let n=async()=>{if(!t.options.server)return;let l=500,a=Date.now(),d;for(;(d=!t.options.columns?.length)&&Date.now()-arequestAnimationFrame(u));d&&this.log("Timeout waiting for columns.")};await(async()=>{await n(),this.log("hide columns");for(let l of e.columns)if(l.hidden){let a=t.options.columns.find(d=>d.field===l.field);a.hidden=!0}this.log("set: meta, pages"),t.options.perPage=e.perPage,t.options.server&&(t.meta=e.meta,t.pages=e.pages,t.page=e.page)})()}this.cachedState=e,this.log("cachedState",this.cachedState);let i=t.loadData;t.loadData=function(...n){return i.apply(this,n).finally(()=>{let s=this.plugins.SaveState;if(s.log("loadData",this.options.columns),!t.classList.contains("dg-initialized")){s.log("not init, loadData skipped");return}if(s.log("loadData finished, set param controls",this.options.columns),s.cachedState&&!s.isFilterSortSet){s.log("set sort and filters");let d=g(t,"thead tr.dg-head-columns th[aria-sort]");for(let h of d)h.setAttribute("aria-sort","none");t.querySelector(`thead tr.dg-head-columns th[field='${s.cachedState.sort}']`)?.setAttribute("aria-sort",s.cachedState.sortDir);let u=g(t.filterRow,"[id^=dg-filter]");s.log("filters",u);for(let h of u)h.value=s?.cachedState?.filters?.[h.dataset.name]??"",s.log({name:h.dataset.name,val:h.value,saveState:s});s.isFilterSortSet=!0}let l={meta:t.meta,pages:t.pages,page:t.page,perPage:t.options.perPage,filters:{},columns:t.options.columns.map(d=>({field:d.field,hidden:d.hidden})),sort:t.getSort(),sortDir:t.getSortDir(),scrollTo:window.scrollY},a=t.getFilters();s.log("filters",a);for(let d of Object.keys(a))l.filters[d]=a[d]??"",s.log({key:d,val:a[d],newState:l,filters:a});s.log("store new state",l),s._setState(l),!t.options.server&&s.cachedState&&!s.isDataLoaded&&(s.isDataLoaded=!0,t.filterData(),t.page=s.cachedState.page,t.pageChanged(),s.log("data loaded"))})};let o=()=>{let n=t.plugins.SaveState,s=n._getState();s&&(s.columns=t.options.columns.map(l=>({field:l.field,hidden:l.hidden})),s.sort=t.getSort(),s.sortDir=t.getSortDir(),s.scrollTo=window.scrollY,n._setState(s))};document.addEventListener("scrollend",o),t.addEventListener("headerRendered",o),t.addEventListener("bodyRendered",n=>{if(!t.classList.contains("dg-initialized")||t.classList.contains("dg-loading"))return;t.options.server||o();let s=t.plugins.SaveState;!s.cachedState||!s.isFilterSortSet||(s.isDataLoaded?s.isScrolled||(s.isScrolled=!0,window.scrollTo({top:s.cachedState.scrollTo,left:0,behavior:"instant"})):(s.isDataLoaded=!0,t.reload(),s.log("***grid reloaded")))})}log(...t){this.grid.log("[Save-State] ",...t)}_getState(){let t;try{t=JSON.parse(sessionStorage.getItem(`gridSaveState_${this.grid.id}`))}catch{}return t}_setState(t){sessionStorage.setItem(`gridSaveState_${this.grid.id}`,JSON.stringify(t))}},Ot=bt;j.registerPlugins({ColumnResizer:Pt,ContextMenu:At,DraggableHeaders:St,TouchSupport:Lt,SelectableRows:Et,FixedHeight:Dt,AutosizeColumn:$t,ResponsiveGrid:It,RowActions:Tt,EditableColumn:Nt,SpinnerSupport:Ht,SaveState:Ot});customElements.get("data-grid")||customElements.define("data-grid",j);var xi=j,Mt=typeof globalThis<"u"?globalThis:self;Mt.DataGrid=j;export{xi as default};
/**
* Data Grid custom element
* https://github.com/lekoala/data-grid/
diff --git a/dist/data-grid.min.js.map b/dist/data-grid.min.js.map
index 93108ad..66aae5b 100644
--- a/dist/data-grid.min.js.map
+++ b/dist/data-grid.min.js.map
@@ -1,7 +1,7 @@
{
"version": 3,
"sources": ["../src/utils/camelize.js", "../src/utils/normalizeData.js", "../src/utils/shortcuts.js", "../src/core/base-element.js", "../src/utils/addSelectOption.js", "../src/utils/appendParamsToUrl.js", "../src/utils/convertArray.js", "../src/utils/elementOffset.js", "../src/utils/interpolate.js", "../src/utils/getTextWidth.js", "../src/utils/randstr.js", "../src/utils/debounce.js", "../src/data-grid.js", "../src/core/base-plugin.js", "../src/plugins/column-resizer.js", "../src/utils/getParentElement.js", "../src/plugins/context-menu.js", "../src/plugins/draggable-headers.js", "../src/plugins/touch-support.js", "../src/plugins/selectable-rows.js", "../src/plugins/fixed-height.js", "../src/plugins/autosize-column.js", "../src/plugins/responsive-grid.js", "../src/plugins/row-actions.js", "../src/plugins/editable-column.js", "../src/plugins/spinner-support.js", "../src/plugins/save-state.js", "../data-grid.js"],
- "sourcesContent": ["/**\n * @param {String} str\n * @returns {String}\n */\nexport default function camelize(str) {\n return str.toLowerCase().replace(/[^a-zA-Z0-9]+(.)/g, (m, chr) => chr.toUpperCase());\n}\n", "/**\n * Parse data attribute and return properly typed data\n * @param {String} v\n * @returns {any}\n */\nexport default function normalizeData(v) {\n // Bool\n if (v === \"true\") {\n return true;\n }\n if (v === \"false\") {\n return false;\n }\n // Null or empty\n if (v === \"\" || v === \"null\") {\n return null;\n }\n // Numeric attributes\n if (v === Number(v).toString()) {\n return Number(v);\n }\n // Only attempt json parsing for array or objects\n if (v && [\"[\", \"{\"].includes(v.substring(0, 1))) {\n try {\n // In case we have only single quoted values, like ['one', 'two', 'three']\n let val = v;\n if (val.indexOf('\"') === -1) {\n val = val.replace(/'/g, '\"');\n }\n return JSON.parse(decodeURIComponent(val));\n } catch {\n console.error(`Failed to parse ${v}`);\n return {};\n }\n }\n return v;\n}\n", "/**\n * @typedef FlexibleHTMLProps\n * @property {boolean} [checked] (HTMLInputElement)\n * @property {string} [value] (HTMLInputElement)\n * @property {number} [rowHeight] (HTMLTableRowElement)\n *\n * A flexible type HTMLElement type that does not require using instanceof all over the place\n * Make sure that your selector is indeed valid\n * Only includes most commons props\n * @typedef {HTMLElement & FlexibleHTMLProps} FlexibleHTMLElement\n */\n\n/**\n * Keep this as reference for easy documentation\n * @typedef {HTMLElement&HTMLInputElement&HTMLTableRowElement} MixedHTMLElement\n */\n\n/**\n * @typedef FlexibleEventProps\n * @property {FlexibleHTMLElement} target\n * @property {FlexibleHTMLElement} currentTarget\n * @property {DataTransfer} [dataTransfer] (DragEvent)\n * @property {number} [clientX] (MouseEvent)\n * @property {number} [clientY] (MouseEvent)\n *\n * @typedef {Event & FlexibleEventProps} FlexibleEvent\n */\n\n/**\n * Keep this as reference for easy documentation\n * @typedef {Event&MouseEvent&InputEvent&DragEvent&FocusEvent&KeyboardEvent&PointerEvent} MixedEvent\n */\n\n/**\n * @callback FlexibleListener\n * @param {FlexibleEvent} event\n */\n\nclass FlexibleEventListenerObject {\n /**\n * @param {FlexibleEvent} e\n */\n handleEvent(e) {}\n}\n\nconst supportedPassiveTypes = [\n \"scroll\",\n \"wheel\",\n \"touchstart\",\n \"touchmove\",\n \"touchenter\",\n \"touchend\",\n \"touchleave\",\n \"mouseout\",\n \"mouseleave\",\n \"mouseup\",\n \"mousedown\",\n \"mousemove\",\n \"mouseenter\",\n \"mousewheel\",\n \"mouseover\",\n];\n\n/**\n * Automatically set passive options based on type\n * @param {string} type\n * @returns {AddEventListenerOptions}\n */\nfunction passiveOpts(type) {\n if (supportedPassiveTypes.includes(type)) {\n return { passive: true };\n }\n return {};\n}\n\n/**\n * @param {Element} el\n * @param {String} name\n * @returns {any}\n */\nexport function getAttribute(el, name) {\n return el.getAttribute(name);\n}\n\n/**\n * @param {Element} el\n * @param {String} name\n * @returns {Boolean}\n */\nexport function hasAttribute(el, name) {\n return el.hasAttribute(name);\n}\n\n/**\n * @param {Element} el\n * @param {String} name\n * @param {any} v\n * @param {Boolean} check Prevent setting if attribute is already there\n */\nexport function setAttribute(el, name, v = \"\", check = false) {\n if (check && hasAttribute(el, name)) return;\n el.setAttribute(name, `${v}`);\n}\n\n/**\n * @param {Element} el\n * @param {String} name\n */\nexport function removeAttribute(el, name) {\n if (hasAttribute(el, name)) {\n el.removeAttribute(name);\n }\n}\n\n/**\n * @param {EventTarget} el\n * @param {String} type\n * @param {EventListenerObject|FlexibleListener} listener\n */\nexport function on(el, type, listener) {\n el.addEventListener(type, listener, passiveOpts(type));\n}\n\n/**\n * @param {EventTarget} el\n * @param {String} type\n * @param {EventListenerObject|FlexibleListener} listener\n */\nexport function off(el, type, listener) {\n el.removeEventListener(type, listener, passiveOpts(type));\n}\n\n/**\n * @param {EventTarget} el\n * @param {String} type\n * @param {EventListenerObject|FlexibleListener} listener\n */\nexport function one(el, type, listener) {\n el.addEventListener(type, listener, {\n once: true,\n });\n}\n\n/**\n * @param {HTMLElement} el\n * @param {String} name\n * @param {any} data\n * @param {Boolean} bubbles\n */\nexport function dispatch(el, name, data = {}, bubbles = false) {\n const opts = {};\n if (bubbles) {\n opts.bubbles = true;\n }\n if (data) {\n opts.detail = data;\n }\n el.dispatchEvent(new CustomEvent(name, opts));\n}\n\n/**\n * @param {Element} el\n * @param {String} name\n * @returns {Boolean}\n */\nexport function hasClass(el, name) {\n return el.classList.contains(name);\n}\n\n/**\n * @param {Element} el\n * @param {String} name\n */\nexport function addClass(el, name) {\n el.classList.add(...name.split(\" \"));\n}\n\n/**\n * @param {Element} el\n * @param {String} name\n */\nexport function removeClass(el, name) {\n el.classList.remove(...name.split(\" \"));\n}\n\n/**\n * @param {Element} el\n * @param {String} name\n */\nexport function toggleClass(el, name) {\n el.classList.toggle(name);\n}\n\n/**\n * @param {String|HTMLElement} selector\n * @param {HTMLElement|Document} base\n * @returns {FlexibleHTMLElement|null}\n */\nexport function $(selector, base = document) {\n if (selector instanceof HTMLElement) {\n return selector;\n }\n return base.querySelector(selector);\n}\n\n/**\n * @param {String} selector\n * @param {Element|Document} base\n * @returns {Array}\n */\nexport function $$(selector, base = document) {\n return Array.from(base.querySelectorAll(selector));\n}\n\n/**\n * Easily retrieve untyped element\n * For actual type, prefer use of el.querySelector\n * @param {HTMLElement} el\n * @param {String|HTMLElement} selector\n * @returns {FlexibleHTMLElement}\n */\nexport function find(el, selector) {\n return $(selector, el);\n}\n\n/**\n * Easily retrieve untyped elements\n * For actual type, prefer use of el.querySelectorAll\n * @param {Element} el\n * @param {String} selector\n * @returns {Array}\n */\nexport function findAll(el, selector) {\n return $$(selector, el);\n}\n\n/**\n * @param {*} el\n * @returns {FlexibleHTMLElement}\n */\nexport function el(el) {\n return el;\n}\n\n/**\n * @template {keyof HTMLElementTagNameMap} K\n * @param {K} tagName\n * @param {HTMLElement} parent\n * @returns {HTMLElementTagNameMap[K]}\n */\nexport function ce(tagName, parent = null) {\n const el = document.createElement(tagName);\n if (parent) {\n parent.appendChild(el);\n }\n return el;\n}\n\n/**\n * @param {HTMLElement} newNode\n * @param {HTMLElement} existingNode\n */\nexport function insertAfter(newNode, existingNode) {\n existingNode.parentNode.insertBefore(newNode, existingNode.nextSibling);\n}\n", "import camelize from \"../utils/camelize.js\";\r\nimport normalizeData from \"../utils/normalizeData.js\";\r\nimport { dispatch, getAttribute, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/** @typedef {import('../data-grid').Options} Options */\r\n\r\n/**\r\n * Base element that does not contain any specific logic\r\n * related to this project but makes HTMLElemnt usable\r\n */\r\nclass BaseElement extends HTMLElement {\r\n /**\r\n * @param {Object} options\r\n */\r\n constructor(options = {}) {\r\n super();\r\n\r\n /** @type {Options} */\r\n this.options = Object.assign({}, this.defaultOptions, this.normalizedDataset, options);\r\n\r\n this.log(\"constructor\");\r\n\r\n this.setup = false;\r\n this.fireEvents = true;\r\n this._ready();\r\n\r\n this.log(\"ready\");\r\n }\r\n\r\n get defaultOptions() {\r\n return {};\r\n }\r\n\r\n /**\r\n * @param {String} opt\r\n * @returns {any}\r\n */\r\n getOption(opt) {\r\n return this.options[opt];\r\n }\r\n\r\n /**\r\n * @param {String} opt\r\n * @param {any} v\r\n */\r\n setOption(opt, v) {\r\n setAttribute(this, `data-${opt}`, v);\r\n }\r\n\r\n /**\r\n * @param {String} opt\r\n */\r\n toggleOption(opt) {\r\n setAttribute(this, `data-${opt}`, !this.getOption(opt));\r\n }\r\n\r\n get normalizedDataset() {\r\n const jsonConfig = this.dataset.config ? JSON.parse(this.dataset.config) : {};\r\n const data = { ...this.dataset };\r\n for (const key in data) {\r\n if (key === \"config\") {\r\n continue;\r\n }\r\n data[key] = normalizeData(data[key]);\r\n }\r\n // Once normalized, merge into json config\r\n Object.assign(data, jsonConfig);\r\n return data;\r\n }\r\n\r\n /**\r\n * @returns {String}\r\n */\r\n static template() {\r\n return \"\";\r\n }\r\n\r\n /**\r\n * This is called at the end of constructor. Extend in subclass if needed.\r\n */\r\n _ready() {}\r\n\r\n /**\r\n * @param {any[]} data\r\n */\r\n log(...data) {\r\n if (this.options.debug) {\r\n console.log(`[${getAttribute(this, \"id\")}] `, ...data);\r\n }\r\n }\r\n\r\n /**\r\n * Handle events within the component\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#handling-events\r\n * @param {Event} event\r\n */\r\n handleEvent(event) {\r\n if (this[`on${event.type}`]) {\r\n this[`on${event.type}`](event);\r\n }\r\n }\r\n\r\n /**\r\n * This is called when connected. Extend in subclass if needed.\r\n */\r\n _connected() {}\r\n\r\n connectedCallback() {\r\n // already connected\r\n if (this.setup) {\r\n return;\r\n }\r\n this.setup = true;\r\n // ensure whenDefined callbacks run first\r\n setTimeout(() => {\r\n this.log(\"connectedCallback\");\r\n\r\n // Append only when labels had the opportunity to be set\r\n // Don't use shadow dom as it makes theming super hard\r\n const template = document.createElement(\"template\");\r\n // @ts-ignore\r\n template.innerHTML = this.constructor.template();\r\n this.appendChild(template.content.cloneNode(true));\r\n\r\n this._connected();\r\n // @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#life-cycle-events\r\n dispatch(this, \"connected\");\r\n }, 0);\r\n }\r\n\r\n /**\r\n * This is called when disconnected. Extend in subclass if needed.\r\n */\r\n _disconnected() {}\r\n\r\n /**\r\n * @link https://nolanlawson.com/2024/12/01/avoiding-unnecessary-cleanup-work-in-disconnectedcallback/\r\n */\r\n disconnectedCallback() {\r\n setTimeout(() => {\r\n if (!this.isConnected && this.setup) {\r\n this.log(\"disconnectedCallback\");\r\n this._disconnected();\r\n // @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#life-cycle-events\r\n dispatch(this, \"disconnected\");\r\n this.setup = false;\r\n }\r\n }, 0);\r\n }\r\n\r\n /**\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#a-props-like-accessor\r\n * @returns {Object}\r\n */\r\n get transformAttributes() {\r\n return {};\r\n }\r\n\r\n /**\r\n * This is only meant to work with data attributes\r\n * This allows us to have properties that reflect automatically in the component\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#reflected-dataset-attributes\r\n * @param {String} attributeName\r\n * @param {String} oldValue\r\n * @param {String} newValue\r\n */\r\n attributeChangedCallback(attributeName, oldValue, newValue) {\r\n // It didn't change\r\n if (oldValue === newValue) {\r\n return;\r\n }\r\n\r\n this.log(`attributeChangedCallback: ${attributeName}`);\r\n\r\n let isOption = false;\r\n const transformer = this.transformAttributes[attributeName] ?? normalizeData;\r\n\r\n let attr = attributeName;\r\n // Data attributes are mapped to options while other attributes are mapped as properties\r\n if (attr.indexOf(\"data-\") === 0) {\r\n attr = attr.slice(5);\r\n isOption = true;\r\n }\r\n attr = camelize(attr);\r\n if (isOption) {\r\n this.options[attr] = transformer(newValue);\r\n } else {\r\n this[attr] = transformer(newValue);\r\n }\r\n\r\n // Fire internal event\r\n if (this.fireEvents && this[`${attr}Changed`]) {\r\n this[`${attr}Changed`]();\r\n }\r\n }\r\n}\r\n\r\nexport default BaseElement;\r\n", "/**\n * @param {HTMLSelectElement} el\n * @param {String} value\n * @param {String} label\n * @param {Boolean} checked\n */\nexport default function addSelectOption(el, value, label, checked = false) {\n const opt = document.createElement(\"option\");\n opt.value = `${value}`;\n if (checked) {\n opt.selected = true;\n }\n opt.label = label;\n el.appendChild(opt);\n}\n", "/**\n * @param {URL} url\n * @param {Object} params\n */\nexport default function appendParamsToUrl(url, params = {}) {\n for (const key of Object.keys(params)) {\n if (Array.isArray(params[key])) {\n for (const k of Object.keys(params[key])) {\n // @ts-ignore\n url.searchParams.append(isNaN(k) ? `${key}[${k}]` : key, params[key][k]);\n }\n } else {\n url.searchParams.append(key, params[key]);\n }\n }\n}\n", "/**\n * Force value as arrays\n * @param {String|Array} v\n * @returns {Array}\n */\nexport default function convertArray(v) {\n if (typeof v === \"string\") {\n if (v[0] === \"[\") {\n // \"['my', 'value']\" would fail as a json\n let bv = v;\n if (bv.indexOf('\"') === -1) {\n bv = bv.replace(/'/g, '\"');\n }\n return JSON.parse(bv);\n }\n\n return v.split(\",\");\n }\n if (!Array.isArray(v)) {\n console.error(\"Invalid array\", v);\n return [];\n }\n return v;\n}\n", "/**\n * @param {HTMLElement} el\n * @returns {Object}\n */\nexport default function elementOffset(el) {\n const rect = el.getBoundingClientRect();\n const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;\n const scrollTop = window.pageYOffset || document.documentElement.scrollTop;\n return { top: rect.top + scrollTop, left: rect.left + scrollLeft };\n}\n", "/**\n * Replace element within {} by their data value\n * @param {String} str\n * @param {Object} data\n * @returns {String}\n */\nexport default function interpolate(str, data) {\n return str.replace(/\\{([^}]+)?\\}/g, ($1, $2) => data[$2]);\n}\n", "let canvas;\n\n/**\n * Uses canvas.measureText to compute and return the width of the given text of given font in pixels.\n * Getting computed styles only works for dom that are added in the dom\n * @see https://stackoverflow.com/questions/118241/calculate-text-width-with-javascript/21015393#21015393\n * @param {String} text The text to be rendered.\n * @param {Element} el Target element (defaults to body)\n * @param {Boolean} withPadding Include padding on element\n * @returns {Number}\n */\nexport default function getTextWidth(text, el = document.body, withPadding = false) {\n const styles = window.getComputedStyle(el || document.createElement(\"div\"));\n const fontWeight = styles.getPropertyValue(\"font-weight\") || \"normal\";\n const fontSize = styles.getPropertyValue(\"font-size\") || \"1rem\";\n const fontFamily = styles.getPropertyValue(\"font-family\") || \"Arial\";\n\n let padding = 0;\n if (withPadding) {\n const paddingLeft = styles.getPropertyValue(\"padding-left\") || \"0\";\n const paddingRight = styles.getPropertyValue(\"padding-right\") || \"0\";\n padding = Number.parseInt(paddingLeft) + Number.parseInt(paddingRight);\n }\n\n // re-use canvas object for better performance\n if (!canvas) {\n canvas = document.createElement(\"canvas\");\n }\n const context = canvas.getContext(\"2d\");\n context.font = `${fontWeight} ${fontSize} ${fontFamily}`;\n const metrics = context.measureText(text);\n return Number.parseInt(metrics.width) + padding;\n}\n", "/**\n * @param {String} prefix\n * @returns {String}\n */\nexport default function randstr(prefix) {\n return Math.random()\n .toString(36)\n .replace(\"0.\", prefix || \"\");\n}\n", "/**\n * Define a function that can be happily passed to addEventListener\n * @typedef {Function & EventListenerOrEventListenerObject} ExtendedFunction\n */\n\n/**\n * @param {Function} handler\n * @param {Number} timeout\n * @returns {ExtendedFunction}\n */\nexport default function debounce(handler, timeout = 300) {\n let timer = null;\n return (...args) => {\n clearTimeout(timer);\n timer = setTimeout(() => {\n timer = null;\n handler(...args);\n }, timeout);\n };\n}\n", "/**\r\n * Data Grid Web component\r\n *\r\n * Credits for inspiration\r\n * @link https://github.com/riverside/zino-grid\r\n */\r\n\r\nimport BaseElement from \"./core/base-element.js\";\r\nimport addSelectOption from \"./utils/addSelectOption.js\";\r\nimport appendParamsToUrl from \"./utils/appendParamsToUrl.js\";\r\nimport camelize from \"./utils/camelize.js\";\r\nimport convertArray from \"./utils/convertArray.js\";\r\nimport elementOffset from \"./utils/elementOffset.js\";\r\nimport interpolate from \"./utils/interpolate.js\";\r\nimport getTextWidth from \"./utils/getTextWidth.js\";\r\nimport randstr from \"./utils/randstr.js\";\r\nimport debounce from \"./utils/debounce.js\";\r\nimport {\r\n $,\r\n $$,\r\n dispatch,\r\n find,\r\n findAll,\r\n hasClass,\r\n removeAttribute,\r\n getAttribute,\r\n setAttribute,\r\n addClass,\r\n toggleClass,\r\n on,\r\n ce,\r\n} from \"./utils/shortcuts.js\";\r\n\r\n/**\r\n * Column definition\r\n * @typedef Column\r\n * @property {String} field - the key in the data\r\n * @property {String} title - the title to display in the header (defaults to \"field\" if not set)\r\n * @property {Number} [width] - the width of the column (auto otherwise)\r\n * @property {String} [class] - class to set on the column (target body or header with th.class or td.class)\r\n * @property {String} [attr] - don't render the column and set a matching attribute on the row with the value of the field\r\n * @property {Boolean} [hidden] - hide the column\r\n * @property {Boolean} [noSort] - allow disabling sort for a given column\r\n * @property {String | Function} [format] - custom data formatting\r\n * @property {String} [defaultFormatValue] - default value to use for formatting\r\n * @property {String} [transform] - custom value transformation\r\n * @property {Boolean} [editable] - replace with input (EditableColumn module)\r\n * @property {String} [editableType] - type of input (EditableColumn module)\r\n * @property {Number} [responsive] - the higher the value, the sooner it will be hidden, disable with 0 (ResponsiveGrid module)\r\n * @property {Boolean} [responsiveHidden] - hidden through responsive module (ResponsiveGrid module)\r\n * @property {String} [filterType] - defines a filter field type (\"text\" or \"select\" - defaults to \"text\")\r\n * @property {Array} [filterList] - defines a custom array to populate a filter select field in the format of [{value: \"\", text: \"\"},...]. When defined, it overrides the default behaviour where the filter select elements are populated by the unique values from the corresponding column records.\r\n * @property {Object} [firstFilterOption] - defines an object for the first option element of the filter select field. defaults to {value: \"\", text: \"\"}\r\n */\r\n\r\n/**\r\n * Row action\r\n * @typedef Action\r\n * @property {String} title - the title of the button\r\n * @property {String} name - the name of the action\r\n * @property {String} class - the class for the button\r\n * @property {String} url - link for the action\r\n * @property {String} html - custom button data\r\n * @property {Boolean} [confirm] - needs confirmation\r\n * @property {Boolean} default - is the default row action\r\n */\r\n\r\n// Import definitions without importing the actual file\r\n/** @typedef {import('./plugins/autosize-column').default} AutosizeColumn */\r\n/** @typedef {import('./plugins/column-resizer').default} ColumnResizer */\r\n/** @typedef {import('./plugins/context-menu').default} ContextMenu */\r\n/** @typedef {import('./plugins/draggable-headers').default} DraggableHeaders */\r\n/** @typedef {import('./plugins/editable-column').default} EditableColumn */\r\n/** @typedef {import('./plugins/fixed-height').default} FixedHeight */\r\n/** @typedef {import('./plugins/responsive-grid').default} ResponsiveGrid */\r\n/** @typedef {import('./plugins/row-actions').default} RowActions */\r\n/** @typedef {import('./plugins/selectable-rows').default} SelectableRows */\r\n/** @typedef {import('./plugins/touch-support').default} TouchSupport */\r\n/** @typedef {import('./plugins/spinner-support').default} SpinnerSupport */\r\n/** @typedef {import('./plugins/save-state').default} SaveState */\r\n\r\n/**\r\n * These plugins are all optional\r\n * @typedef {Object} Plugins\r\n * @property {ColumnResizer} [ColumnResizer] resize handlers in the headers\r\n * @property {ContextMenu} [ContextMenu] menu to show/hide columns\r\n * @property {DraggableHeaders} [DraggableHeaders] draggable headers columns\r\n * @property {EditableColumn} [EditableColumn] draggable headers columns\r\n * @property {TouchSupport} [TouchSupport] touch swipe\r\n * @property {SelectableRows} [SelectableRows] create a column with checkboxes to select rows\r\n * @property {FixedHeight} [FixedHeight] allows having fixed height tables\r\n * @property {AutosizeColumn} [AutosizeColumn] compute ideal width based on column content\r\n * @property {ResponsiveGrid} [ResponsiveGrid] hide/show column on the fly\r\n * @property {RowActions} [RowActions] add action on rows\r\n * @property {SpinnerSupport} [SpinnerSupport] inserts a spinning icon element to indicate grid loading.\r\n * @property {SaveState} [SaveState] stores grid filter, sort, and paging.\r\n */\r\n\r\n/**\r\n * Parameters to pass along or receive from the server\r\n * @typedef ServerParams\r\n * @property {String} serverParams.start\r\n * @property {String} serverParams.length\r\n * @property {String} serverParams.search\r\n * @property {String} serverParams.sort\r\n * @property {String} serverParams.sortDir\r\n * @property {String} serverParams.dataKey\r\n * @property {String} serverParams.metaKey\r\n * @property {String} serverParams.metaTotalKey\r\n * @property {String} serverParams.metaFilteredKey\r\n * @property {String} serverParams.optionsKey\r\n * @property {String} serverParams.paramsKey\r\n */\r\n\r\n/**\r\n * Available data grid options, plugins included\r\n * @typedef Options\r\n * @property {?String} id Custom id for the grid\r\n * @property {?String} url An URL with data to display in JSON format\r\n * @property {Boolean} debug Log actions in DevTools console\r\n * @property {Boolean} filter Allows a filtering functionality\r\n * @property {Boolean} sort Allows a sort by column functionality\r\n * @property {String} defaultSort Default sort field if sorting is enabled\r\n * @property {Boolean} server Is a server side powered grid\r\n * @property {ServerParams} serverParams Describe keys passed to the server backend\r\n * @property {String} dir Dir\r\n * @property {Array} perPageValues Available per page options\r\n * @property {Boolean} hidePerPage Hides the page size select element\r\n * @property {Column[]} columns Available columns\r\n * @property {Number} defaultPage Starting page\r\n * @property {Number} perPage Number of records displayed per page (page size)\r\n * @property {Boolean} expand Allow cell content to spawn over multiple lines\r\n * @property {Action[]} actions Row actions (RowActions module)\r\n * @property {Boolean} collapseActions Group actions (RowActions module)\r\n * @property {Boolean} resizable Make columns resizable (ColumnResizer module)\r\n * @property {Boolean} selectable Allow selecting rows with a checkbox (SelectableRows module)\r\n * @property {Boolean} selectVisibleOnly Select all only selects visible rows (SelectableRows module)\r\n * @property {Boolean} autosize Compute column sizes based on given data (Autosize module)\r\n * @property {Boolean} autoheight Adjust height so that it matches table size (FixedHeight module)\r\n * @property {Boolean} autohidePager auto-hides the pager when number of records falls below the selected page size\r\n * @property {Boolean} menu Right click menu on column headers (ContextMenu module)\r\n * @property {Boolean} reorder Allows a column reordering functionality (DraggableHeaders module)\r\n * @property {Boolean} responsive Change display mode on small screens (ResponsiveGrid module)\r\n * @property {Boolean} responsiveToggle Show toggle column (ResponsiveGrid module)\r\n * @property {Boolean} filterOnEnter Toggles the ability to filter column data by pressing the Enter or Return key\r\n * @property {String} spinnerClass Sets a space-delimited string of css classes for a spinner (use spinner-border css class for bootstrap 5 spinner)\r\n * @property {Number} filterKeypressDelay Sets a keypress delay time in milliseconds before triggering filter operation.\r\n * @property {Boolean} saveState Enable/disable save state plugin (SaveState module)\r\n * @property {?String} errorMessage A generic text to be displayed in footer when error occurs.\r\n */\r\n\r\n/**\r\n * Available labels that can be translated\r\n * @typedef Labels\r\n * @property {String} itemsPerPage\r\n * @property {String} gotoPage\r\n * @property {String} gotoFirstPage\r\n * @property {String} gotoPrevPage\r\n * @property {String} gotoNextPage\r\n * @property {String} gotoLastPage\r\n * @property {String} of\r\n * @property {String} items\r\n * @property {String} resizeColumn\r\n * @property {String} noData\r\n * @property {String} areYouSure\r\n * @property {String} networkError\r\n */\r\n\r\n/**\r\n * List of registered plugins\r\n * @type {Plugins}\r\n */\r\nlet plugins = {};\r\n\r\n/**\r\n * @type {Labels}\r\n */\r\nlet labels = {\r\n itemsPerPage: \"Items per page\",\r\n gotoPage: \"Go to page\",\r\n gotoFirstPage: \"Go to first page\",\r\n gotoPrevPage: \"Go to previous page\",\r\n gotoNextPage: \"Go to next page\",\r\n gotoLastPage: \"Go to last page\",\r\n of: \"of\",\r\n items: \"items\",\r\n resizeColumn: \"Resize column\",\r\n noData: \"No data\",\r\n areYouSure: \"Are you sure?\",\r\n networkError: \"Network response error\",\r\n};\r\n\r\n/**\r\n * Column definition will update some props on the html element\r\n * @param {HTMLElement} el\r\n * @param {Column} column\r\n */\r\nfunction applyColumnDefinition(el, column) {\r\n if (column.width) {\r\n setAttribute(el, \"width\", column.width);\r\n }\r\n if (column.class) {\r\n addClass(el, column.class);\r\n }\r\n if (column.hidden) {\r\n setAttribute(el, \"hidden\", \"\");\r\n if (column.responsiveHidden) {\r\n addClass(el, \"dg-responsive-hidden\");\r\n }\r\n }\r\n}\r\n\r\n/**\r\n */\r\nclass DataGrid extends BaseElement {\r\n _filterSelector = \"[id^=dg-filter]\";\r\n _excludedKeys = [\r\n 37,\r\n 39,\r\n 38,\r\n 40,\r\n 45,\r\n 36,\r\n 35,\r\n 33,\r\n 34,\r\n 27,\r\n 20,\r\n 16,\r\n 17,\r\n 91,\r\n 92,\r\n 18,\r\n 93,\r\n 144,\r\n 231,\r\n \"ArrowLeft\",\r\n \"ArrowRight\",\r\n \"ArrowUp\",\r\n \"ArrowDown\",\r\n \"Insert\",\r\n \"Home\",\r\n \"End\",\r\n \"PageUp\",\r\n \"PageDown\",\r\n \"Escape\",\r\n \"CapsLock\",\r\n \"Shift\",\r\n \"Control\",\r\n \"Meta\",\r\n \"Alt\",\r\n \"ContextMenu\",\r\n \"NumLock\",\r\n \"Unidentified\",\r\n ];\r\n\r\n _ready() {\r\n setAttribute(this, \"id\", this.options.id ?? randstr(\"el-\"), true);\r\n\r\n /**\r\n * The grid displays that data\r\n * @type {Array}\r\n */\r\n this.data = [];\r\n /**\r\n * We store the original data in this\r\n * @type {Array}\r\n */\r\n this.originalData; // declared uninitialized to allow data preloading before fetch.\r\n\r\n // Make the IDE happy\r\n /**\r\n * @type {Options}\r\n */\r\n this.options = this.options || this.defaultOptions;\r\n\r\n // Init values\r\n this.fireEvents = false;\r\n this.page = this.options.defaultPage || 1;\r\n this.pages = 0;\r\n this.meta; // declared uninitialized to allow data preloading before fetch.\r\n /**\r\n * @type {Plugins}\r\n */\r\n this.plugins = {};\r\n // Init plugins\r\n for (const [pluginName, pluginClass] of Object.entries(plugins)) {\r\n // @ts-ignore until we can set typeof import ...\r\n this.plugins[pluginName] = new pluginClass(this);\r\n }\r\n\r\n // Expose options as observed attributes in the dom\r\n // Do it when fireEvents is disabled to avoid firing change callbacks\r\n for (const attr of DataGrid.observedAttributes) {\r\n if (attr.indexOf(\"data-\") === 0) {\r\n setAttribute(this, attr, this.options[camelize(attr.slice(5))]);\r\n }\r\n }\r\n }\r\n\r\n static template() {\r\n return `\r\n\r\n \r\n |
\r\n
\r\n \r\n \r\n \r\n \r\n | \r\n \r\n | \r\n
\r\n \r\n \r\n
\r\n`;\r\n }\r\n\r\n /**\r\n * @returns {Labels}\r\n */\r\n get labels() {\r\n return labels;\r\n }\r\n\r\n /**\r\n * @returns {Labels}\r\n */\r\n static getLabels() {\r\n return labels;\r\n }\r\n\r\n /**\r\n * @param {Object} v\r\n */\r\n static setLabels(v) {\r\n labels = Object.assign(labels, v);\r\n }\r\n\r\n /**\r\n * @returns {Column}\r\n */\r\n get defaultColumn() {\r\n return {\r\n field: \"\",\r\n title: \"\",\r\n width: 0,\r\n class: \"\",\r\n attr: \"\",\r\n hidden: false,\r\n editable: false,\r\n noSort: false,\r\n responsive: 1,\r\n responsiveHidden: false,\r\n format: \"\",\r\n transform: \"\",\r\n filterType: \"text\",\r\n firstFilterOption: { value: \"\", text: \"\" },\r\n };\r\n }\r\n\r\n /**\r\n * @returns {Options}\r\n */\r\n get defaultOptions() {\r\n return {\r\n id: null,\r\n url: null,\r\n perPage: 10,\r\n debug: false,\r\n filter: false,\r\n menu: false,\r\n sort: false,\r\n server: false,\r\n serverParams: {\r\n start: \"start\",\r\n length: \"length\",\r\n search: \"search\",\r\n sort: \"sort\",\r\n sortDir: \"sortDir\",\r\n dataKey: \"data\",\r\n metaKey: \"meta\",\r\n metaTotalKey: \"total\",\r\n metaFilteredKey: \"filtered\",\r\n optionsKey: \"options\",\r\n paramsKey: \"params\",\r\n },\r\n defaultSort: \"\",\r\n reorder: false,\r\n dir: \"ltr\",\r\n perPageValues: [10, 25, 50, 100, 250],\r\n hidePerPage: false,\r\n columns: [],\r\n actions: [],\r\n collapseActions: false,\r\n selectable: false,\r\n selectVisibleOnly: true,\r\n defaultPage: 1,\r\n resizable: false,\r\n autosize: true,\r\n expand: false,\r\n autoheight: true,\r\n autohidePager: false,\r\n responsive: false,\r\n responsiveToggle: true,\r\n filterOnEnter: true,\r\n filterKeypressDelay: 500,\r\n spinnerClass: \"\",\r\n saveState: false,\r\n errorMessage: \"\",\r\n };\r\n }\r\n\r\n /**\r\n * Determines if the grid is initialized.\r\n * @returns {Boolean}\r\n */\r\n get isInit() {\r\n return this.classList.contains(\"dg-initialized\");\r\n }\r\n\r\n /**\r\n * Determines if data load has failed.\r\n * @returns {Boolean}\r\n */\r\n get hasDataError() {\r\n return this.classList.contains(\"dg-network-error\");\r\n }\r\n\r\n /**\r\n * @param {Plugins} list\r\n */\r\n static registerPlugins(list) {\r\n plugins = list;\r\n }\r\n\r\n /**\r\n * @param {String} plugin\r\n */\r\n static unregisterPlugins(plugin = null) {\r\n if (plugin === null) {\r\n plugins = {};\r\n } else {\r\n delete plugins[plugin];\r\n }\r\n }\r\n\r\n /**\r\n * @returns {Plugins}\r\n */\r\n static registeredPlugins() {\r\n return plugins;\r\n }\r\n\r\n /**\r\n * @param {Object|Array} columns\r\n * @returns {Column[]}\r\n */\r\n convertColumns(columns) {\r\n const cols = [];\r\n // Convert key:value objects to actual columns\r\n if (typeof columns === \"object\" && !Array.isArray(columns)) {\r\n for (const key of Object.keys(columns)) {\r\n const col = Object.assign({}, this.defaultColumn);\r\n col.title = columns[key];\r\n col.field = key;\r\n cols.push(col);\r\n }\r\n } else {\r\n for (const item of columns) {\r\n let col = Object.assign({}, this.defaultColumn);\r\n if (typeof item === \"string\") {\r\n col.title = item;\r\n col.field = item;\r\n } else if (typeof item === \"object\") {\r\n col = Object.assign(col, item);\r\n if (!col.field) {\r\n console.error(\"Invalid column definition\", item);\r\n }\r\n if (!col.title) {\r\n col.title = col.field;\r\n }\r\n } else {\r\n console.error(\"Column definition must be a string or an object\");\r\n }\r\n cols.push(col);\r\n }\r\n }\r\n return cols;\r\n }\r\n\r\n /**\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#reflected-dom-attributes\r\n * @returns {Array}\r\n */\r\n static get observedAttributes() {\r\n return [\r\n \"page\",\r\n \"data-filter\",\r\n \"data-sort\",\r\n \"data-debug\",\r\n \"data-reorder\",\r\n \"data-menu\",\r\n \"data-selectable\",\r\n \"data-url\",\r\n \"data-per-page\",\r\n \"data-responsive\",\r\n ];\r\n }\r\n\r\n get transformAttributes() {\r\n return {\r\n columns: (v) => this.convertColumns(convertArray(v)),\r\n actions: (v) => convertArray(v),\r\n defaultPage: (v) => Number.parseInt(v),\r\n perPage: (v) => Number.parseInt(v),\r\n };\r\n }\r\n\r\n /** @returns {HTMLTableSectionElement} */\r\n get thead() {\r\n //@ts-ignore\r\n return $(\"thead\", this);\r\n }\r\n\r\n /** @returns {HTMLTableSectionElement} */\r\n get tbody() {\r\n //@ts-ignore\r\n return $(\"tbody\", this);\r\n }\r\n\r\n /** @returns {HTMLTableSectionElement} */\r\n get tfoot() {\r\n //@ts-ignore\r\n return $(\"tfoot\", this);\r\n }\r\n\r\n get page() {\r\n return Number.parseInt(this.getAttribute(\"page\"));\r\n }\r\n\r\n set page(val) {\r\n setAttribute(this, \"page\", this.constrainPageValue(val));\r\n }\r\n\r\n /**\r\n * Loads data and configures the grid.\r\n * @param {Boolean} initOnly\r\n */\r\n urlChanged(initOnly = false) {\r\n if (initOnly && !this.isInit) return;\r\n this.reconfig();\r\n this.loadData().then(() => {\r\n this.configureUi();\r\n });\r\n }\r\n\r\n /**\r\n * Clears columns, re-renders table, and repopulates columns to ensure consistent column widths rendering.\r\n */\r\n reconfig() {\r\n const cols = this.options.columns;\r\n this.options.columns = [];\r\n this.configureUi();\r\n this.options.columns = cols;\r\n }\r\n\r\n constrainPageValue(v) {\r\n let pv = v;\r\n if (this.pages < pv) {\r\n pv = this.pages;\r\n }\r\n if (pv < 1 || !pv) {\r\n pv = 1;\r\n }\r\n return pv;\r\n }\r\n\r\n fixPage() {\r\n this.pages = this.totalPages();\r\n this.page = this.constrainPageValue(this.page);\r\n\r\n // Show current page in input\r\n setAttribute(this.inputPage, \"max\", this.pages);\r\n this.inputPage.value = `${this.page}`;\r\n this.inputPage.disabled = this.pages < 2;\r\n }\r\n\r\n pageChanged() {\r\n this.reload();\r\n }\r\n\r\n responsiveChanged() {\r\n if (!this.plugins.ResponsiveGrid) {\r\n return;\r\n }\r\n if (this.options.responsive) {\r\n this.plugins.ResponsiveGrid.observe();\r\n } else {\r\n this.plugins.ResponsiveGrid.unobserve();\r\n }\r\n }\r\n\r\n menuChanged() {\r\n this.renderHeader();\r\n }\r\n\r\n /**\r\n * This is the callback for the select control\r\n */\r\n changePerPage() {\r\n this.options.perPage = Number.parseInt(this.selectPerPage.options[this.selectPerPage.selectedIndex].value);\r\n this.perPageChanged();\r\n }\r\n\r\n /**\r\n * This is the actual event triggered on attribute change\r\n */\r\n perPageChanged() {\r\n // Refresh UI\r\n if (\r\n this.options.perPage !== Number.parseInt(this.selectPerPage.options[this.selectPerPage.selectedIndex].value)\r\n ) {\r\n this.perPageValuesChanged();\r\n }\r\n // Make sure current page is still valid\r\n let updatePage = this.page;\r\n while (updatePage > 1 && this.page * this.options.perPage > this.totalRecords()) {\r\n updatePage--;\r\n }\r\n if (updatePage !== this.page) {\r\n // Triggers pageChanged, which will trigger reload\r\n this.page = updatePage;\r\n } else {\r\n // Simply reload current page\r\n this.reload(() => {\r\n // Preserve distance between top of page and select control if no fixed height\r\n if (!this.plugins.FixedHeight || !this.plugins.FixedHeight.hasFixedHeight) {\r\n this.selectPerPage.scrollIntoView();\r\n }\r\n });\r\n }\r\n }\r\n\r\n dirChanged() {\r\n setAttribute(this, \"dir\", this.options.dir);\r\n }\r\n\r\n defaultSortChanged() {\r\n this.sortChanged();\r\n }\r\n\r\n /**\r\n * Populate the select dropdown according to options\r\n */\r\n perPageValuesChanged() {\r\n if (!this.selectPerPage) {\r\n return;\r\n }\r\n while (this.selectPerPage.lastChild) {\r\n this.selectPerPage.removeChild(this.selectPerPage.lastChild);\r\n }\r\n for (const v of this.options.perPageValues) {\r\n addSelectOption(this.selectPerPage, v, v, v === this.options.perPage);\r\n }\r\n }\r\n\r\n _connected() {\r\n /**\r\n * @type {HTMLTableElement}\r\n */\r\n this.table = this.querySelector(\"table\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnFirst = this.querySelector(\".dg-btn-first\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnPrev = this.querySelector(\".dg-btn-prev\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnNext = this.querySelector(\".dg-btn-next\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnLast = this.querySelector(\".dg-btn-last\");\r\n /**\r\n * @type {HTMLSelectElement}\r\n */\r\n this.selectPerPage = this.querySelector(\".dg-select-per-page\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.inputPage = this.querySelector(\".dg-input-page\");\r\n\r\n this.getFirst = this.getFirst.bind(this);\r\n this.getPrev = this.getPrev.bind(this);\r\n this.getNext = this.getNext.bind(this);\r\n this.getLast = this.getLast.bind(this);\r\n this.changePerPage = this.changePerPage.bind(this);\r\n this.gotoPage = this.gotoPage.bind(this);\r\n\r\n this.btnFirst.addEventListener(\"click\", this.getFirst);\r\n this.btnPrev.addEventListener(\"click\", this.getPrev);\r\n this.btnNext.addEventListener(\"click\", this.getNext);\r\n this.btnLast.addEventListener(\"click\", this.getLast);\r\n this.selectPerPage.addEventListener(\"change\", this.changePerPage);\r\n this.selectPerPage.toggleAttribute(\"hidden\", this.options.hidePerPage);\r\n this.inputPage.addEventListener(\"input\", this.gotoPage);\r\n\r\n for (const plugin of Object.values(this.plugins)) {\r\n plugin.connected();\r\n }\r\n\r\n // Display even if we don't have data\r\n this.dirChanged();\r\n this.perPageValuesChanged();\r\n\r\n setTimeout(() => { //ensures all registered plugins are connected before loading data\r\n // @ts-ignore\r\n this.loadData().finally(() => {\r\n this.configureUi();\r\n\r\n this.sortChanged();\r\n this.classList.add(\"dg-initialized\"); //acts as a flag to prevent unnecessary server calls down the chain.\r\n\r\n this.filterChanged();\r\n this.reorderChanged();\r\n\r\n this.dirChanged();\r\n this.perPageValuesChanged();\r\n this.pageChanged();\r\n\r\n this.fireEvents = true; // We can now fire attributeChangedCallback events\r\n\r\n this.log(\"initialized\");\r\n });\r\n }, 0);\r\n }\r\n\r\n _disconnected() {\r\n this.btnFirst?.removeEventListener(\"click\", this.getFirst);\r\n this.btnPrev?.removeEventListener(\"click\", this.getPrev);\r\n this.btnNext?.removeEventListener(\"click\", this.getNext);\r\n this.btnLast?.removeEventListener(\"click\", this.getLast);\r\n this.selectPerPage?.removeEventListener(\"change\", this.changePerPage);\r\n this.inputPage?.removeEventListener(\"input\", this.gotoPage);\r\n\r\n for (const plugin of Object.values(this.plugins)) {\r\n plugin.disconnected();\r\n }\r\n }\r\n\r\n /**\r\n * @param {string} field\r\n * @returns {Column}\r\n */\r\n getCol(field) {\r\n let found = null;\r\n\r\n for (const col of this.options.columns) {\r\n if (col.field === field) {\r\n found = col;\r\n }\r\n }\r\n return found;\r\n }\r\n\r\n getColProp(field, prop) {\r\n const c = this.getCol(field);\r\n return c ? c[prop] : null;\r\n }\r\n\r\n setColProp(field, prop, val) {\r\n const c = this.getCol(field);\r\n if (c) {\r\n c[prop] = val;\r\n }\r\n }\r\n\r\n visibleColumns() {\r\n return this.options.columns.filter((col) => {\r\n return !col.hidden;\r\n });\r\n }\r\n\r\n hiddenColumns() {\r\n return this.options.columns.filter((col) => {\r\n return col.hidden === true;\r\n });\r\n }\r\n\r\n showColumn(field, render = true) {\r\n this.setColProp(field, \"hidden\", false);\r\n\r\n // We need to render the whole table otherwise layout fixed won't do its job\r\n if (render) this.renderTable();\r\n\r\n dispatch(this, \"columnVisibility\", {\r\n col: field,\r\n visibility: \"visible\",\r\n });\r\n }\r\n\r\n hideColumn(field, render = true) {\r\n this.setColProp(field, \"hidden\", true);\r\n\r\n // We need to render the whole table otherwise layout fixed won't do its job\r\n if (render) this.renderTable();\r\n\r\n dispatch(this, \"columnVisibility\", {\r\n col: field,\r\n visibility: \"hidden\",\r\n });\r\n }\r\n\r\n /**\r\n * Returns the starting index of actual data\r\n * @returns {Number}\r\n */\r\n startColIndex() {\r\n let start = 1;\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n start++;\r\n }\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n start++;\r\n }\r\n return start;\r\n }\r\n\r\n /**\r\n * @returns {Boolean}\r\n */\r\n isSticky() {\r\n return this.hasAttribute(\"sticky\");\r\n }\r\n\r\n /**\r\n * @param {Boolean} visibleOnly\r\n * @returns {Number}\r\n */\r\n columnsLength(visibleOnly = false) {\r\n let len = 0;\r\n // One column per (visible) column\r\n for (const col of this.options.columns) {\r\n if (visibleOnly && col.hidden) {\r\n continue;\r\n }\r\n if (!col.attr) {\r\n len++;\r\n }\r\n }\r\n // Add one col for selectable checkbox at the beginning\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n len++;\r\n }\r\n // Add one col for actions at the end\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n len++;\r\n }\r\n // Add one col for the responsive toggle\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n len++;\r\n }\r\n return len;\r\n }\r\n\r\n /**\r\n * Global configuration and renderTable\r\n * This should be called after your data has been loaded\r\n */\r\n configureUi() {\r\n this.table.style.visibility = \"hidden\";\r\n this.renderTable();\r\n if (this.options.responsive && this.plugins.ResponsiveGrid) {\r\n // Let the observer make the table visible\r\n } else {\r\n this.table.style.visibility = \"visible\";\r\n }\r\n\r\n // Store row height for later usage\r\n if (!this.rowHeight) {\r\n const tr = find(this, \"tbody tr\") || find(this, \"table tr\");\r\n if (tr) {\r\n this.rowHeight = tr.offsetHeight;\r\n }\r\n }\r\n this.fixPage();\r\n }\r\n\r\n filterChanged() {\r\n const row = this.querySelector(\"thead tr.dg-head-filters\");\r\n if (this.options.filter) {\r\n removeAttribute(row, \"hidden\");\r\n } else {\r\n this.clearFilters();\r\n setAttribute(row, \"hidden\", \"\");\r\n }\r\n }\r\n\r\n reorderChanged() {\r\n const headers = findAll(this, \"thead tr.dg-head-columns th\");\r\n for (const th of headers) {\r\n if (th.classList.contains(\"dg-selectable\") || th.classList.contains(\"dg-actions\")) {\r\n continue;\r\n }\r\n if (this.options.reorder && this.plugins.DraggableHeaders) {\r\n th.draggable = true;\r\n } else {\r\n th.removeAttribute(\"draggable\");\r\n }\r\n }\r\n }\r\n\r\n sortChanged() {\r\n this.log(\"toggle sort\");\r\n\r\n const headers = findAll(this, \"thead tr.dg-head-columns th\");\r\n for (const th of headers) {\r\n const fieldName = th.getAttribute(\"field\");\r\n if (\r\n th.classList.contains(\"dg-not-sortable\") ||\r\n (!this.fireEvents && fieldName === this.options.defaultSort)\r\n ) {\r\n return;\r\n }\r\n if (this.options.sort && !this.getColProp(fieldName, \"noSort\")) {\r\n setAttribute(th, \"aria-sort\", \"none\");\r\n } else {\r\n removeAttribute(th, \"aria-sort\");\r\n }\r\n }\r\n }\r\n\r\n selectableChanged() {\r\n this.renderTable();\r\n }\r\n\r\n addRow(row) {\r\n if (!Array.isArray(this.originalData)) {\r\n return;\r\n }\r\n this.log(\"add row\");\r\n this.originalData.push(row);\r\n this.data = this.originalData.slice();\r\n this.sortData();\r\n }\r\n\r\n /**\r\n * @param {any} value Value to remove. Defaults to last row.\r\n * @param {String} key The key of the item to remove. Defaults to first column\r\n */\r\n removeRow(value = null, key = null) {\r\n if (!Array.isArray(this.originalData)) {\r\n return;\r\n }\r\n\r\n let v = value;\r\n let k = key;\r\n if (k === null) {\r\n k = this.options.columns[0].field;\r\n }\r\n if (v === null) {\r\n v = this.originalData[this.originalData.length - 1][k];\r\n }\r\n this.log(`remove row ${k}:${v}`);\r\n for (let i = 0; i < this.originalData.length; i++) {\r\n if (this.originalData[i][k] === v) {\r\n this.originalData.splice(i, 1);\r\n break;\r\n }\r\n }\r\n this.data = this.originalData.slice();\r\n this.sortData();\r\n }\r\n\r\n /**\r\n * @param {String} key Return a specific key (eg: id) instead of the whole row\r\n * @returns {Array}\r\n */\r\n getSelection(key = null) {\r\n if (!this.plugins.SelectableRows) {\r\n return [];\r\n }\r\n return this.plugins.SelectableRows.getSelection(key);\r\n }\r\n\r\n getData() {\r\n return this.originalData;\r\n }\r\n\r\n clearData() {\r\n // Already empty\r\n if (this.data.length === 0) {\r\n return;\r\n }\r\n this.data = this.originalData = [];\r\n this.renderBody();\r\n }\r\n\r\n /**\r\n * Preloads the data intended to bypass the initial fetch operation, allowing for faster intial page load time.\r\n * Subsequent grid actions after initialization will operate as normal.\r\n * @param {Object} data - an object with meta ({total, filtered, start}) and data (array of objects) properties.\r\n */\r\n preload(data) {\r\n const metaKey = this.options.serverParams.metaKey;\r\n const dataKey = this.options.serverParams.dataKey;\r\n if (data?.[metaKey]) {\r\n this.meta = data[metaKey];\r\n }\r\n if (data?.[dataKey]) {\r\n this.data = this.originalData = data[dataKey];\r\n }\r\n }\r\n\r\n refresh(cb = null) {\r\n this.data = this.originalData = [];\r\n return this.reload(cb);\r\n }\r\n\r\n reload(cb = null) {\r\n this.log(\"reload\");\r\n\r\n // If the data was cleared, we need to render again\r\n const needRender = !this.originalData?.length;\r\n this.fixPage();\r\n // @ts-ignore\r\n this.loadData().finally(() => {\r\n if (this.hasDataError) return;\r\n // If we load data from the server, we redraw the table body\r\n // Otherwise, we just need to paginate\r\n this.options.server || needRender ? this.renderBody() : this.paginate();\r\n if (cb) {\r\n cb();\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * @returns {Promise}\r\n */\r\n loadData() {\r\n const flagEmpty = () => !this.data.length && this.classList.add(\"dg-empty\");\r\n const tbody = this.tbody;\r\n\r\n // We already have some data\r\n if (this.meta || this.originalData || this.isInit) {\r\n // We don't use server side data\r\n if (!this.options.server || (this.options.server && !this.fireEvents)) {\r\n this.log(\"skip loadData\");\r\n flagEmpty();\r\n return new Promise((resolve) => {\r\n resolve();\r\n });\r\n }\r\n }\r\n this.log(\"loadData\");\r\n this.loading = true;\r\n this.classList.add(\"dg-loading\");\r\n this.classList.remove(\"dg-empty\", \"dg-network-error\");\r\n return (\r\n this.fetchData()\r\n .then((response) => {\r\n // We can get a straight array or an object\r\n if (Array.isArray(response)) {\r\n this.data = response;\r\n } else {\r\n // Object must contain data key\r\n if (!response[this.options.serverParams.dataKey]) {\r\n console.error(\r\n \"Invalid response, it should contain a data key with an array or be a plain array\",\r\n response,\r\n );\r\n this.options.url = null;\r\n return;\r\n }\r\n\r\n // We may have a config object\r\n this.options = Object.assign(\r\n this.options,\r\n response[this.options.serverParams.optionsKey] ?? {},\r\n );\r\n // It should return meta data (see metaFilteredKey)\r\n this.meta = response[this.options.serverParams.metaKey] ?? {};\r\n this.data = response[this.options.serverParams.dataKey];\r\n }\r\n this.originalData = this.data.slice();\r\n this.fixPage();\r\n\r\n // Make sure we have a proper set of columns\r\n if (this.options.columns.length === 0 && this.originalData.length) {\r\n this.options.columns = this.convertColumns(Object.keys(this.originalData[0]));\r\n } else {\r\n this.options.columns = this.convertColumns(this.options.columns);\r\n }\r\n })\r\n .catch((err) => {\r\n this.log(err);\r\n tbody.setAttribute(\r\n \"data-empty\",\r\n this.options.errorMessage ||\r\n err.message?.replace(/^\\s+|\\r\\n|\\n|\\r$/g, \"\") ||\r\n labels.networkError,\r\n );\r\n this.classList.add(\"dg-empty\", \"dg-network-error\");\r\n dispatch(this, \"loadDataFailed\", err);\r\n })\r\n // @ts-ignore\r\n .finally(() => {\r\n flagEmpty();\r\n if (!this.hasDataError && tbody.getAttribute(\"data-empty\") !== this.labels.noData) {\r\n tbody.setAttribute(\"data-empty\", this.labels.noData);\r\n }\r\n this.classList.remove(\"dg-loading\");\r\n setAttribute(this.table, \"aria-rowcount\", this.data.length);\r\n this.loading = false;\r\n })\r\n );\r\n }\r\n\r\n getFirst() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = 1;\r\n }\r\n\r\n getLast() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = this.pages;\r\n }\r\n\r\n getPrev() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = this.page - 1;\r\n }\r\n\r\n getNext() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = this.page + 1;\r\n }\r\n\r\n gotoPage(event) {\r\n if (event.type === \"keypress\") {\r\n const key = event.keyCode || event.key;\r\n if (key === 13 || key === \"Enter\") {\r\n event.preventDefault();\r\n } else {\r\n return;\r\n }\r\n }\r\n this.page = Number.parseInt(this.inputPage.value);\r\n }\r\n\r\n getSort() {\r\n const col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n if (col) {\r\n return col.getAttribute(\"field\");\r\n }\r\n return this.options.defaultSort;\r\n }\r\n\r\n getSortDir() {\r\n const col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n if (col) {\r\n return col.getAttribute(\"aria-sort\") || \"\";\r\n }\r\n return \"\";\r\n }\r\n\r\n getFilters() {\r\n const filters = [];\r\n const inputs = findAll(this, this._filterSelector);\r\n for (const input of inputs) {\r\n filters[input.dataset.name] = input.value;\r\n }\r\n return filters;\r\n }\r\n\r\n clearFilters() {\r\n const inputs = findAll(this, this._filterSelector);\r\n for (const input of inputs) {\r\n input.value = \"\";\r\n }\r\n this.filterData();\r\n }\r\n\r\n filterData() {\r\n this.log(\"filter data\");\r\n\r\n this.page = 1;\r\n\r\n if (this.options.server) {\r\n this.reload();\r\n } else {\r\n this.data = this.originalData?.slice() ?? [];\r\n\r\n // Look for rows matching the filters\r\n const inputs = findAll(this, this._filterSelector);\r\n for (const input of inputs) {\r\n const value = input.value;\r\n if (value) {\r\n const name = input.dataset.name;\r\n this.data = this.data.filter((item) => {\r\n const str = `${item[name]}`;\r\n return str.toLowerCase().indexOf(value.toLowerCase()) !== -1;\r\n });\r\n }\r\n }\r\n this.pageChanged();\r\n\r\n const col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n if (this.options.sort && col) {\r\n this.sortData();\r\n } else {\r\n this.renderBody();\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Data will be sorted then rendered using renderBody\r\n * @param {Element} baseCol The column that was clicked or null to use current sort\r\n */\r\n sortData(baseCol = null) {\r\n this.log(\"sort data\");\r\n\r\n let col = baseCol;\r\n\r\n // Early exit\r\n if (col && this.getColProp(col.getAttribute(\"field\"), \"noSort\")) {\r\n this.log(\"sorting prevented because column is not sortable\");\r\n return;\r\n }\r\n if (this.plugins.ColumnResizer?.isResizing) {\r\n this.log(\"sorting prevented because resizing\");\r\n return;\r\n }\r\n if (this.loading) {\r\n this.log(\"sorting prevented because loading\");\r\n return;\r\n }\r\n\r\n // We clicked on a column, update sort state\r\n if (col !== null) {\r\n // Remove active sort if any\r\n const haveClasses = (c) => [\"dg-selectable\", \"dg-actions\", \"dg-responsive-toggle\"].includes(c);\r\n\r\n const headers = findAll(this, \"thead tr:first-child th\");\r\n for (const th of headers) {\r\n // @ts-ignore\r\n if ([...th.classList].some(haveClasses)) {\r\n continue;\r\n }\r\n if (th !== col) {\r\n th.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n }\r\n\r\n // Set tristate col\r\n if (!col.hasAttribute(\"aria-sort\") || col.getAttribute(\"aria-sort\") === \"none\") {\r\n col.setAttribute(\"aria-sort\", \"ascending\");\r\n } else if (col.getAttribute(\"aria-sort\") === \"ascending\") {\r\n col.setAttribute(\"aria-sort\", \"descending\");\r\n } else if (col.getAttribute(\"aria-sort\") === \"descending\") {\r\n col.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n } else {\r\n // Or fetch current sort\r\n col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n }\r\n\r\n if (this.options.server) {\r\n // Reload data with updated sort\r\n this.loadData().finally(() => {\r\n this.renderBody();\r\n });\r\n } else {\r\n const sort = col ? col.getAttribute(\"aria-sort\") : \"none\";\r\n if (sort === \"none\") {\r\n const stack = [];\r\n\r\n // Restore order while keeping filters\r\n this.originalData?.some((itemA) => {\r\n this.data.some((itemB) => {\r\n if (JSON.stringify(itemA) === JSON.stringify(itemB)) {\r\n stack.push(itemB);\r\n return true;\r\n }\r\n return false;\r\n });\r\n return stack.length === this.data.length;\r\n });\r\n\r\n this.data = stack;\r\n } else {\r\n const field = col.getAttribute(\"field\");\r\n this.data.sort((a, b) => {\r\n if (!isNaN(a[field]) && !isNaN(b[field])) {\r\n return sort === \"ascending\" ? a[field] - b[field] : b[field] - a[field];\r\n }\r\n const valA = sort === \"ascending\" ? a[field].toUpperCase() : b[field].toUpperCase();\r\n const valB = sort === \"ascending\" ? b[field].toUpperCase() : a[field].toUpperCase();\r\n\r\n switch (true) {\r\n case valA > valB:\r\n return 1;\r\n case valA < valB:\r\n return -1;\r\n case valA === valB:\r\n return 0;\r\n }\r\n });\r\n }\r\n this.renderBody();\r\n }\r\n }\r\n\r\n _sort(columnName, sortDir) {\r\n const col = this.querySelector(`.dg-head-columns th[field=${columnName}]`);\r\n const dir = sortDir === \"ascending\" ? \"none\" : sortDir === \"descending\" ? \"ascending\" : \"descending\";\r\n col?.setAttribute(\"aria-sort\", dir);\r\n this.sortData(col);\r\n }\r\n\r\n sortAsc = (columnName) => this._sort(columnName, \"ascending\");\r\n sortDesc = (columnName) => this._sort(columnName, \"descending\");\r\n sortNone = (columnName) => this._sort(columnName, \"none\");\r\n\r\n fetchData() {\r\n if (!this.options.url) {\r\n return new Promise((resolve, reject) => reject(\"No url set\"));\r\n }\r\n\r\n let base = window.location.href;\r\n // Fix trailing slash if no extension is present\r\n if (!base.split(\"/\").pop().includes(\".\")) {\r\n base += base.endsWith(\"/\") ? \"\" : \"/\";\r\n }\r\n const url = new URL(this.options.url, base);\r\n let params = {\r\n r: Date.now(),\r\n };\r\n if (this.options.server) {\r\n // 0 based\r\n params[this.options.serverParams.start] = this.page - 1;\r\n params[this.options.serverParams.length] = this.options.perPage;\r\n if (this.options.filter) params[this.options.serverParams.search] = this.getFilters();\r\n params[this.options.serverParams.sort] = this.getSort() || \"\";\r\n params[this.options.serverParams.sortDir] = this.getSortDir();\r\n\r\n // extra params ?\r\n if (this.meta?.[this.options.serverParams.paramsKey]) {\r\n params = Object.assign(params, this.meta[this.options.serverParams.paramsKey]);\r\n }\r\n }\r\n\r\n appendParamsToUrl(url, params);\r\n\r\n return fetch(url).then((response) => {\r\n const newError = new Error(response.statusText || labels.networkError);\r\n if (!response.ok) {\r\n // @ts-ignore\r\n newError.response = response;\r\n throw newError;\r\n }\r\n return response\r\n .clone()\r\n .json()\r\n .catch((err) => {\r\n let error = err;\r\n if (!this.options.debug) {\r\n error = newError;\r\n }\r\n error.response = response;\r\n throw error;\r\n });\r\n });\r\n }\r\n\r\n renderTable() {\r\n this.log(\"render table\");\r\n\r\n if (this.options.menu && this.plugins.ContextMenu) {\r\n this.plugins.ContextMenu.createMenu();\r\n }\r\n\r\n let sortedColumn;\r\n\r\n this.renderHeader();\r\n if (this.options.defaultSort) {\r\n // We can have a default sort even with sort disabled\r\n sortedColumn = this.querySelector(`thead tr.dg-head-columns th[field=\"${this.options.defaultSort}\"]`);\r\n }\r\n\r\n if (sortedColumn) {\r\n this.sortData(sortedColumn);\r\n } else {\r\n this.renderBody();\r\n }\r\n\r\n this.renderFooter();\r\n }\r\n\r\n /**\r\n * Create table header\r\n * - One row for the column headers\r\n * - One row for the filters\r\n */\r\n renderHeader() {\r\n this.log(\"render header\");\r\n\r\n const thead = this.thead;\r\n this.createColumnHeaders(thead);\r\n this.createColumnFilters(thead);\r\n\r\n if (this.options.resizable && this.plugins.ColumnResizer) {\r\n this.plugins.ColumnResizer.renderResizer(labels.resizeColumn);\r\n }\r\n\r\n dispatch(this, \"headerRendered\");\r\n }\r\n\r\n renderFooter() {\r\n this.log(\"render footer\");\r\n\r\n const tfoot = this.tfoot;\r\n const td = tfoot.querySelector(\"td\");\r\n tfoot.removeAttribute(\"hidden\");\r\n setAttribute(td, \"colspan\", this.columnsLength(true));\r\n tfoot.style.display = \"\";\r\n }\r\n\r\n /**\r\n * Create the column headers based on column definitions and set options\r\n * @param {HTMLTableSectionElement} thead\r\n */\r\n createColumnHeaders(thead) {\r\n // @link https://stackoverflow.com/questions/21064101/understanding-offsetwidth-clientwidth-scrollwidth-and-height-respectively\r\n const availableWidth = this.clientWidth;\r\n const colMaxWidth = Math.round((availableWidth / this.columnsLength(true)) * 2);\r\n\r\n let idx = 0;\r\n let tr;\r\n\r\n // Create row\r\n tr = ce(\"tr\");\r\n this.headerRow = tr;\r\n tr.setAttribute(\"role\", \"row\");\r\n tr.setAttribute(\"aria-rowindex\", \"1\");\r\n tr.setAttribute(\"class\", \"dg-head-columns\");\r\n\r\n // We need a real th from the dom to compute the size\r\n let sampleTh = thead.querySelector(\"tr.dg-head-columns th\");\r\n this.log(\"createColumnHeaders - sampleTh\", sampleTh);\r\n if (!sampleTh) {\r\n sampleTh = ce(\"th\");\r\n thead.querySelector(\"tr\").appendChild(sampleTh);\r\n }\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.createHeaderCol(tr);\r\n }\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n this.plugins.ResponsiveGrid.createHeaderCol(tr);\r\n }\r\n\r\n // Create columns\r\n idx = 0;\r\n let totalWidth = 0;\r\n this.log(\"createColumnHeaders - columns\", this.options.columns);\r\n\r\n for (const column of this.options.columns) {\r\n if (column.attr) {\r\n continue;\r\n }\r\n const colIdx = idx + this.startColIndex();\r\n const th = ce(\"th\");\r\n th.setAttribute(\"scope\", \"col\");\r\n th.setAttribute(\"role\", \"columnheader button\");\r\n th.setAttribute(\"aria-colindex\", `${colIdx}`);\r\n th.setAttribute(\"id\", randstr(\"dg-col-\"));\r\n if (this.options.sort) {\r\n th.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n th.setAttribute(\"field\", column.field);\r\n if (this.plugins.ResponsiveGrid && this.options.responsive) {\r\n setAttribute(th, \"data-responsive\", column.responsive || \"\");\r\n }\r\n // Make sure the header fits (+ add some room for sort icon if necessary)\r\n const computedWidth = getTextWidth(column.title, sampleTh, true) + 20;\r\n th.dataset.minWidth = `${computedWidth}`;\r\n applyColumnDefinition(th, column);\r\n th.tabIndex = 0;\r\n th.textContent = column.title;\r\n\r\n let w = 0;\r\n // Autosize small based on first/last row ?\r\n // Take into account minWidth of the header and max available size based on col numbers\r\n if (this.options.autosize && this.plugins.AutosizeColumn) {\r\n const colAvailableWidth = Math.min(availableWidth - totalWidth, colMaxWidth);\r\n w = this.plugins.AutosizeColumn.computeSize(\r\n th,\r\n column,\r\n Number.parseInt(th.dataset.minWidth),\r\n colAvailableWidth,\r\n );\r\n } else {\r\n w = Math.max(Number.parseInt(th.dataset.minWidth), Number.parseInt(th.getAttribute(\"width\")));\r\n }\r\n\r\n setAttribute(th, \"width\", w);\r\n if (column.hidden) {\r\n th.setAttribute(\"hidden\", \"\");\r\n } else {\r\n totalWidth += w;\r\n }\r\n\r\n // Reorder columns with drag/drop\r\n if (this.options.reorder && this.plugins.DraggableHeaders) {\r\n this.plugins.DraggableHeaders.makeHeaderDraggable(th);\r\n }\r\n\r\n tr.appendChild(th);\r\n idx++;\r\n }\r\n\r\n // There is too much available width, and we want to avoid fixed layout to split remaining amount\r\n if (totalWidth < availableWidth) {\r\n const visibleCols = findAll(tr, \"th:not([hidden],.dg-not-resizable)\");\r\n if (visibleCols.length) {\r\n const lastCol = visibleCols[visibleCols.length - 1];\r\n removeAttribute(lastCol, \"width\");\r\n }\r\n }\r\n\r\n // Actions\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n this.plugins.RowActions.makeActionHeader(tr);\r\n }\r\n\r\n thead.replaceChild(tr, thead.querySelector(\"tr.dg-head-columns\"));\r\n\r\n // Once columns are inserted, we have an actual dom to query\r\n if (thead.offsetWidth > availableWidth) {\r\n this.log(`adjust width to fix size, ${thead.offsetWidth} > ${availableWidth}`);\r\n const scrollbarWidth = this.offsetWidth - this.clientWidth;\r\n let diff = thead.offsetWidth - availableWidth - scrollbarWidth;\r\n if (this.options.responsive && this.plugins.ResponsiveGrid) {\r\n diff += scrollbarWidth;\r\n }\r\n // Remove diff for columns that can afford it\r\n const thWithWidth = findAll(tr, \"th[width]\");\r\n\r\n for (const th of thWithWidth) {\r\n if (hasClass(th, \"dg-not-resizable\")) {\r\n continue;\r\n }\r\n if (diff <= 0) {\r\n continue;\r\n }\r\n const actualWidth = Number.parseInt(th.getAttribute(\"width\"));\r\n const minWidth = th.dataset.minWidth ? Number.parseInt(th.dataset.minWidth) : 0;\r\n if (actualWidth > minWidth) {\r\n let newWidth = actualWidth - diff;\r\n if (newWidth < minWidth) {\r\n newWidth = minWidth;\r\n }\r\n diff -= actualWidth - newWidth;\r\n setAttribute(th, \"width\", newWidth);\r\n }\r\n }\r\n }\r\n\r\n // Context menu\r\n if (this.options.menu && this.plugins.ContextMenu) {\r\n this.plugins.ContextMenu.attachContextMenu();\r\n }\r\n\r\n // Sort col on click\r\n const rowsWithSort = findAll(tr, \"[aria-sort]\");\r\n for (const sortableRow of rowsWithSort) {\r\n sortableRow.addEventListener(\"click\", () => this.sortData(sortableRow));\r\n }\r\n\r\n setAttribute(this.table, \"aria-colcount\", this.columnsLength(true));\r\n }\r\n\r\n createColumnFilters(thead) {\r\n let idx = 0;\r\n let tr;\r\n\r\n // Create row for filters\r\n tr = ce(\"tr\");\r\n this.filterRow = tr;\r\n tr.setAttribute(\"role\", \"row\");\r\n tr.setAttribute(\"aria-rowindex\", \"2\");\r\n tr.setAttribute(\"class\", \"dg-head-filters\");\r\n if (!this.options.filter) {\r\n tr.setAttribute(\"hidden\", \"\");\r\n }\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.createFilterCol(tr);\r\n }\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n this.plugins.ResponsiveGrid.createFilterCol(tr);\r\n }\r\n\r\n this.log(\"createColumnFilters - columns\", this.options.columns);\r\n for (const column of this.options.columns) {\r\n if (column.attr) {\r\n continue;\r\n }\r\n const colIdx = idx + this.startColIndex();\r\n const relatedTh = thead.querySelector(`tr.dg-head-columns th[aria-colindex=\"${colIdx}\"]`);\r\n if (!relatedTh) {\r\n console.warn(\"Related th not found\", colIdx);\r\n continue;\r\n }\r\n const th = ce(\"th\");\r\n th.setAttribute(\"aria-colindex\", `${colIdx}`);\r\n\r\n const filter = this.createFilterElement(column, relatedTh);\r\n if (!this.options.filter) {\r\n th.tabIndex = 0;\r\n } else {\r\n filter.tabIndex = 0;\r\n }\r\n\r\n if (column.hidden) {\r\n th.setAttribute(\"hidden\", \"\");\r\n }\r\n\r\n th.appendChild(filter);\r\n tr.appendChild(th);\r\n idx++;\r\n }\r\n\r\n // Actions\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n this.plugins.RowActions.makeActionFilter(tr);\r\n }\r\n\r\n thead.replaceChild(tr, thead.querySelector(\"tr.dg-head-filters\"));\r\n\r\n if (typeof this.options.filterKeypressDelay !== \"number\" || this.options.filterOnEnter)\r\n this.options.filterKeypressDelay = 0;\r\n\r\n // Filter content by field events\r\n const filteredRows = findAll(tr, this._filterSelector);\r\n for (const el of filteredRows) {\r\n const eventName = /select/i.test(el.tagName) ? \"change\" : \"keyup\";\r\n const eventHandler = debounce((e) => {\r\n const key = e.keyCode || e.key;\r\n const isKeyPressFilter = !this.options.filterOnEnter && !this._excludedKeys.some((k) => k === key);\r\n if (key === 13 || key === \"Enter\" || isKeyPressFilter || e.type === \"change\") {\r\n this.filterData.call(this);\r\n }\r\n }, this.options.filterKeypressDelay);\r\n el.addEventListener(eventName, eventHandler);\r\n }\r\n }\r\n\r\n createFilterElement(column, relatedTh) {\r\n const isSelect = column.filterType === \"select\";\r\n const filter = isSelect ? ce(\"select\") : ce(\"input\");\r\n if (isSelect) {\r\n if (!Array.isArray(column.filterList)) {\r\n // Gets unique values from column records\r\n const uniqueValues = [...new Set((this.data ?? []).map((e) => e[column.field]))]\r\n .filter((v) => v)\r\n .sort();\r\n column.filterList = [column.firstFilterOption || this.defaultColumn.firstFilterOption].concat(\r\n uniqueValues.map((e) => ({ value: e, text: e })),\r\n );\r\n }\r\n\r\n for (const e of column.filterList) {\r\n const opt = ce(\"option\");\r\n opt.value = e.value;\r\n opt.text = e.text;\r\n\r\n if (filter instanceof HTMLSelectElement) {\r\n filter.add(opt);\r\n }\r\n }\r\n } else {\r\n //@ts-ignore\r\n filter.type = \"text\";\r\n filter.inputMode = \"search\";\r\n filter.autocomplete = \"off\";\r\n filter.spellcheck = false;\r\n }\r\n // Allows binding filter to this column\r\n filter.dataset.name = column.field;\r\n filter.id = randstr(\"dg-filter-\");\r\n // Don't use aria-label as it triggers autocomplete\r\n filter.setAttribute(\"aria-labelledby\", relatedTh.getAttribute(\"id\"));\r\n return filter;\r\n }\r\n\r\n /**\r\n * Render the data as rows in tbody\r\n * It will call paginate() at the end\r\n */\r\n renderBody() {\r\n this.log(\"render body\");\r\n let tr;\r\n let td;\r\n let idx;\r\n const tbody = ce(\"tbody\");\r\n\r\n this.data.forEach((item, i) => {\r\n tr = ce(\"tr\");\r\n setAttribute(tr, \"role\", \"row\");\r\n setAttribute(tr, \"hidden\", \"\");\r\n setAttribute(tr, \"aria-rowindex\", i + 1);\r\n tr.tabIndex = 0;\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.createDataCol(tr);\r\n }\r\n if (\r\n this.options.responsive &&\r\n this.plugins.ResponsiveGrid &&\r\n this.plugins.ResponsiveGrid.hasHiddenColumns()\r\n ) {\r\n this.plugins.ResponsiveGrid.createDataCol(tr);\r\n }\r\n\r\n // Expandable\r\n if (this.options.expand) {\r\n tr.classList.add(\"dg-expandable\");\r\n\r\n on(tr, \"click\", (ev) => {\r\n if (this.plugins.ResponsiveGrid) {\r\n this.plugins.ResponsiveGrid.blockObserver();\r\n }\r\n toggleClass(ev.currentTarget, \"dg-expanded\");\r\n if (this.plugins.ResponsiveGrid) {\r\n this.plugins.ResponsiveGrid.unblockObserver();\r\n }\r\n });\r\n }\r\n\r\n idx = 0;\r\n\r\n for (const column of this.options.columns) {\r\n if (!column) {\r\n console.error(\"Empty column found!\", this.options.columns);\r\n }\r\n // It should be applied as an attr of the row\r\n if (column.attr) {\r\n if (item[column.field]) {\r\n // Special case if we try to write over the class attr\r\n if (column.attr === \"class\") {\r\n addClass(tr, item[column.field]);\r\n } else {\r\n tr.setAttribute(column.attr, item[column.field]);\r\n }\r\n }\r\n return;\r\n }\r\n td = ce(\"td\");\r\n td.setAttribute(\"role\", \"gridcell\");\r\n td.setAttribute(\"aria-colindex\", `${idx}${this.startColIndex()}`);\r\n applyColumnDefinition(td, column);\r\n // This is required for pure css responsive layout\r\n td.setAttribute(\"data-name\", column.title);\r\n td.tabIndex = -1;\r\n\r\n // Inline editing ...\r\n if (column.editable && this.plugins.EditableColumn) {\r\n addClass(td, \"dg-editable-col\");\r\n this.plugins.EditableColumn.makeEditableInput(td, column, item, i);\r\n } else {\r\n // ... or formatting\r\n const v = item[column.field] ?? \"\";\r\n let tv;\r\n // TODO: make this modular\r\n switch (column.transform) {\r\n case \"uppercase\":\r\n tv = v.toUpperCase();\r\n break;\r\n case \"lowercase\":\r\n tv = v.toLowerCase();\r\n break;\r\n default:\r\n tv = v;\r\n break;\r\n }\r\n if (column.format) {\r\n // Only use formatting with values or if defaultFormatValue is set\r\n if (column.defaultFormatValue !== undefined && (tv === \"\" || tv === null)) {\r\n tv = `${column.defaultFormatValue}`;\r\n }\r\n if (typeof column.format === \"string\" && tv) {\r\n td.innerHTML = interpolate(\r\n // @ts-ignore\r\n column.format,\r\n Object.assign(\r\n {\r\n _v: v,\r\n _tv: tv,\r\n },\r\n item,\r\n ),\r\n );\r\n } else if (column.format instanceof Function) {\r\n const val = column.format.call(this, { column, rowData: item, cellData: tv, td, tr });\r\n td.innerHTML = val || tv || v;\r\n }\r\n } else {\r\n td.textContent = tv;\r\n }\r\n }\r\n tr.appendChild(td);\r\n idx++;\r\n }\r\n\r\n // Actions\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n this.plugins.RowActions.makeActionRow(tr, item);\r\n }\r\n\r\n tbody.appendChild(tr);\r\n\r\n dispatch(this, \"rowRendered\", { rowData: item, tr });\r\n });\r\n\r\n tbody.setAttribute(\"role\", \"rowgroup\");\r\n\r\n // Keep data empty message\r\n const prev = this.tbody;\r\n tbody.setAttribute(\"data-empty\", prev.getAttribute(\"data-empty\"));\r\n this.table.replaceChild(tbody, prev);\r\n\r\n if (this.plugins.FixedHeight) {\r\n this.plugins.FixedHeight.createFakeRow();\r\n }\r\n\r\n this.paginate();\r\n\r\n if (this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.shouldSelectAll(tbody);\r\n }\r\n\r\n this.data.length && this.classList.remove(\"dg-empty\");\r\n\r\n dispatch(this, \"bodyRendered\");\r\n }\r\n\r\n paginate() {\r\n this.log(\"paginate\");\r\n\r\n const total = this.totalRecords();\r\n const p = this.page || 1;\r\n const tbody = this.tbody;\r\n const tfoot = this.tfoot;\r\n const bodyRows = findAll(tbody, \"tr\");\r\n\r\n // Refresh page count in case we added/removed a page\r\n this.pages = this.totalPages();\r\n\r\n let index;\r\n let high = p * this.options.perPage;\r\n let low = high - this.options.perPage + 1;\r\n\r\n if (high > total) {\r\n high = total;\r\n }\r\n if (!total) {\r\n low = 0;\r\n }\r\n\r\n // Display all rows within the set indexes\r\n // For server side paginated grids, we display everything\r\n // since the server is taking care of actual pagination\r\n for (const tr of bodyRows) {\r\n if (this.options.server) {\r\n removeAttribute(tr, \"hidden\");\r\n continue;\r\n }\r\n index = Number(getAttribute(tr, \"aria-rowindex\"));\r\n if (index > high || index < low) {\r\n setAttribute(tr, \"hidden\", \"\");\r\n } else {\r\n removeAttribute(tr, \"hidden\");\r\n }\r\n }\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.clearCheckboxes(tbody);\r\n }\r\n\r\n // Store default height and update styles if needed\r\n if (this.plugins.FixedHeight) {\r\n this.plugins.FixedHeight.updateFakeRow();\r\n }\r\n\r\n // Enable/disable buttons if shown\r\n if (this.btnFirst) {\r\n this.btnFirst.disabled = this.page <= 1;\r\n this.btnPrev.disabled = this.page <= 1;\r\n this.btnNext.disabled = this.page >= this.pages;\r\n this.btnLast.disabled = this.page >= this.pages;\r\n }\r\n tfoot.querySelector(\".dg-low\").textContent = low.toString();\r\n tfoot.querySelector(\".dg-high\").textContent = high.toString();\r\n tfoot.querySelector(\".dg-total\").textContent = `${this.totalRecords()}`;\r\n tfoot.toggleAttribute(\"hidden\", this.options.autohidePager && this.options.perPage > this.totalRecords());\r\n }\r\n\r\n /**\r\n * @returns {number}\r\n */\r\n totalPages() {\r\n return Math.ceil(this.totalRecords() / this.options.perPage);\r\n }\r\n\r\n /**\r\n * @returns {number}\r\n */\r\n totalRecords() {\r\n if (this.options.server) {\r\n return this.meta?.[this.options.serverParams.metaFilteredKey] || 0;\r\n }\r\n return this.data.length;\r\n }\r\n}\r\n\r\nexport default DataGrid;\r\n", "/** @typedef {import(\"../data-grid\").default} DataGrid */\n\nclass BasePlugin {\n /**\n * @param {DataGrid} grid\n */\n constructor(grid) {\n this.grid = grid;\n }\n\n connected() {}\n\n disconnected() {}\n\n /**\n * Handle events within the plugin\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#handling-events\n * @param {Event} event\n */\n handleEvent(event) {\n if (this[`on${event.type}`]) {\n this[`on${event.type}`](event);\n }\n }\n}\n\nexport default BasePlugin;\n", "import BasePlugin from \"../core/base-plugin.js\";\nimport elementOffset from \"../utils/elementOffset.js\";\nimport {\n addClass,\n dispatch,\n findAll,\n getAttribute,\n hasClass,\n off,\n on,\n removeAttribute,\n removeClass,\n setAttribute,\n} from \"../utils/shortcuts.js\";\n\n/**\n * Allows to resize columns\n */\nclass ColumnResizer extends BasePlugin {\n constructor(grid) {\n super(grid);\n this.isResizing = false;\n }\n\n /**\n * @param {String} resizeLabel\n */\n renderResizer(resizeLabel) {\n const grid = this.grid;\n const table = grid.table;\n const cols = findAll(grid, \"thead tr.dg-head-columns th\");\n\n for (const col of cols) {\n if (hasClass(col, \"dg-not-resizable\")) {\n continue;\n }\n // Create a resizer element\n const resizer = document.createElement(\"div\");\n addClass(resizer, \"dg-resizer\");\n resizer.ariaLabel = resizeLabel;\n\n // Add a resizer element to the column\n col.appendChild(resizer);\n\n // Handle resizing\n let startX = 0;\n let startW = 0;\n let remainingSpace = 0;\n let max = 0;\n\n const mouseMoveHandler = (e) => {\n if (e.clientX > max) {\n return;\n }\n const newWidth = startW + (e.clientX - startX);\n if (col.dataset.minWidth && newWidth > Number.parseInt(col.dataset.minWidth)) {\n setAttribute(col, \"width\", newWidth);\n }\n };\n\n // When user releases the mouse, remove the existing event listeners\n const mouseUpHandler = () => {\n grid.log(\"resized column\");\n\n // Prevent accidental sorting if mouse is not over resize handler\n setTimeout(() => {\n this.isResizing = false;\n }, 0);\n\n removeClass(resizer, \"dg-resizer-active\");\n if (grid.options.reorder) {\n col.draggable = true;\n }\n col.style.overflow = \"hidden\";\n\n // Remove handlers\n off(document, \"mousemove\", mouseMoveHandler);\n off(document, \"mouseup\", mouseUpHandler);\n\n dispatch(grid, \"columnResized\", {\n col: getAttribute(col, \"field\"),\n width: getAttribute(col, \"width\"),\n });\n };\n\n // Otherwise it could sort the col\n on(resizer, \"click\", (e) => {\n e.stopPropagation();\n });\n\n on(resizer, \"mousedown\", (e) => {\n e.stopPropagation();\n\n this.isResizing = true;\n\n const target = e.target;\n const currentCols = findAll(grid, \"dg-head-columns th\");\n const visibleCols = currentCols.filter((col) => {\n return !col.hasAttribute(\"hidden\");\n });\n const columnIndex = visibleCols.findIndex((column) => column === target.parentNode);\n grid.log(\"resize column\");\n\n addClass(resizer, \"dg-resizer-active\");\n\n // Make sure we don't drag it\n removeAttribute(col, \"draggable\");\n\n // Allow overflow when resizing\n col.style.overflow = \"visible\";\n\n // Show full column height (-1 to avoid scrollbar)\n resizer.style.height = `${table.offsetHeight - 1}px`;\n\n // Register initial data\n startX = e.clientX;\n startW = col.offsetWidth;\n\n remainingSpace = (visibleCols.length - columnIndex) * 30;\n max = elementOffset(target).left + grid.offsetWidth - remainingSpace;\n\n // Remove width from next columns to allow auto layout\n setAttribute(col, \"width\", startW);\n for (let j = 0; j < visibleCols.length; j++) {\n if (j > columnIndex) {\n removeAttribute(cols[j], \"width\");\n }\n }\n\n // Attach handlers\n on(document, \"mousemove\", mouseMoveHandler);\n on(document, \"mouseup\", mouseUpHandler);\n });\n }\n }\n}\n\nexport default ColumnResizer;\n", "/**\n * @param {HTMLElement} el\n * @param {String} type\n * @param {String} prop\n * @returns {HTMLElement}\n */\nexport default function getParentElement(el, type, prop = \"nodeName\") {\n let parent = el;\n while (parent[prop] !== type) {\n parent = parent.parentElement;\n }\n return parent;\n}\n", "import BasePlugin from \"../core/base-plugin.js\";\nimport getParentElement from \"../utils/getParentElement.js\";\nimport { find, off, on, removeAttribute, setAttribute } from \"../utils/shortcuts.js\";\n\n/**\n * Create a right click menu on the headers\n */\nclass ContextMenu extends BasePlugin {\n connected() {\n /**\n * @type {HTMLUListElement}\n */\n this.menu = this.grid.querySelector(\".dg-menu\");\n }\n disconnected() {\n if (this.grid.headerRow) {\n off(this.grid.headerRow, \"contextmenu\", this);\n }\n }\n\n attachContextMenu() {\n const grid = this.grid;\n on(grid.headerRow, \"contextmenu\", this);\n }\n\n onchange(e) {\n const grid = this.grid;\n const t = e.target;\n const field = t.dataset.name;\n if (t.checked) {\n grid.showColumn(field);\n } else {\n // Prevent hidding last\n if (grid.visibleColumns().length <= 1) {\n // Restore checkbox value\n t.checked = true;\n return;\n }\n grid.hideColumn(field);\n }\n grid.fixPage(); //fixes Chrome footer flexbox resize issues that may appear when there is a large number of columns (i.e. more than 10).\n }\n\n oncontextmenu(e) {\n e.preventDefault();\n const grid = this.grid;\n const target = getParentElement(e.target, \"THEAD\");\n const menu = this.menu;\n const rect = target.getBoundingClientRect();\n let x = e.clientX - rect.left;\n const y = e.clientY - rect.top;\n\n menu.style.top = `${y}px`;\n menu.style.left = `${x}px`;\n\n removeAttribute(menu, \"hidden\");\n if (x + 150 > rect.width) {\n x -= menu.offsetWidth;\n menu.style.left = `${x}px`;\n }\n\n const documentClickHandler = (e) => {\n if (!menu.contains(e.target)) {\n setAttribute(menu, \"hidden\", \"\");\n off(document, \"click\", documentClickHandler);\n }\n };\n on(document, \"click\", documentClickHandler);\n }\n createMenu() {\n const grid = this.grid;\n const menu = this.menu;\n while (menu.lastChild) {\n menu.removeChild(menu.lastChild);\n }\n menu.addEventListener(\"change\", this);\n\n for (const col of grid.options.columns) {\n if (col.attr) {\n continue;\n }\n const li = document.createElement(\"li\");\n const label = document.createElement(\"label\");\n const checkbox = document.createElement(\"input\");\n setAttribute(checkbox, \"type\", \"checkbox\");\n setAttribute(checkbox, \"data-name\", col.field);\n if (!col.hidden) {\n checkbox.checked = true;\n }\n const text = document.createTextNode(col.title);\n\n label.appendChild(checkbox);\n label.appendChild(text);\n\n li.appendChild(label);\n menu.appendChild(li);\n }\n }\n}\n\nexport default ContextMenu;\n", "import BasePlugin from \"../core/base-plugin.js\";\nimport getParentElement from \"../utils/getParentElement.js\";\nimport { dispatch, findAll, getAttribute, on, setAttribute } from \"../utils/shortcuts.js\";\n\n/**\n * Allows to move headers\n */\nclass DraggableHeaders extends BasePlugin {\n /**\n * @param {HTMLTableCellElement} th\n */\n makeHeaderDraggable(th) {\n const grid = this.grid;\n th.draggable = true;\n on(th, \"dragstart\", (e) => {\n if (grid.plugins.ColumnResizer?.isResizing && e.preventDefault) {\n e.preventDefault();\n return;\n }\n grid.log(\"reorder col\");\n e.dataTransfer.effectAllowed = \"move\";\n e.dataTransfer.setData(\"text/plain\", e.target.getAttribute(\"aria-colindex\"));\n });\n on(th, \"dragover\", (e) => {\n if (e.preventDefault) {\n e.preventDefault();\n }\n e.dataTransfer.dropEffect = \"move\";\n return false;\n });\n on(th, \"drop\", (e) => {\n if (e.stopPropagation) {\n e.stopPropagation();\n }\n const t = e.target;\n const target = getParentElement(t, \"TH\");\n const index = Number.parseInt(e.dataTransfer.getData(\"text/plain\"));\n const targetIndex = Number.parseInt(target.getAttribute(\"aria-colindex\"));\n\n if (index === targetIndex) {\n grid.log(\"reordered col stayed the same\");\n return;\n }\n grid.log(`reordered col from ${index} to ${targetIndex}`);\n\n const offset = grid.startColIndex();\n const tmp = grid.options.columns[index - offset];\n grid.options.columns[index - offset] = grid.options.columns[targetIndex - offset];\n grid.options.columns[targetIndex - offset] = tmp;\n\n const swapNodes = (selector, el1) => {\n const rowIndex = el1.parentNode.getAttribute(\"aria-rowindex\");\n const el2 = grid.querySelector(\n `${selector} tr[aria-rowindex=\"${rowIndex}\"] [aria-colindex=\"${targetIndex}\"]`,\n );\n setAttribute(el1, \"aria-colindex\", targetIndex);\n setAttribute(el2, \"aria-colindex\", index);\n const newNode = document.createElement(\"th\");\n el1.parentNode.insertBefore(newNode, el1);\n el2.parentNode.replaceChild(el1, el2);\n newNode.parentNode.replaceChild(el2, newNode);\n };\n\n // Swap all rows in header and body\n for (const el1 of findAll(grid, `thead th[aria-colindex=\"${index}\"]`)) {\n swapNodes(\"thead\", el1);\n }\n for (const el1 of findAll(grid, `tbody td[aria-colindex=\"${index}\"]`)) {\n swapNodes(\"tbody\", el1);\n }\n\n // Updates the columns\n grid.options.columns = findAll(grid, \"thead tr.dg-head-columns th[field]\").map((th) =>\n grid.options.columns.find((c) => c.field === getAttribute(th, \"field\")),\n );\n\n dispatch(grid, \"columnReordered\", {\n col: tmp.field,\n from: index,\n to: targetIndex,\n });\n return false;\n });\n }\n}\n\nexport default DraggableHeaders;\n", "import BasePlugin from \"../core/base-plugin.js\";\n\n/**\n * Allows to paginate with horizontal swipe motions\n */\nclass TouchSupport extends BasePlugin {\n constructor(grid) {\n super(grid);\n this.touch = null;\n }\n connected() {\n const grid = this.grid;\n grid.addEventListener(\"touchstart\", this, { passive: true });\n grid.addEventListener(\"touchmove\", this, { passive: true });\n }\n\n disconnected() {\n const grid = this.grid;\n grid.removeEventListener(\"touchstart\", this);\n grid.removeEventListener(\"touchmove\", this);\n }\n\n ontouchstart(e) {\n this.touch = e.touches[0];\n }\n\n ontouchmove(e) {\n if (!this.touch) {\n return;\n }\n const grid = this.grid;\n const xDiff = this.touch.clientX - e.touches[0].clientX;\n const yDiff = this.touch.clientY - e.touches[0].clientY;\n\n if (Math.abs(xDiff) > Math.abs(yDiff)) {\n if (xDiff > 0) {\n grid.getNext();\n } else {\n grid.getPrev();\n }\n }\n this.touch = null;\n }\n}\n\nexport default TouchSupport;\n", "import BasePlugin from \"../core/base-plugin.js\";\nimport { dispatch, findAll, hasClass, setAttribute } from \"../utils/shortcuts.js\";\n\nconst SELECTABLE_CLASS = \"dg-selectable\";\nconst SELECT_ALL_CLASS = \"dg-select-all\";\nconst CHECKBOX_CLASS = \"form-check-input\"; //bs5\n\n/**\n * Allows to select rows\n */\nclass SelectableRows extends BasePlugin {\n disconnected() {\n if (this.selectAll) {\n this.selectAll.removeEventListener(\"change\", this);\n }\n }\n\n /**\n * @param {String} key Return a specific key (eg: id) instead of the whole row\n * @returns {Array}\n */\n getSelection(key = null) {\n const grid = this.grid;\n const selectedData = [];\n\n const inputs = findAll(grid, `tbody .${SELECTABLE_CLASS} input:checked`);\n\n for (const checkbox of inputs) {\n const idx = Number.parseInt(checkbox.dataset.id);\n const item = grid.data[idx - 1];\n if (!item) {\n console.warn(`Item ${idx} not found`);\n }\n if (key) {\n selectedData.push(item[key]);\n } else {\n selectedData.push(item);\n }\n }\n return selectedData;\n }\n\n /**\n * Uncheck box if hidden and visible only\n * @param {HTMLTableSectionElement} tbody\n */\n clearCheckboxes(tbody) {\n const grid = this.grid;\n if (!grid.options.selectVisibleOnly) {\n return;\n }\n const inputs = findAll(tbody, `tr[hidden] .${SELECTABLE_CLASS} input`);\n for (const input of inputs) {\n input.checked = false;\n }\n this.selectAll.checked = false;\n }\n\n colIndex() {\n return this.grid.startColIndex() - 2;\n }\n\n /**\n * @param {HTMLTableRowElement} tr\n */\n createHeaderCol(tr) {\n const th = document.createElement(\"th\");\n setAttribute(th, \"scope\", \"col\");\n setAttribute(th, \"role\", \"columnheader button\");\n setAttribute(th, \"aria-colindex\", this.colIndex());\n th.classList.add(...[SELECTABLE_CLASS, \"dg-not-resizable\", \"dg-not-sortable\"]);\n th.tabIndex = 0;\n\n this.selectAll = document.createElement(\"input\");\n this.selectAll.type = \"checkbox\";\n this.selectAll.classList.add(SELECT_ALL_CLASS);\n this.selectAll.classList.add(CHECKBOX_CLASS);\n this.selectAll.addEventListener(\"change\", this);\n\n const label = document.createElement(\"label\");\n label.appendChild(this.selectAll);\n\n th.appendChild(label);\n\n th.setAttribute(\"width\", \"40\");\n tr.appendChild(th);\n }\n\n /**\n * @param {HTMLTableRowElement} tr\n */\n createFilterCol(tr) {\n const th = document.createElement(\"th\");\n setAttribute(th, \"role\", \"columnheader button\");\n setAttribute(th, \"aria-colindex\", this.colIndex());\n th.classList.add(SELECTABLE_CLASS);\n th.tabIndex = 0;\n\n tr.appendChild(th);\n }\n\n /**\n * Handles the selectAll checkbox when any other .dg-selectable checkbox is checked on table body.\n * It should check selectAll if all is checked\n * It should uncheck selectAll if any is unchecked\n * @param {HTMLTableSectionElement} tbody\n */\n shouldSelectAll(tbody) {\n if (!this.selectAll) {\n return;\n }\n // Delegate listener for change events on input checkboxes\n tbody.addEventListener(\"change\", this);\n // Make sure state is up to date\n tbody.dispatchEvent(new Event(\"change\"));\n }\n\n /**\n * @param {HTMLTableRowElement} tr\n */\n createDataCol(tr) {\n // Create col\n const td = document.createElement(\"td\");\n setAttribute(td, \"role\", \"gridcell button\");\n setAttribute(td, \"aria-colindex\", this.colIndex());\n td.classList.add(SELECTABLE_CLASS);\n\n // Create input\n const selectOne = document.createElement(\"input\");\n // Alias row id for easy retrieval in getSelection\n selectOne.dataset.id = tr.getAttribute(\"aria-rowindex\");\n selectOne.type = \"checkbox\";\n selectOne.classList.add(CHECKBOX_CLASS);\n // Label need to take full space thanks to css to make the whole cell clickable\n const label = document.createElement(\"label\");\n label.classList.add(\"dg-clickable-cell\");\n label.appendChild(selectOne);\n td.appendChild(label);\n\n // Prevent unwanted click behaviour on row\n label.addEventListener(\"click\", this);\n\n tr.appendChild(td);\n }\n\n /**\n * @param {Event} e\n */\n onclick(e) {\n e.stopPropagation();\n }\n\n /**\n * Handle change event on select all or any select checkbox in the table body\n * @param {import(\"../utils/shortcuts.js\").FlexibleEvent} e\n */\n onchange(e) {\n const grid = this.grid;\n if (hasClass(e.target, SELECT_ALL_CLASS)) {\n const visibleOnly = grid.options.selectVisibleOnly;\n const inputs = findAll(grid, `tbody .${SELECTABLE_CLASS} input`);\n for (const cb of inputs) {\n if (visibleOnly && !cb.offsetWidth) {\n return;\n }\n cb.checked = this.selectAll.checked;\n }\n dispatch(grid, \"rowsSelected\", {\n selection: this.getSelection(),\n });\n } else {\n if (!e.target.closest(`.${SELECTABLE_CLASS}`)) {\n return;\n }\n const totalCheckboxes = findAll(grid, `tbody .${SELECTABLE_CLASS} input[type=checkbox]`);\n // @ts-ignore\n const totalChecked = totalCheckboxes.filter((n) => n.checked);\n this.selectAll.checked = totalChecked.length === totalCheckboxes.length;\n\n dispatch(grid, \"rowsSelected\", {\n selection: grid.getSelection(),\n });\n }\n }\n}\n\nexport default SelectableRows;\n", "import BasePlugin from \"../core/base-plugin.js\";\nimport { setAttribute } from \"../utils/shortcuts.js\";\n\n/**\n * Support for fixed table height\n *\n * We should add a fake row to push the footer down in case we don't have enough rows\n */\nclass FixedHeight extends BasePlugin {\n constructor(grid) {\n super(grid);\n\n this.hasFixedHeight = false;\n // If we have a fixed height, make sure we have overflowY set\n if (grid.style.height) {\n grid.style.overflowY = \"auto\";\n this.hasFixedHeight = true;\n }\n }\n\n /**\n */\n createFakeRow() {\n const grid = this.grid;\n const tbody = grid.querySelector(\"tbody\");\n const tr = document.createElement(\"tr\");\n setAttribute(tr, \"role\", \"row\");\n setAttribute(tr, \"hidden\", \"\");\n tr.classList.add(\"dg-fake-row\");\n tr.tabIndex = 0;\n tbody.appendChild(tr);\n }\n\n get fakeRow() {\n return this.grid.querySelector(\".dg-fake-row\");\n }\n\n /**\n * On last page, use a fake row to push footer down\n */\n updateFakeRow() {\n const grid = this.grid;\n const fakeRow = this.fakeRow;\n if (!fakeRow) {\n return;\n }\n\n // We don't need a fake row if we display everything\n if (grid.options.perPage > grid.totalRecords()) {\n return;\n }\n // We are not on last page\n if (grid.page !== grid.totalPages()) {\n return;\n }\n if (!grid.options.autoheight) {\n return;\n }\n // Find remaining missing height\n const max = grid.options.perPage * grid.rowHeight;\n const visibleRows = grid.querySelectorAll(\"tbody tr:not([hidden])\").length;\n const fakeHeight = visibleRows > 1 ? max - visibleRows * grid.rowHeight : max;\n if (fakeHeight > 0) {\n setAttribute(fakeRow, \"height\", fakeHeight);\n fakeRow.removeAttribute(\"hidden\");\n } else {\n fakeRow.removeAttribute(\"height\");\n }\n }\n}\n\nexport default FixedHeight;\n", "import BasePlugin from \"../core/base-plugin.js\";\nimport getTextWidth from \"../utils/getTextWidth.js\";\nimport { getAttribute, hasAttribute, setAttribute } from \"../utils/shortcuts.js\";\n\n/**\n * Allows to resize columns\n */\nclass AutosizeColumn extends BasePlugin {\n /**\n * Autosize col based on column data\n * @param {HTMLTableCellElement} th\n * @param {import(\"../data-grid\").Column} column\n * @param {Number} min\n * @param {Number} max\n * @returns {Number}\n */\n computeSize(th, column, min, max) {\n const grid = this.grid;\n if (hasAttribute(th, \"width\")) {\n return getAttribute(th, \"width\");\n }\n if (!grid.data.length) {\n return;\n }\n const firstVal = grid.data[0];\n const lastVal = grid.data[grid.data.length - 1];\n let v = firstVal[column.field] ? firstVal[column.field].toString() : \"\";\n const v2 = lastVal[column.field] ? lastVal[column.field].toString() : \"\";\n if (v2.length > v.length) {\n v = v2;\n }\n let width = 0;\n if (v.length <= 6) {\n width = min;\n } else if (v.length > 50) {\n width = max;\n } else {\n // Add some extra room to have some spare space\n width = getTextWidth(`${v}0000`, th);\n }\n if (width > max) {\n width = max;\n }\n if (width < min) {\n width = min;\n }\n setAttribute(th, \"width\", width);\n return width;\n }\n}\n\nexport default AutosizeColumn;\n", "import BasePlugin from \"../core/base-plugin.js\";\nimport debounce from \"../utils/debounce.js\";\nimport {\n addClass,\n ce,\n find,\n findAll,\n hasClass,\n insertAfter,\n removeAttribute,\n removeClass,\n setAttribute,\n} from \"../utils/shortcuts.js\";\n\nconst RESPONSIVE_CLASS = \"dg-responsive\";\n\nlet obsTo;\n\n/**\n * @param {Array} list\n * @returns {Array}\n */\nfunction sortByPriority(list) {\n return list.sort((a, b) => {\n const v1 = Number.parseInt(a.dataset.responsive) || 1;\n const v2 = Number.parseInt(b.dataset.responsive) || 1;\n return v2 - v1;\n });\n}\n\n/**\n * @type {ResizeObserverCallback}\n */\n//@ts-ignore\nconst callback = debounce((entries) => {\n for (const entry of entries) {\n /**\n * @type {import(\"../data-grid\").default}\n */\n // @ts-ignore\n const grid = entry.target;\n const table = grid.table;\n if (grid.plugins.ResponsiveGrid.observerBlocked) {\n return;\n }\n // check inlineSize (width) and not blockSize (height)\n const contentBoxSize = Array.isArray(entry.contentBoxSize) ? entry.contentBoxSize[0] : entry.contentBoxSize;\n const size = Number.parseInt(contentBoxSize.inlineSize);\n const tableWidth = table.offsetWidth;\n const realTableWidth = findAll(grid.headerRow, \"th\").reduce((result, th) => {\n return result + th.offsetWidth;\n }, 0);\n const diff = (realTableWidth || tableWidth) - size - 1;\n const minWidth = 50;\n const prevAction = grid.plugins.ResponsiveGrid.prevAction;\n // We have an array with the columns to show/hide are in order, most important first\n const headerCols = sortByPriority(\n findAll(grid.headerRow, \"th[field]\")\n .reverse() // Order takes precedence if no priority is set\n .filter((col) => {\n // Leave out unresponsive columns\n return col.dataset.responsive !== \"0\";\n }),\n );\n let changed = false;\n\n grid.log(`table is ${tableWidth}/${realTableWidth} and available size is ${size}. Diff: ${diff}`);\n\n // The table is too big when diff has a high value, otherwise it will be like -1 or -2\n if (diff > 0) {\n if (prevAction === \"show\") {\n return;\n }\n grid.plugins.ResponsiveGrid.prevAction = \"hide\";\n let remaining = diff;\n let cols = headerCols.filter((col) => {\n return !col.hasAttribute(\"hidden\") && col.hasAttribute(\"data-responsive\");\n });\n if (cols.length === 0) {\n cols = headerCols.filter((col) => {\n return !col.hasAttribute(\"hidden\");\n });\n // Always keep one column\n if (cols.length === 1) {\n return;\n }\n }\n\n for (const col of cols) {\n if (remaining < 0) {\n continue;\n }\n\n const colWidth = col.offsetWidth;\n const field = col.getAttribute(\"field\");\n if (!field) {\n continue;\n }\n col.dataset.baseWidth = `${col.offsetWidth}`;\n\n grid.hideColumn(field, false);\n grid.setColProp(field, \"responsiveHidden\", true);\n changed = true;\n\n remaining -= colWidth;\n remaining = Math.round(remaining);\n }\n } else {\n if (prevAction === \"hide\") {\n return;\n }\n grid.plugins.ResponsiveGrid.prevAction = \"show\";\n\n const requiredWidth =\n headerCols\n .filter((col) => {\n return !col.hasAttribute(\"hidden\");\n })\n .reduce((result, col) => {\n const width = col.dataset.minWidth ? Number.parseInt(col.dataset.minWidth) : col.offsetWidth;\n return result + width;\n }, 0) + minWidth; // Add an offset so that inserting column is smoother\n\n // Compute available width to insert columns\n let remaining = size - requiredWidth;\n // Do we have any hidden column that we can restore ?\n const filteredHeaderCols = headerCols\n .slice()\n .reverse() // Reverse the array to restore the columns in the proper order\n .filter((col) => {\n return col.hasAttribute(\"hidden\");\n });\n\n for (const col of filteredHeaderCols) {\n if (remaining < minWidth) {\n continue;\n }\n const colWidth = Number.parseInt(col.dataset.minWidth);\n\n // We need to have enough space to restore it\n if (colWidth > remaining) {\n remaining = -1; // break loop to keep restoring in order\n continue;\n }\n\n const field = col.getAttribute(\"field\");\n if (!field) {\n continue;\n }\n\n grid.showColumn(field, false);\n grid.setColProp(field, \"responsiveHidden\", false);\n changed = true;\n\n remaining -= colWidth;\n remaining = Math.round(remaining);\n }\n }\n\n // Check footer\n const footer = find(grid.table, \"tfoot\");\n const realFooterWidth = findAll(grid.table, \".dg-footer > div\").reduce((result, div) => {\n return result + div.offsetWidth;\n }, 0);\n const availableFooterWidth = footer.offsetWidth - realFooterWidth;\n if (realFooterWidth > size) {\n addClass(footer, \"dg-footer-compact\");\n } else if (availableFooterWidth > 250) {\n removeClass(footer, \"dg-footer-compact\");\n }\n if (changed) {\n grid.renderTable();\n }\n // Prevent resize loop\n setTimeout(() => {\n grid.plugins.ResponsiveGrid.prevAction = null;\n }, 1000);\n grid.table.style.visibility = \"visible\";\n }\n}, 100);\nconst resizeObserver = new ResizeObserver(callback);\n\n/**\n * Responsive data grid\n */\nclass ResponsiveGrid extends BasePlugin {\n constructor(grid) {\n super(grid);\n\n this.observerBlocked = false;\n this.prevAction = null;\n }\n\n connected() {\n if (this.grid.options.responsive) {\n this.observe();\n }\n }\n\n disconnected() {\n this.unobserve();\n }\n\n observe() {\n if (!this.grid.options.responsive) {\n return;\n }\n resizeObserver.observe(this.grid);\n this.grid.style.display = \"block\"; // Otherwise resize doesn't happen\n this.grid.style.overflowX = \"hidden\"; // Prevent scrollbars from appearing\n }\n\n unobserve() {\n resizeObserver.unobserve(this.grid);\n this.grid.style.display = \"unset\";\n this.grid.style.overflowX = \"unset\";\n }\n\n blockObserver() {\n this.observerBlocked = true;\n if (obsTo) {\n clearTimeout(obsTo);\n }\n }\n\n unblockObserver() {\n obsTo = setTimeout(() => {\n this.observerBlocked = false;\n }, 200); // more than debounce\n }\n\n /**\n * @returns {Boolean}\n */\n hasHiddenColumns() {\n let flag = false;\n\n for (const col of this.grid.options.columns) {\n if (col.responsiveHidden) {\n flag = true;\n }\n }\n return flag;\n }\n\n colIndex() {\n return this.grid.startColIndex() - 1;\n }\n\n /**\n * @param {HTMLTableRowElement} tr\n */\n createHeaderCol(tr) {\n if (!this.grid.options.responsiveToggle) {\n return;\n }\n const th = ce(\"th\", tr);\n setAttribute(th, \"scope\", \"col\");\n setAttribute(th, \"role\", \"columnheader button\");\n setAttribute(th, \"aria-colindex\", this.colIndex());\n setAttribute(th, \"width\", \"40\");\n th.classList.add(...[`${RESPONSIVE_CLASS}-toggle`, \"dg-not-resizable\", \"dg-not-sortable\"]);\n th.tabIndex = 0;\n }\n\n /**\n * @param {HTMLTableRowElement} tr\n */\n createFilterCol(tr) {\n if (!this.grid.options.responsiveToggle) {\n return;\n }\n const th = ce(\"th\", tr);\n setAttribute(th, \"role\", \"columnheader button\");\n setAttribute(th, \"aria-colindex\", this.colIndex());\n th.classList.add(`${RESPONSIVE_CLASS}-toggle`);\n th.tabIndex = 0;\n }\n\n /**\n * @param {HTMLTableRowElement} tr\n */\n createDataCol(tr) {\n if (!this.grid.options.responsiveToggle) {\n return;\n }\n // Create col\n const td = document.createElement(\"td\");\n setAttribute(td, \"role\", \"gridcell button\");\n setAttribute(td, \"aria-colindex\", this.colIndex());\n td.classList.add(`${RESPONSIVE_CLASS}-toggle`);\n\n // Create icon\n td.innerHTML = `\n \n \n\n\n \n
`;\n tr.appendChild(td);\n\n td.addEventListener(\"click\", this);\n td.addEventListener(\"mousedown\", this);\n }\n\n computeLabelWidth() {\n let idealWidth = 0;\n let consideredCol = 0;\n while (idealWidth < 120) {\n consideredCol++;\n const hCol = find(this.grid, `.dg-head-columns th[aria-colindex=\"${consideredCol}\"]`);\n if (hCol) {\n idealWidth += hCol.offsetWidth;\n } else {\n break;\n }\n }\n return idealWidth;\n }\n\n /**\n * @param {Event} ev\n */\n onmousedown(ev) {\n // Avoid selection through double click\n ev.preventDefault();\n }\n\n /**\n * @param {Event} ev\n */\n onclick(ev) {\n // Prevent expandable\n ev.stopPropagation();\n\n // target is the element that triggered the event (e.g., the user clicked on)\n // currentTarget is the element that the event listener is attached to.\n\n /**\n * @type {HTMLTableRowElement}\n */\n //@ts-ignore\n const td = ev.currentTarget;\n const tr = td.parentElement;\n const open = find(td, `.${RESPONSIVE_CLASS}-open`);\n const close = find(td, `.${RESPONSIVE_CLASS}-close`);\n\n this.blockObserver();\n\n const isExpanded = hasClass(tr, `${RESPONSIVE_CLASS}-expanded`);\n if (isExpanded) {\n removeClass(tr, `${RESPONSIVE_CLASS}-expanded`);\n open.style.display = \"unset\";\n close.style.display = \"none\";\n\n // Move back rows and cleanup row\n const childRow = tr.nextElementSibling;\n const hiddenCols = findAll(childRow, `.${RESPONSIVE_CLASS}-hidden`);\n\n for (const col of hiddenCols) {\n // We don't really need to care where we insert them since we are going to redraw anyway\n tr.appendChild(col);\n setAttribute(col, \"hidden\");\n }\n\n childRow.parentElement.removeChild(childRow);\n } else {\n addClass(tr, `${RESPONSIVE_CLASS}-expanded`);\n open.style.display = \"none\";\n close.style.display = \"unset\";\n\n // Create a child row and move rows into it\n const childRow = ce(\"tr\");\n insertAfter(childRow, tr);\n addClass(childRow, `${RESPONSIVE_CLASS}-child-row`);\n\n const childRowTd = ce(\"td\", childRow);\n setAttribute(childRowTd, \"colspan\", this.grid.columnsLength(true));\n\n const childTable = ce(\"table\", childRowTd);\n addClass(childTable, `${RESPONSIVE_CLASS}-table`);\n\n const hiddenCols = findAll(tr, `.${RESPONSIVE_CLASS}-hidden`);\n const idealWidth = this.computeLabelWidth();\n\n for (const col of hiddenCols) {\n const childTableRow = ce(\"tr\", childTable);\n\n // Add label\n const label = col.dataset.name;\n const labelCol = ce(\"th\", childTableRow);\n // It looks much better when aligned with an actual col\n labelCol.style.width = `${idealWidth}px`;\n labelCol.innerHTML = label;\n\n // Add actual row\n childTableRow.appendChild(col);\n removeAttribute(col, \"hidden\");\n }\n }\n\n this.unblockObserver();\n }\n}\n\nexport default ResponsiveGrid;\n", "import BasePlugin from \"../core/base-plugin.js\";\nimport interpolate from \"../utils/interpolate.js\";\nimport { dispatch, on, setAttribute } from \"../utils/shortcuts.js\";\n\n/**\n * Add action on rows\n */\nclass RowActions extends BasePlugin {\n /**\n * @returns {Boolean}\n */\n hasActions() {\n return this.grid.options.actions.length > 0;\n }\n\n /**\n *\n * @param {HTMLTableRowElement} tr\n */\n makeActionHeader(tr) {\n const actionsTh = document.createElement(\"th\");\n setAttribute(actionsTh, \"role\", \"columnheader button\");\n setAttribute(actionsTh, \"aria-colindex\", this.grid.columnsLength(true));\n actionsTh.classList.add(...[\"dg-actions\", \"dg-not-sortable\", \"dg-not-resizable\", this.actionClass]);\n actionsTh.tabIndex = 0;\n tr.appendChild(actionsTh);\n }\n\n /**\n *\n * @param {HTMLTableRowElement} tr\n */\n makeActionFilter(tr) {\n const actionsTh = document.createElement(\"th\");\n actionsTh.setAttribute(\"role\", \"columnheader button\");\n setAttribute(actionsTh, \"aria-colindex\", this.grid.columnsLength(true));\n actionsTh.classList.add(...[\"dg-actions\", this.actionClass]);\n actionsTh.tabIndex = 0;\n tr.appendChild(actionsTh);\n }\n\n /**\n * @param {HTMLTableRowElement} tr\n * @param {Object} item\n */\n makeActionRow(tr, item) {\n const labels = this.grid.labels;\n const td = document.createElement(\"td\");\n setAttribute(td, \"role\", \"gridcell\");\n setAttribute(td, \"aria-colindex\", this.grid.columnsLength(true));\n td.classList.add(...[\"dg-actions\", this.actionClass]);\n td.tabIndex = 0;\n\n // Add menu toggle\n const actionsToggle = document.createElement(\"button\");\n actionsToggle.classList.add(\"dg-actions-toggle\");\n actionsToggle.innerHTML = \"\u2630\";\n td.appendChild(actionsToggle);\n on(actionsToggle, \"click\", (ev) => {\n ev.stopPropagation();\n ev.target.parentElement.classList.toggle(\"dg-actions-expand\");\n });\n\n for (const action of this.grid.options.actions) {\n const button = document.createElement(\"button\");\n if (action.html) {\n button.innerHTML = action.html;\n } else {\n button.innerText = action.title ?? action.name;\n }\n if (action.title) {\n button.title = action.title;\n }\n if (action.url) {\n button.type = \"submit\";\n button.formAction = interpolate(action.url, item);\n }\n if (action.class) {\n button.classList.add(...action.class.split(\" \"));\n }\n const actionHandler = (ev) => {\n ev.stopPropagation();\n if (action.confirm) {\n const c = confirm(labels.areYouSure);\n if (!c) {\n ev.preventDefault();\n return;\n }\n }\n dispatch(this.grid, \"action\", {\n data: item,\n action: action.name,\n });\n };\n button.addEventListener(\"click\", actionHandler);\n td.appendChild(button);\n\n // Row action\n if (action.default) {\n tr.classList.add(\"dg-actionable\");\n tr.addEventListener(\"click\", actionHandler);\n }\n }\n\n tr.appendChild(td);\n }\n\n get actionClass() {\n if (this.grid.options.actions.length < 3 && !this.grid.options.collapseActions) {\n return `dg-actions-${this.grid.options.actions.length}`;\n }\n return \"dg-actions-more\";\n }\n}\n\nexport default RowActions;\n", "import BasePlugin from \"../core/base-plugin.js\";\nimport { dispatch } from \"../utils/shortcuts.js\";\n\n/**\n * Make editable inputs in rows\n */\nclass EditableColumn extends BasePlugin {\n /**\n *\n * @param {HTMLTableCellElement} td\n * @param {import(\"../data-grid\").Column} column\n * @param {Object} item\n * @param {number} i\n */\n makeEditableInput(td, column, item, i) {\n const gridId = this.grid.getAttribute(\"id\");\n const input = document.createElement(\"input\");\n input.type = column.editableType || \"text\";\n if (input.type === \"email\") {\n input.inputMode = \"email\";\n }\n if (input.type === \"decimal\") {\n input.type = \"text\";\n input.inputMode = \"decimal\";\n }\n input.autocomplete = \"off\";\n input.spellcheck = false;\n input.tabIndex = 0;\n input.classList.add(\"dg-editable\");\n input.name = `${gridId.replace(\"-\", \"_\")}[${i + 1}][${column.field}]`;\n input.value = item[column.field];\n input.dataset.field = column.field;\n\n // Prevent row action\n input.addEventListener(\"click\", (ev) => ev.stopPropagation());\n // Enter validates edit\n input.addEventListener(\"keypress\", (ev) => {\n if (ev.type === \"keypress\") {\n const key = ev.keyCode || ev.key;\n if (key === 13 || key === \"Enter\") {\n input.blur();\n ev.preventDefault();\n }\n }\n });\n // Save on blur\n input.addEventListener(\"blur\", () => {\n // Only fire on update\n if (input.value === item[input.dataset.field]) {\n return;\n }\n // Update underlying data\n item[input.dataset.field] = input.value;\n // Notify\n dispatch(this.grid, \"edit\", {\n data: item,\n value: input.value,\n });\n });\n td.appendChild(input);\n }\n}\n\nexport default EditableColumn;\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport { $ } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Adds an element for showing a spinning icon on grid loading.\r\n */\r\nclass SpinnerSupport extends BasePlugin {\r\n connected() {\r\n // Inserts spinner\r\n if (this.grid.options.spinnerClass && this.grid.plugins.SpinnerSupport) {\r\n this.add();\r\n }\r\n }\r\n\r\n /**\r\n * Adds a spinner element with its associated css styles.\r\n */\r\n add() {\r\n const grid = this.grid;\r\n const classes = grid.options.spinnerClass;\r\n if (!classes) {\r\n return;\r\n }\r\n const cls = classes\r\n .split(\" \")\r\n .map((e) => `.${e}`)\r\n .join(\"\");\r\n\r\n const template = `\r\n\r\n`;\r\n if (!$(\"#dg-styles\")) {\r\n const styleParent = $(\"head\") ?? $(\"body\");\r\n const position = /head/i.test(styleParent.tagName) ? \"beforeend\" : \"afterbegin\";\r\n styleParent.insertAdjacentHTML(position, template);\r\n }\r\n !$(`i${cls}`, grid) && grid.insertAdjacentHTML(\"afterbegin\", ``);\r\n }\r\n}\r\n\r\nexport default SpinnerSupport;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport { findAll } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * @typedef GridState\r\n * @property {Object} meta\r\n * @property {Number} pages\r\n * @property {Number} page\r\n * @property {Number} perPage\r\n * @property {Object} filters\r\n * @property {Array} columns\r\n * @property {String} sort\r\n * @property {String} sortDir\r\n * @property {Number} scrollTo\r\n */\r\n\r\nclass SaveState extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n this.cachedState = null;\r\n this.isFilterSortSet = false;\r\n this.isDataLoaded = false;\r\n this.isScrolled = false;\r\n this.log(\"Init\");\r\n }\r\n\r\n connected() {\r\n this.log(\"connected\");\r\n const grid = this.grid;\r\n\r\n this.log(grid.options);\r\n\r\n if (!grid.options.saveState) {\r\n this.log(\"disabled\");\r\n return;\r\n }\r\n\r\n this.log(\"enabled\");\r\n\r\n const cachedState = this._getState();\r\n if (cachedState) {\r\n this.log(\"hide columns\");\r\n\r\n for (const col of cachedState.columns) {\r\n if (col.hidden) {\r\n const hideCol = grid.options.columns.find((c) => c.field === col.field);\r\n hideCol.hidden = true;\r\n }\r\n }\r\n\r\n this.log(\"set: meta, pages\");\r\n grid.options.perPage = cachedState.perPage;\r\n if (grid.options.server) {\r\n grid.meta = cachedState.meta;\r\n grid.pages = cachedState.pages;\r\n grid.page = cachedState.page;\r\n }\r\n }\r\n\r\n this.cachedState = cachedState;\r\n this.log(\"cachedState\", this.cachedState);\r\n\r\n setTimeout(() => {\r\n const dgLoadData = grid.loadData;\r\n grid.loadData = function (...args) {\r\n return dgLoadData.apply(this, args).finally(() => {\r\n const saveState = this.plugins.SaveState;\r\n saveState.log(\"loadData\", this.options.columns);\r\n\r\n if (!grid.classList.contains(\"dg-initialized\")) {\r\n saveState.log(\"not init, loadData skipped\");\r\n return;\r\n }\r\n\r\n saveState.log(\"loadData finished, set param controls\", this.options.columns);\r\n\r\n if (saveState.cachedState && !saveState.isFilterSortSet) {\r\n saveState.log(\"set sort and filters\");\r\n\r\n const sortableHeaders = findAll(grid, \"thead tr.dg-head-columns th[aria-sort]\");\r\n for (const el of sortableHeaders) {\r\n el.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n\r\n grid.querySelector(`thead tr.dg-head-columns th[field='${saveState.cachedState.sort}']`)\r\n ?.setAttribute(\"aria-sort\", saveState.cachedState.sortDir);\r\n\r\n const filters = findAll(grid.filterRow, \"[id^=dg-filter]\");\r\n saveState.log(\"filters\", filters);\r\n\r\n for (const el of filters) {\r\n el.value = saveState?.cachedState?.filters?.[el.dataset.name] ?? \"\";\r\n saveState.log({ name: el.dataset.name, val: el.value, saveState });\r\n }\r\n saveState.isFilterSortSet = true;\r\n }\r\n\r\n /** @type {GridState} */\r\n const newState = {\r\n meta: grid.meta,\r\n pages: grid.pages,\r\n page: grid.page,\r\n perPage: grid.options.perPage,\r\n filters: {},\r\n columns: grid.options.columns.map((col) => ({ field: col.field, hidden: col.hidden })),\r\n sort: grid.getSort(),\r\n sortDir: grid.getSortDir(),\r\n scrollTo: window.scrollY,\r\n };\r\n\r\n const filters = grid.getFilters();\r\n saveState.log(\"filters\", filters);\r\n\r\n for (const key of Object.keys(filters)) {\r\n newState.filters[key] = filters[key] ?? \"\";\r\n saveState.log({ key, val: filters[key], newState, filters });\r\n }\r\n\r\n saveState.log(\"store new state\", newState);\r\n saveState._setState(newState);\r\n\r\n if (!grid.options.server && saveState.cachedState && !saveState.isDataLoaded) {\r\n saveState.isDataLoaded = true;\r\n grid.filterData();\r\n grid.page = saveState.cachedState.page;\r\n grid.pageChanged();\r\n saveState.log(\"data loaded\");\r\n }\r\n });\r\n };\r\n }, 0);\r\n\r\n const updateState = () => {\r\n const saveState = grid.plugins.SaveState;\r\n const state = saveState._getState();\r\n if (!state) {\r\n return;\r\n }\r\n state.columns = grid.options.columns.map((col) => ({ field: col.field, hidden: col.hidden }));\r\n state.sort = grid.getSort();\r\n state.sortDir = grid.getSortDir();\r\n state.scrollTo = window.scrollY;\r\n saveState._setState(state);\r\n };\r\n\r\n document.addEventListener(\"scrollend\", updateState);\r\n grid.addEventListener(\"headerRendered\", updateState);\r\n\r\n grid.addEventListener(\"bodyRendered\", (ev) => {\r\n if (!grid.classList.contains(\"dg-initialized\") || grid.classList.contains(\"dg-loading\")) {\r\n return;\r\n }\r\n\r\n if (!grid.options.server) {\r\n updateState();\r\n }\r\n\r\n const saveState = grid.plugins.SaveState;\r\n if (!saveState.cachedState || !saveState.isFilterSortSet) {\r\n return;\r\n }\r\n\r\n if (!saveState.isDataLoaded) {\r\n saveState.isDataLoaded = true;\r\n grid.reload();\r\n saveState.log(\"***grid reloaded\");\r\n } else if (!saveState.isScrolled) {\r\n saveState.isScrolled = true;\r\n window.scrollTo({ top: saveState.cachedState.scrollTo, left: 0, behavior: \"instant\" });\r\n }\r\n });\r\n }\r\n\r\n log(...data) {\r\n this.grid.log(\"[Save-State] \", ...data);\r\n }\r\n\r\n /**\r\n * @returns {GridState}\r\n */\r\n _getState() {\r\n let state;\r\n try {\r\n state = JSON.parse(sessionStorage.getItem(`gridSaveState_${this.grid.id}`));\r\n } catch (_) {}\r\n return state;\r\n }\r\n\r\n /**\r\n * @param {GridState} state\r\n */\r\n _setState(state) {\r\n sessionStorage.setItem(`gridSaveState_${this.grid.id}`, JSON.stringify(state));\r\n }\r\n}\r\n\r\nexport default SaveState;\r\n", "/**\r\n * Data Grid custom element\r\n * https://github.com/lekoala/data-grid/\r\n * @license MIT\r\n */\r\n\r\nimport DataGrid from \"./src/data-grid.js\";\r\n// Optional plugins\r\nimport ColumnResizer from \"./src/plugins/column-resizer.js\";\r\nimport ContextMenu from \"./src/plugins/context-menu.js\";\r\nimport DraggableHeaders from \"./src/plugins/draggable-headers.js\";\r\nimport TouchSupport from \"./src/plugins/touch-support.js\";\r\nimport SelectableRows from \"./src/plugins/selectable-rows.js\";\r\nimport FixedHeight from \"./src/plugins/fixed-height.js\";\r\nimport AutosizeColumn from \"./src/plugins/autosize-column.js\";\r\nimport ResponsiveGrid from \"./src/plugins/responsive-grid.js\";\r\nimport RowActions from \"./src/plugins/row-actions.js\";\r\nimport EditableColumn from \"./src/plugins/editable-column.js\";\r\nimport SpinnerSupport from \"./src/plugins/spinner-support.js\";\r\nimport SaveState from \"./src/plugins/save-state.js\";\r\n\r\n// Using shorthand property names\r\n// This make them reserved and keys will be preserved\r\n// Actual class names are renamed\r\nDataGrid.registerPlugins({\r\n ColumnResizer,\r\n ContextMenu,\r\n DraggableHeaders,\r\n TouchSupport,\r\n SelectableRows,\r\n FixedHeight,\r\n AutosizeColumn,\r\n ResponsiveGrid,\r\n RowActions,\r\n EditableColumn,\r\n SpinnerSupport,\r\n SaveState\r\n});\r\n\r\n// Prevent errors if included multiple times\r\nif (!customElements.get(\"data-grid\")) {\r\n customElements.define(\"data-grid\", DataGrid);\r\n}\r\n\r\nexport default DataGrid;\r\n\r\nconst global = typeof globalThis !== \"undefined\" ? globalThis : self;\r\nglobal.DataGrid = DataGrid;"],
- "mappings": "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",
- "names": ["camelize", "str", "m", "chr", "normalizeData", "v", "val", "supportedPassiveTypes", "passiveOpts", "type", "getAttribute", "el", "name", "hasAttribute", "setAttribute", "v", "check", "removeAttribute", "on", "listener", "off", "dispatch", "el", "name", "data", "bubbles", "opts", "hasClass", "addClass", "removeClass", "toggleClass", "$", "selector", "base", "$$", "find", "findAll", "ce", "tagName", "parent", "el", "insertAfter", "newNode", "existingNode", "BaseElement", "options", "opt", "v", "setAttribute", "jsonConfig", "data", "key", "normalizeData", "getAttribute", "event", "template", "dispatch", "attributeName", "oldValue", "newValue", "isOption", "transformer", "attr", "camelize", "base_element_default", "addSelectOption", "el", "value", "label", "checked", "opt", "appendParamsToUrl", "url", "params", "key", "k", "convertArray", "v", "bv", "elementOffset", "el", "rect", "scrollLeft", "scrollTop", "interpolate", "str", "data", "$1", "$2", "canvas", "getTextWidth", "text", "el", "withPadding", "styles", "fontWeight", "fontSize", "fontFamily", "padding", "paddingLeft", "paddingRight", "context", "metrics", "randstr", "prefix", "debounce", "handler", "timeout", "timer", "args", "plugins", "labels", "applyColumnDefinition", "el", "column", "setAttribute", "addClass", "DataGrid", "_DataGrid", "base_element_default", "randstr", "pluginName", "pluginClass", "attr", "camelize", "v", "list", "plugin", "columns", "cols", "key", "col", "item", "convertArray", "$", "val", "initOnly", "pv", "updatePage", "addSelectOption", "field", "found", "prop", "c", "render", "dispatch", "start", "visibleOnly", "len", "tr", "find", "row", "removeAttribute", "headers", "findAll", "th", "fieldName", "value", "k", "i", "data", "metaKey", "dataKey", "cb", "needRender", "flagEmpty", "tbody", "resolve", "response", "err", "event", "filters", "inputs", "input", "name", "baseCol", "haveClasses", "sort", "stack", "itemA", "itemB", "a", "b", "valA", "valB", "columnName", "sortDir", "dir", "reject", "base", "url", "params", "appendParamsToUrl", "newError", "error", "sortedColumn", "thead", "tfoot", "td", "availableWidth", "colMaxWidth", "idx", "ce", "sampleTh", "totalWidth", "colIdx", "computedWidth", "getTextWidth", "w", "colAvailableWidth", "visibleCols", "lastCol", "scrollbarWidth", "diff", "thWithWidth", "hasClass", "actualWidth", "minWidth", "newWidth", "rowsWithSort", "sortableRow", "relatedTh", "filter", "filteredRows", "eventName", "eventHandler", "debounce", "e", "isKeyPressFilter", "isSelect", "uniqueValues", "opt", "on", "ev", "toggleClass", "tv", "interpolate", "prev", "total", "p", "bodyRows", "index", "high", "low", "getAttribute", "data_grid_default", "BasePlugin", "grid", "event", "base_plugin_default", "ColumnResizer", "base_plugin_default", "grid", "resizeLabel", "table", "cols", "findAll", "col", "hasClass", "resizer", "addClass", "startX", "startW", "remainingSpace", "max", "mouseMoveHandler", "e", "newWidth", "setAttribute", "mouseUpHandler", "removeClass", "off", "dispatch", "getAttribute", "on", "target", "visibleCols", "columnIndex", "column", "removeAttribute", "elementOffset", "j", "column_resizer_default", "getParentElement", "el", "type", "prop", "parent", "ContextMenu", "base_plugin_default", "off", "grid", "on", "e", "t", "field", "target", "getParentElement", "menu", "rect", "x", "y", "removeAttribute", "documentClickHandler", "setAttribute", "col", "li", "label", "checkbox", "text", "context_menu_default", "DraggableHeaders", "base_plugin_default", "th", "grid", "on", "e", "t", "target", "getParentElement", "index", "targetIndex", "offset", "tmp", "swapNodes", "selector", "el1", "rowIndex", "el2", "setAttribute", "newNode", "findAll", "c", "getAttribute", "dispatch", "draggable_headers_default", "TouchSupport", "base_plugin_default", "grid", "e", "xDiff", "yDiff", "touch_support_default", "SELECTABLE_CLASS", "SELECT_ALL_CLASS", "CHECKBOX_CLASS", "SelectableRows", "base_plugin_default", "key", "grid", "selectedData", "inputs", "findAll", "checkbox", "idx", "item", "tbody", "input", "tr", "th", "setAttribute", "label", "td", "selectOne", "e", "hasClass", "visibleOnly", "cb", "dispatch", "totalCheckboxes", "totalChecked", "n", "selectable_rows_default", "FixedHeight", "base_plugin_default", "grid", "tbody", "tr", "setAttribute", "fakeRow", "max", "visibleRows", "fakeHeight", "fixed_height_default", "AutosizeColumn", "base_plugin_default", "th", "column", "min", "max", "grid", "hasAttribute", "getAttribute", "firstVal", "lastVal", "v", "v2", "width", "getTextWidth", "setAttribute", "autosize_column_default", "RESPONSIVE_CLASS", "obsTo", "sortByPriority", "list", "a", "b", "v1", "callback", "debounce", "entries", "entry", "grid", "table", "contentBoxSize", "size", "tableWidth", "realTableWidth", "findAll", "result", "th", "diff", "minWidth", "prevAction", "headerCols", "col", "changed", "remaining", "cols", "colWidth", "field", "requiredWidth", "width", "filteredHeaderCols", "footer", "find", "realFooterWidth", "div", "availableFooterWidth", "addClass", "removeClass", "resizeObserver", "ResponsiveGrid", "base_plugin_default", "flag", "tr", "ce", "setAttribute", "td", "idealWidth", "consideredCol", "hCol", "ev", "open", "close", "hasClass", "childRow", "hiddenCols", "insertAfter", "childRowTd", "childTable", "childTableRow", "label", "labelCol", "removeAttribute", "responsive_grid_default", "RowActions", "base_plugin_default", "tr", "actionsTh", "setAttribute", "item", "labels", "td", "actionsToggle", "on", "ev", "action", "button", "interpolate", "actionHandler", "dispatch", "row_actions_default", "EditableColumn", "base_plugin_default", "td", "column", "item", "i", "gridId", "input", "ev", "key", "dispatch", "editable_column_default", "SpinnerSupport", "base_plugin_default", "grid", "classes", "cls", "e", "template", "$", "styleParent", "position", "spinner_support_default", "SaveState", "base_plugin_default", "grid", "cachedState", "col", "hideCol", "c", "dgLoadData", "args", "saveState", "sortableHeaders", "findAll", "el", "filters", "newState", "key", "updateState", "state", "ev", "data", "save_state_default", "data_grid_default", "column_resizer_default", "context_menu_default", "draggable_headers_default", "touch_support_default", "selectable_rows_default", "fixed_height_default", "autosize_column_default", "responsive_grid_default", "row_actions_default", "editable_column_default", "spinner_support_default", "save_state_default", "global"]
+ "sourcesContent": ["/**\r\n * @param {String} str\r\n * @returns {String}\r\n */\r\nexport default function camelize(str) {\r\n return str.toLowerCase().replace(/[^a-zA-Z0-9]+(.)/g, (m, chr) => chr.toUpperCase());\r\n}\r\n", "/**\r\n * Parse data attribute and return properly typed data\r\n * @param {String} v\r\n * @returns {any}\r\n */\r\nexport default function normalizeData(v) {\r\n // Bool\r\n if (v === \"true\") {\r\n return true;\r\n }\r\n if (v === \"false\") {\r\n return false;\r\n }\r\n // Null or empty\r\n if (v === \"\" || v === \"null\") {\r\n return null;\r\n }\r\n // Numeric attributes\r\n if (v === Number(v).toString()) {\r\n return Number(v);\r\n }\r\n // Only attempt json parsing for array or objects\r\n if (v && typeof v.substring === \"function\" && [\"[\", \"{\"].includes(v.substring(0, 1))) {\r\n try {\r\n // In case we have only single quoted values, like ['one', 'two', 'three']\r\n let val = v;\r\n if (val.indexOf('\"') === -1) {\r\n val = val.replace(/'/g, '\"');\r\n }\r\n return JSON.parse(decodeURIComponent(val));\r\n } catch {\r\n console.error(`Failed to parse ${v}`);\r\n return {};\r\n }\r\n }\r\n return v;\r\n}\r\n", "/**\r\n * @typedef FlexibleHTMLProps\r\n * @property {boolean} [checked] (HTMLInputElement)\r\n * @property {string} [value] (HTMLInputElement)\r\n * @property {number} [rowHeight] (HTMLTableRowElement)\r\n *\r\n * A flexible type HTMLElement type that does not require using instanceof all over the place\r\n * Make sure that your selector is indeed valid\r\n * Only includes most commons props\r\n * @typedef {HTMLElement & FlexibleHTMLProps} FlexibleHTMLElement\r\n */\r\n\r\n/**\r\n * Keep this as reference for easy documentation\r\n * @typedef {HTMLElement&HTMLInputElement&HTMLTableRowElement} MixedHTMLElement\r\n */\r\n\r\n/**\r\n * @typedef FlexibleEventProps\r\n * @property {FlexibleHTMLElement} target\r\n * @property {FlexibleHTMLElement} currentTarget\r\n * @property {DataTransfer} [dataTransfer] (DragEvent)\r\n * @property {number} [clientX] (MouseEvent)\r\n * @property {number} [clientY] (MouseEvent)\r\n *\r\n * @typedef {Event & FlexibleEventProps} FlexibleEvent\r\n */\r\n\r\n/**\r\n * Keep this as reference for easy documentation\r\n * @typedef {Event&MouseEvent&InputEvent&DragEvent&FocusEvent&KeyboardEvent&PointerEvent} MixedEvent\r\n */\r\n\r\n/**\r\n * @callback FlexibleListener\r\n * @param {FlexibleEvent} event\r\n */\r\n\r\nclass FlexibleEventListenerObject {\r\n /**\r\n * @param {FlexibleEvent} e\r\n */\r\n handleEvent(e) {}\r\n}\r\n\r\nconst supportedPassiveTypes = [\r\n \"scroll\",\r\n \"wheel\",\r\n \"touchstart\",\r\n \"touchmove\",\r\n \"touchenter\",\r\n \"touchend\",\r\n \"touchleave\",\r\n \"mouseout\",\r\n \"mouseleave\",\r\n \"mouseup\",\r\n \"mousedown\",\r\n \"mousemove\",\r\n \"mouseenter\",\r\n \"mousewheel\",\r\n \"mouseover\",\r\n];\r\n\r\n/**\r\n * Automatically set passive options based on type\r\n * @param {string} type\r\n * @returns {AddEventListenerOptions}\r\n */\r\nfunction passiveOpts(type) {\r\n if (supportedPassiveTypes.includes(type)) {\r\n return { passive: true };\r\n }\r\n return {};\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n * @returns {any}\r\n */\r\nexport function getAttribute(el, name) {\r\n return el.getAttribute(name);\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n * @returns {Boolean}\r\n */\r\nexport function hasAttribute(el, name) {\r\n return el.hasAttribute(name);\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n * @param {any} v\r\n * @param {Boolean} check Prevent setting if attribute is already there\r\n */\r\nexport function setAttribute(el, name, v = \"\", check = false) {\r\n if (check && hasAttribute(el, name)) return;\r\n el.setAttribute(name, `${v}`);\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n */\r\nexport function removeAttribute(el, name) {\r\n if (hasAttribute(el, name)) {\r\n el.removeAttribute(name);\r\n }\r\n}\r\n\r\n/**\r\n * @param {EventTarget} el\r\n * @param {String} type\r\n * @param {EventListenerObject|FlexibleListener} listener\r\n */\r\nexport function on(el, type, listener) {\r\n el.addEventListener(type, listener, passiveOpts(type));\r\n}\r\n\r\n/**\r\n * @param {EventTarget} el\r\n * @param {String} type\r\n * @param {EventListenerObject|FlexibleListener} listener\r\n */\r\nexport function off(el, type, listener) {\r\n el.removeEventListener(type, listener, passiveOpts(type));\r\n}\r\n\r\n/**\r\n * @param {EventTarget} el\r\n * @param {String} type\r\n * @param {EventListenerObject|FlexibleListener} listener\r\n */\r\nexport function one(el, type, listener) {\r\n el.addEventListener(type, listener, {\r\n once: true,\r\n });\r\n}\r\n\r\n/**\r\n * @param {HTMLElement} el\r\n * @param {String} name\r\n * @param {any} data\r\n * @param {Boolean} bubbles\r\n */\r\nexport function dispatch(el, name, data = {}, bubbles = false) {\r\n const opts = {};\r\n if (bubbles) {\r\n opts.bubbles = true;\r\n }\r\n if (data) {\r\n opts.detail = data;\r\n }\r\n el.dispatchEvent(new CustomEvent(name, opts));\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n * @returns {Boolean}\r\n */\r\nexport function hasClass(el, name) {\r\n return el.classList.contains(name);\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n */\r\nexport function addClass(el, name) {\r\n el.classList.add(...name.split(\" \"));\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n */\r\nexport function removeClass(el, name) {\r\n el.classList.remove(...name.split(\" \"));\r\n}\r\n\r\n/**\r\n * @param {Element} el\r\n * @param {String} name\r\n */\r\nexport function toggleClass(el, name) {\r\n el.classList.toggle(name);\r\n}\r\n\r\n/**\r\n * @param {String|HTMLElement} selector\r\n * @param {HTMLElement|Document} base\r\n * @returns {FlexibleHTMLElement|null}\r\n */\r\nexport function $(selector, base = document) {\r\n if (selector instanceof HTMLElement) {\r\n return selector;\r\n }\r\n return base.querySelector(selector);\r\n}\r\n\r\n/**\r\n * @param {String} selector\r\n * @param {Element|Document} base\r\n * @returns {Array}\r\n */\r\nexport function $$(selector, base = document) {\r\n return Array.from(base.querySelectorAll(selector));\r\n}\r\n\r\n/**\r\n * Easily retrieve untyped element\r\n * For actual type, prefer use of el.querySelector\r\n * @param {HTMLElement} el\r\n * @param {String|HTMLElement} selector\r\n * @returns {FlexibleHTMLElement}\r\n */\r\nexport function find(el, selector) {\r\n return $(selector, el);\r\n}\r\n\r\n/**\r\n * Easily retrieve untyped elements\r\n * For actual type, prefer use of el.querySelectorAll\r\n * @param {Element} el\r\n * @param {String} selector\r\n * @returns {Array}\r\n */\r\nexport function findAll(el, selector) {\r\n return $$(selector, el);\r\n}\r\n\r\n/**\r\n * @param {*} el\r\n * @returns {FlexibleHTMLElement}\r\n */\r\nexport function el(el) {\r\n return el;\r\n}\r\n\r\n/**\r\n * @template {keyof HTMLElementTagNameMap} K\r\n * @param {K} tagName\r\n * @param {HTMLElement} parent\r\n * @returns {HTMLElementTagNameMap[K]}\r\n */\r\nexport function ce(tagName, parent = null) {\r\n const el = document.createElement(tagName);\r\n if (parent) {\r\n parent.appendChild(el);\r\n }\r\n return el;\r\n}\r\n\r\n/**\r\n * @param {HTMLElement} newNode\r\n * @param {HTMLElement} existingNode\r\n */\r\nexport function insertAfter(newNode, existingNode) {\r\n existingNode.parentNode.insertBefore(newNode, existingNode.nextSibling);\r\n}\r\n", "import camelize from \"../utils/camelize.js\";\r\nimport normalizeData from \"../utils/normalizeData.js\";\r\nimport { dispatch, getAttribute, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/** @typedef {import('../data-grid').Options} Options */\r\n\r\n/**\r\n * Base element that does not contain any specific logic\r\n * related to this project but makes HTMLElemnt usable\r\n */\r\nclass BaseElement extends HTMLElement {\r\n /**\r\n * @param {Object} options\r\n */\r\n constructor(options = {}) {\r\n super();\r\n\r\n /** @type {Options} */\r\n this.options = Object.assign({}, this.defaultOptions, this.normalizedDataset, options);\n\r\n this.log(\"constructor\");\r\n\r\n this.setup = false;\r\n this.fireEvents = true;\r\n this._ready();\r\n\r\n this.log(\"ready\");\r\n }\r\n\r\n get defaultOptions() {\r\n return {};\r\n }\r\n\r\n /**\r\n * @param {String} opt\r\n * @returns {any}\r\n */\r\n getOption(opt) {\r\n return this.options[opt];\r\n }\r\n\r\n /**\r\n * @param {String} opt\r\n * @param {any} v\r\n */\r\n setOption(opt, v) {\r\n setAttribute(this, `data-${opt}`, v);\r\n }\r\n\r\n /**\r\n * @param {String} opt\r\n */\r\n toggleOption(opt) {\r\n setAttribute(this, `data-${opt}`, !this.getOption(opt));\r\n }\r\n\r\n get normalizedDataset() {\r\n const jsonConfig = this.dataset.config ? JSON.parse(this.dataset.config) : {};\r\n const data = { ...this.dataset };\r\n for (const key in data) {\r\n if (key === \"config\" || !data.hasOwnProperty(key) || typeof data[key] === \"function\") {\r\n continue;\r\n }\r\n data[key] = normalizeData(data[key]);\r\n }\r\n // Once normalized, merge into json config\r\n Object.assign(data, jsonConfig);\r\n return data;\r\n }\r\n\r\n /**\r\n * @returns {String}\r\n */\r\n static template() {\r\n return \"\";\r\n }\r\n\r\n /**\r\n * This is called at the end of constructor. Extend in subclass if needed.\r\n */\r\n _ready() {}\r\n\r\n /**\r\n * @param {any[]} data\r\n */\r\n log(...data) {\r\n if (this.options.debug) {\r\n console.log(`[${getAttribute(this, \"id\")}] `, ...data);\r\n }\r\n }\r\n\r\n /**\r\n * Handle events within the component\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#handling-events\r\n * @param {Event} event\r\n */\r\n handleEvent(event) {\r\n if (this[`on${event.type}`]) {\r\n this[`on${event.type}`](event);\r\n }\r\n }\r\n\r\n /**\r\n * This is called when connected. Extend in subclass if needed.\r\n */\r\n _connected() {}\r\n\r\n connectedCallback() {\r\n // already connected\r\n if (this.setup) {\r\n return;\r\n }\r\n this.setup = true;\r\n // ensure whenDefined callbacks run first\r\n setTimeout(async () => {\r\n this.log(\"connectedCallback\");\r\n\r\n // Append only when labels had the opportunity to be set\r\n // Don't use shadow dom as it makes theming super hard\r\n const template = document.createElement(\"template\");\r\n // @ts-ignore\r\n template.innerHTML = this.constructor.template();\r\n this.appendChild(template.content.cloneNode(true));\r\n\n await this._connected();\n\r\n // @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#life-cycle-events\r\n dispatch(this, \"connected\");\r\n }, 0);\r\n }\r\n\r\n /**\r\n * This is called when disconnected. Extend in subclass if needed.\r\n */\r\n _disconnected() {}\r\n\r\n /**\r\n * @link https://nolanlawson.com/2024/12/01/avoiding-unnecessary-cleanup-work-in-disconnectedcallback/\r\n */\r\n disconnectedCallback() {\r\n setTimeout(() => {\r\n if (!this.isConnected && this.setup) {\r\n this.log(\"disconnectedCallback\");\r\n this._disconnected();\r\n // @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#life-cycle-events\r\n dispatch(this, \"disconnected\");\r\n this.setup = false;\r\n }\r\n }, 0);\r\n }\r\n\r\n /**\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#a-props-like-accessor\r\n * @returns {Object}\r\n */\r\n get transformAttributes() {\r\n return {};\r\n }\r\n\r\n /**\r\n * This is only meant to work with data attributes\r\n * This allows us to have properties that reflect automatically in the component\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#reflected-dataset-attributes\r\n * @param {String} attributeName\r\n * @param {String} oldValue\r\n * @param {String} newValue\r\n */\r\n attributeChangedCallback(attributeName, oldValue, newValue) {\r\n // It didn't change\r\n if (oldValue === newValue) {\r\n return;\r\n }\r\n\r\n this.log(`attributeChangedCallback: ${attributeName}`);\r\n\r\n let isOption = false;\r\n const transformer = this.transformAttributes[attributeName] ?? normalizeData;\r\n\r\n let attr = attributeName;\r\n // Data attributes are mapped to options while other attributes are mapped as properties\r\n if (attr.indexOf(\"data-\") === 0) {\r\n attr = attr.slice(5);\r\n isOption = true;\r\n }\r\n attr = camelize(attr);\r\n if (isOption) {\r\n this.options[attr] = transformer(newValue);\r\n } else {\r\n this[attr] = transformer(newValue);\r\n }\r\n\r\n // Fire internal event\r\n if (this.fireEvents && this[`${attr}Changed`]) {\r\n this[`${attr}Changed`]();\r\n }\r\n }\r\n}\r\n\r\nexport default BaseElement;\r\n", "/**\r\n * @param {HTMLSelectElement} el\r\n * @param {String} value\r\n * @param {String} label\r\n * @param {Boolean} checked\r\n */\r\nexport default function addSelectOption(el, value, label, checked = false) {\r\n const opt = document.createElement(\"option\");\r\n opt.value = `${value}`;\r\n if (checked) {\r\n opt.selected = true;\r\n }\r\n opt.label = label;\r\n el.appendChild(opt);\r\n}\r\n", "/**\r\n * @param {URL} url\r\n * @param {Object} params\r\n */\r\nexport default function appendParamsToUrl(url, params = {}) {\r\n for (const key of Object.keys(params)) {\r\n if (Array.isArray(params[key])) {\r\n for (const k of Object.keys(params[key])) {\r\n // @ts-ignore\r\n url.searchParams.append(isNaN(k) ? `${key}[${k}]` : key, params[key][k]);\r\n }\r\n } else {\r\n url.searchParams.append(key, params[key]);\r\n }\r\n }\r\n}\r\n", "/**\r\n * Force value as arrays\r\n * @param {String|Array} v\r\n * @returns {Array}\r\n */\r\nexport default function convertArray(v) {\r\n if (typeof v === \"string\") {\r\n if (v[0] === \"[\") {\r\n // \"['my', 'value']\" would fail as a json\r\n let bv = v;\r\n if (bv.indexOf('\"') === -1) {\r\n bv = bv.replace(/'/g, '\"');\r\n }\r\n return JSON.parse(bv);\r\n }\r\n\r\n return v.split(\",\");\r\n }\r\n if (!Array.isArray(v)) {\r\n console.error(\"Invalid array\", v);\r\n return [];\r\n }\r\n return v;\r\n}\r\n", "/**\r\n * @param {HTMLElement} el\r\n * @returns {Object}\r\n */\r\nexport default function elementOffset(el) {\r\n const rect = el.getBoundingClientRect();\r\n const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;\r\n const scrollTop = window.pageYOffset || document.documentElement.scrollTop;\r\n return { top: rect.top + scrollTop, left: rect.left + scrollLeft };\r\n}\r\n", "/**\r\n * Replace element within {} by their data value\r\n * @param {String} str\r\n * @param {Object} data\r\n * @returns {String}\r\n */\r\nexport default function interpolate(str, data) {\r\n return str.replace(/\\{([^}]+)?\\}/g, ($1, $2) => data[$2]);\r\n}\r\n", "let canvas;\r\n\r\n/**\r\n * Uses canvas.measureText to compute and return the width of the given text of given font in pixels.\r\n * Getting computed styles only works for dom that are added in the dom\r\n * @see https://stackoverflow.com/questions/118241/calculate-text-width-with-javascript/21015393#21015393\r\n * @param {String} text The text to be rendered.\r\n * @param {Element} el Target element (defaults to body)\r\n * @param {Boolean} withPadding Include padding on element\r\n * @returns {Number}\r\n */\r\nexport default function getTextWidth(text, el = document.body, withPadding = false) {\r\n const styles = window.getComputedStyle(el || document.createElement(\"div\"));\r\n const fontWeight = styles.getPropertyValue(\"font-weight\") || \"normal\";\r\n const fontSize = styles.getPropertyValue(\"font-size\") || \"1rem\";\r\n const fontFamily = styles.getPropertyValue(\"font-family\") || \"Arial\";\r\n\r\n let padding = 0;\r\n if (withPadding) {\r\n const paddingLeft = styles.getPropertyValue(\"padding-left\") || \"0\";\r\n const paddingRight = styles.getPropertyValue(\"padding-right\") || \"0\";\r\n padding = Number.parseInt(paddingLeft) + Number.parseInt(paddingRight);\r\n }\r\n\r\n // re-use canvas object for better performance\r\n if (!canvas) {\r\n canvas = document.createElement(\"canvas\");\r\n }\r\n const context = canvas.getContext(\"2d\");\r\n context.font = `${fontWeight} ${fontSize} ${fontFamily}`;\r\n const metrics = context.measureText(text);\r\n return Number.parseInt(metrics.width) + padding;\r\n}\r\n", "/**\r\n * @param {String} prefix\r\n * @returns {String}\r\n */\r\nexport default function randstr(prefix) {\r\n return Math.random()\r\n .toString(36)\r\n .replace(\"0.\", prefix || \"\");\r\n}\r\n", "/**\r\n * Define a function that can be happily passed to addEventListener\r\n * @typedef {Function & EventListenerOrEventListenerObject} ExtendedFunction\r\n */\r\n\r\n/**\r\n * @param {Function} handler\r\n * @param {Number} timeout\r\n * @returns {ExtendedFunction}\r\n */\r\nexport default function debounce(handler, timeout = 300) {\r\n let timer = null;\r\n return (...args) => {\r\n clearTimeout(timer);\r\n timer = setTimeout(() => {\r\n timer = null;\r\n handler(...args);\r\n }, timeout);\r\n };\r\n}\r\n", "/**\r\n * Data Grid Web component\r\n *\r\n * Credits for inspiration\r\n * @link https://github.com/riverside/zino-grid\r\n */\r\n\r\nimport BaseElement from \"./core/base-element.js\";\r\nimport addSelectOption from \"./utils/addSelectOption.js\";\r\nimport appendParamsToUrl from \"./utils/appendParamsToUrl.js\";\r\nimport camelize from \"./utils/camelize.js\";\r\nimport convertArray from \"./utils/convertArray.js\";\r\nimport elementOffset from \"./utils/elementOffset.js\";\r\nimport interpolate from \"./utils/interpolate.js\";\r\nimport getTextWidth from \"./utils/getTextWidth.js\";\r\nimport randstr from \"./utils/randstr.js\";\r\nimport debounce from \"./utils/debounce.js\";\r\nimport {\r\n $,\r\n $$,\r\n dispatch,\r\n find,\r\n findAll,\r\n hasClass,\r\n removeAttribute,\r\n getAttribute,\r\n setAttribute,\r\n addClass,\r\n toggleClass,\r\n on,\r\n ce,\r\n} from \"./utils/shortcuts.js\";\r\n\r\n/**\r\n * Column definition\r\n * @typedef Column\r\n * @property {String} field - the key in the data\r\n * @property {String} title - the title to display in the header (defaults to \"field\" if not set)\r\n * @property {Number} [width] - the width of the column (auto otherwise)\r\n * @property {String} [class] - class to set on the column (target body or header with th.class or td.class)\r\n * @property {String} [attr] - don't render the column and set a matching attribute on the row with the value of the field\r\n * @property {Boolean} [hidden] - hide the column\r\n * @property {Boolean} [noSort] - allow disabling sort for a given column\r\n * @property {String | Function} [format] - custom data formatting\r\n * @property {String} [defaultFormatValue] - default value to use for formatting\r\n * @property {String} [transform] - custom value transformation\r\n * @property {Boolean} [editable] - replace with input (EditableColumn module)\r\n * @property {String} [editableType] - type of input (EditableColumn module)\r\n * @property {Number} [responsive] - the higher the value, the sooner it will be hidden, disable with 0 (ResponsiveGrid module)\r\n * @property {Boolean} [responsiveHidden] - hidden through responsive module (ResponsiveGrid module)\r\n * @property {String} [filterType] - defines a filter field type (\"text\" or \"select\" - defaults to \"text\")\r\n * @property {Array} [filterList] - defines a custom array to populate a filter select field in the format of [{value: \"\", text: \"\"},...]. When defined, it overrides the default behaviour where the filter select elements are populated by the unique values from the corresponding column records.\r\n * @property {Object} [firstFilterOption] - defines an object for the first option element of the filter select field. defaults to {value: \"\", text: \"\"}\r\n */\r\n\r\n/**\r\n * Row action\r\n * @typedef Action\r\n * @property {String} title - the title of the button\r\n * @property {String} name - the name of the action\r\n * @property {String} class - the class for the button\r\n * @property {String} url - link for the action\r\n * @property {String} html - custom button data\r\n * @property {Boolean} [confirm] - needs confirmation\r\n * @property {Boolean} default - is the default row action\r\n */\r\n\r\n// Import definitions without importing the actual file\r\n/** @typedef {import('./plugins/autosize-column').default} AutosizeColumn */\r\n/** @typedef {import('./plugins/column-resizer').default} ColumnResizer */\r\n/** @typedef {import('./plugins/context-menu').default} ContextMenu */\r\n/** @typedef {import('./plugins/draggable-headers').default} DraggableHeaders */\r\n/** @typedef {import('./plugins/editable-column').default} EditableColumn */\r\n/** @typedef {import('./plugins/fixed-height').default} FixedHeight */\r\n/** @typedef {import('./plugins/responsive-grid').default} ResponsiveGrid */\r\n/** @typedef {import('./plugins/row-actions').default} RowActions */\r\n/** @typedef {import('./plugins/selectable-rows').default} SelectableRows */\r\n/** @typedef {import('./plugins/touch-support').default} TouchSupport */\r\n/** @typedef {import('./plugins/spinner-support').default} SpinnerSupport */\r\n/** @typedef {import('./plugins/save-state').default} SaveState */\r\n\r\n/**\r\n * These plugins are all optional\r\n * @typedef {Object} Plugins\r\n * @property {ColumnResizer} [ColumnResizer] resize handlers in the headers\r\n * @property {ContextMenu} [ContextMenu] menu to show/hide columns\r\n * @property {DraggableHeaders} [DraggableHeaders] draggable headers columns\r\n * @property {EditableColumn} [EditableColumn] draggable headers columns\r\n * @property {TouchSupport} [TouchSupport] touch swipe\r\n * @property {SelectableRows} [SelectableRows] create a column with checkboxes to select rows\r\n * @property {FixedHeight} [FixedHeight] allows having fixed height tables\r\n * @property {AutosizeColumn} [AutosizeColumn] compute ideal width based on column content\r\n * @property {ResponsiveGrid} [ResponsiveGrid] hide/show column on the fly\r\n * @property {RowActions} [RowActions] add action on rows\r\n * @property {SpinnerSupport} [SpinnerSupport] inserts a spinning icon element to indicate grid loading.\r\n * @property {SaveState} [SaveState] stores grid filter, sort, and paging.\r\n */\r\n\r\n/**\r\n * Parameters to pass along or receive from the server\r\n * @typedef ServerParams\r\n * @property {String} serverParams.start\r\n * @property {String} serverParams.length\r\n * @property {String} serverParams.search\r\n * @property {String} serverParams.sort\r\n * @property {String} serverParams.sortDir\r\n * @property {String} serverParams.dataKey\r\n * @property {String} serverParams.metaKey\r\n * @property {String} serverParams.metaTotalKey\r\n * @property {String} serverParams.metaFilteredKey\r\n * @property {String} serverParams.optionsKey\r\n * @property {String} serverParams.paramsKey\r\n */\r\n\r\n/**\r\n * Available data grid options, plugins included\r\n * @typedef Options\r\n * @property {?String} id Custom id for the grid\r\n * @property {?String} url An URL with data to display in JSON format\r\n * @property {Boolean} debug Log actions in DevTools console\r\n * @property {Boolean} filter Allows a filtering functionality\r\n * @property {Boolean} sort Allows a sort by column functionality\r\n * @property {String} defaultSort Default sort field if sorting is enabled\r\n * @property {Boolean} server Is a server side powered grid\r\n * @property {ServerParams} serverParams Describe keys passed to the server backend\r\n * @property {String} dir Dir\r\n * @property {Array} perPageValues Available per page options\r\n * @property {Boolean} hidePerPage Hides the page size select element\r\n * @property {Column[]} columns Available columns\r\n * @property {Number} defaultPage Starting page\r\n * @property {Number} perPage Number of records displayed per page (page size)\r\n * @property {Boolean} expand Allow cell content to spawn over multiple lines\r\n * @property {Action[]} actions Row actions (RowActions module)\r\n * @property {Boolean} collapseActions Group actions (RowActions module)\r\n * @property {Boolean} resizable Make columns resizable (ColumnResizer module)\r\n * @property {Boolean} selectable Allow multi-selecting rows with a checkboxes (SelectableRows module)\r\n * @property {Boolean} selectVisibleOnly Select all only selects visible rows (SelectableRows module)\r\n * @property {Boolean} singleSelect Enables single row select with radio buttons - no need to set selectable (SelectableRows module)\r\n * @property {Boolean} autosize Compute column sizes based on given data (Autosize module)\r\n * @property {Boolean} autoheight Adjust height so that it matches table size (FixedHeight module)\r\n * @property {Boolean} autohidePager auto-hides the pager when number of records falls below the selected page size\r\n * @property {Boolean} menu Right click menu on column headers (ContextMenu module)\r\n * @property {Boolean} reorder Allows a column reordering functionality (DraggableHeaders module)\r\n * @property {Boolean} responsive Change display mode on small screens (ResponsiveGrid module)\r\n * @property {Boolean} responsiveToggle Show toggle column (ResponsiveGrid module)\r\n * @property {Boolean} filterOnEnter Toggles the ability to filter column data by pressing the Enter or Return key\r\n * @property {String} spinnerClass Sets a space-delimited string of css classes for a spinner (use spinner-border css class for bootstrap 5 spinner)\r\n * @property {Number} filterKeypressDelay Sets a keypress delay time in milliseconds before triggering filter operation.\r\n * @property {Boolean} saveState Enable/disable save state plugin (SaveState module)\r\n * @property {?String} errorMessage A generic text to be displayed in footer when error occurs.\r\n * @property {?String} noData A custom text to be displayed when no data is loaded. This is different from the generic labels.noData that applies for data-grid as a component.\r\n */\r\n\r\n/**\r\n * Available labels that can be translated\r\n * @typedef Labels\r\n * @property {String} itemsPerPage\r\n * @property {String} gotoPage\r\n * @property {String} gotoFirstPage\r\n * @property {String} gotoPrevPage\r\n * @property {String} gotoNextPage\r\n * @property {String} gotoLastPage\r\n * @property {String} of\r\n * @property {String} items\r\n * @property {String} resizeColumn\r\n * @property {String} noData\r\n * @property {String} areYouSure\r\n * @property {String} networkError\r\n */\r\n\r\n/**\r\n * List of registered plugins\r\n * @type {Plugins}\r\n */\r\nlet plugins = {};\r\n\r\n/**\r\n * @type {Labels}\r\n */\r\nlet labels = {\r\n itemsPerPage: \"Items per page\",\r\n gotoPage: \"Go to page\",\r\n gotoFirstPage: \"Go to first page\",\r\n gotoPrevPage: \"Go to previous page\",\r\n gotoNextPage: \"Go to next page\",\r\n gotoLastPage: \"Go to last page\",\r\n of: \"of\",\r\n items: \"items\",\r\n resizeColumn: \"Resize column\",\r\n noData: \"No data\",\r\n areYouSure: \"Are you sure?\",\r\n networkError: \"Network response error\",\r\n};\r\n\r\n/**\r\n * Column definition will update some props on the html element\r\n * @param {HTMLElement} el\r\n * @param {Column} column\r\n */\r\nfunction applyColumnDefinition(el, column) {\r\n if (column.width) {\r\n setAttribute(el, \"width\", column.width);\r\n }\r\n if (column.class) {\r\n addClass(el, column.class);\r\n }\r\n if (column.hidden) {\r\n setAttribute(el, \"hidden\", \"\");\r\n if (column.responsiveHidden) {\r\n addClass(el, \"dg-responsive-hidden\");\r\n }\r\n }\r\n}\r\n\r\n/**\r\n */\r\nclass DataGrid extends BaseElement {\r\n _filterSelector = \"[id^=dg-filter]\";\n _excludedRowElementSelector = \"a,button,input,select,textarea\";\r\n _excludedKeys = [\r\n 37,\r\n 39,\r\n 38,\r\n 40,\r\n 45,\r\n 36,\r\n 35,\r\n 33,\r\n 34,\r\n 27,\r\n 20,\r\n 16,\r\n 17,\r\n 91,\r\n 92,\r\n 18,\r\n 93,\r\n 144,\r\n 231,\r\n \"ArrowLeft\",\r\n \"ArrowRight\",\r\n \"ArrowUp\",\r\n \"ArrowDown\",\r\n \"Insert\",\r\n \"Home\",\r\n \"End\",\r\n \"PageUp\",\r\n \"PageDown\",\r\n \"Escape\",\r\n \"CapsLock\",\r\n \"Shift\",\r\n \"Control\",\r\n \"Meta\",\r\n \"Alt\",\r\n \"ContextMenu\",\r\n \"NumLock\",\r\n \"Unidentified\",\r\n ];\n\r\n _ready() {\r\n setAttribute(this, \"id\", this.options.id ?? randstr(\"el-\"), true);\r\n\r\n /**\r\n * The grid displays that data\r\n * @type {Array}\r\n */\r\n this.data = [];\r\n /**\r\n * We store the original data in this\r\n * @type {Array}\r\n */\r\n this.originalData; // declared uninitialized to allow data preloading before fetch.\r\n\r\n // Make the IDE happy\r\n /**\r\n * @type {Options}\r\n */\r\n this.options = this.options || this.defaultOptions;\n if (this.options.singleSelect) this.options.selectable = true; // singleSelect implies selectable\r\n\r\n // Init values\r\n this.fireEvents = false;\r\n this.page = this.options.defaultPage || 1;\r\n this.pages = 0;\r\n this.meta; // declared uninitialized to allow data preloading before fetch.\r\n /**\r\n * @type {Plugins}\r\n */\r\n this.plugins = {};\r\n // Init plugins\r\n for (const [pluginName, pluginClass] of Object.entries(plugins)) {\r\n // @ts-ignore until we can set typeof import ...\r\n this.plugins[pluginName] = new pluginClass(this);\r\n }\r\n\r\n // Expose options as observed attributes in the dom\r\n // Do it when fireEvents is disabled to avoid firing change callbacks\r\n for (const attr of DataGrid.observedAttributes) {\r\n if (attr.indexOf(\"data-\") === 0) {\r\n setAttribute(this, attr, this.options[camelize(attr.slice(5))]);\r\n }\r\n }\r\n }\r\n\r\n static template() {\r\n return `\r\n\r\n \r\n |
\r\n
\r\n \r\n \r\n \r\n \r\n | \r\n \r\n | \r\n
\r\n \r\n \r\n
\r\n`;\r\n }\r\n\r\n /**\r\n * @returns {Labels}\r\n */\r\n get labels() {\r\n return labels;\r\n }\r\n\r\n /**\r\n * @returns {Labels}\r\n */\r\n static getLabels() {\r\n return labels;\r\n }\r\n\r\n /**\r\n * @param {Object} v\r\n */\r\n static setLabels(v) {\r\n labels = Object.assign(labels, v);\r\n }\n\r\n /** Gets the text to be displayed when no data is loaded. */\n get noData() {\n return this.options.noData || this.labels.noData;\r\n }\n\n /**\r\n * @param {HTMLTableSectionElement} tbody\r\n */\n #setNoData(tbody) {\n if (!this.hasDataError && tbody.getAttribute(\"data-empty\") !== this.noData) {\r\n tbody.setAttribute(\"data-empty\", this.noData);\r\n }\r\n }\n\r\n /**\r\n * @returns {Column}\r\n */\r\n get defaultColumn() {\r\n return {\r\n field: \"\",\r\n title: \"\",\r\n width: 0,\r\n class: \"\",\r\n attr: \"\",\r\n hidden: false,\r\n editable: false,\r\n noSort: false,\r\n responsive: 1,\r\n responsiveHidden: false,\r\n format: \"\",\r\n transform: \"\",\r\n filterType: \"text\",\r\n firstFilterOption: { value: \"\", text: \"\" },\r\n };\r\n }\r\n\r\n /**\r\n * @returns {Options}\r\n */\r\n get defaultOptions() {\r\n return {\r\n id: null,\r\n url: \"\",\r\n perPage: 10,\r\n debug: false,\r\n filter: false,\r\n menu: false,\r\n sort: false,\r\n server: false,\r\n serverParams: {\r\n start: \"start\",\r\n length: \"length\",\r\n search: \"search\",\r\n sort: \"sort\",\r\n sortDir: \"sortDir\",\r\n dataKey: \"data\",\r\n metaKey: \"meta\",\r\n metaTotalKey: \"total\",\r\n metaFilteredKey: \"filtered\",\r\n optionsKey: \"options\",\r\n paramsKey: \"params\",\r\n },\r\n defaultSort: \"\",\r\n reorder: false,\r\n dir: \"ltr\",\r\n perPageValues: [10, 25, 50, 100, 250],\r\n hidePerPage: false,\r\n columns: [],\r\n actions: [],\r\n collapseActions: false,\r\n selectable: false,\r\n selectVisibleOnly: true,\n singleSelect: false,\r\n defaultPage: 1,\r\n resizable: false,\r\n autosize: true,\r\n expand: false,\r\n autoheight: true,\r\n autohidePager: false,\r\n responsive: false,\r\n responsiveToggle: true,\r\n filterOnEnter: true,\r\n filterKeypressDelay: 500,\r\n spinnerClass: \"\",\r\n saveState: false,\r\n errorMessage: \"\",\n noData: \"\"\r\n };\r\n }\r\n\r\n /**\r\n * Determines if the grid is initialized.\r\n * @returns {Boolean}\r\n */\r\n get isInit() {\r\n return this.classList.contains(\"dg-initialized\");\r\n }\r\n\r\n /**\r\n * Determines if data load has failed.\r\n * @returns {Boolean}\r\n */\r\n get hasDataError() {\r\n return this.classList.contains(\"dg-network-error\");\r\n }\r\n\r\n /**\r\n * @param {Plugins} list\r\n */\r\n static registerPlugins(list) {\r\n plugins = list;\r\n }\r\n\r\n /**\r\n * @param {String} plugin\r\n */\r\n static unregisterPlugins(plugin = null) {\r\n if (plugin === null) {\r\n plugins = {};\r\n } else {\r\n delete plugins[plugin];\r\n }\r\n }\r\n\r\n /**\r\n * @returns {Plugins}\r\n */\r\n static registeredPlugins() {\r\n return plugins;\r\n }\r\n\r\n /**\r\n * @param {Object|Array} columns\r\n * @returns {Column[]}\r\n */\r\n convertColumns(columns) {\r\n const cols = [];\r\n // Convert key:value objects to actual columns\r\n if (typeof columns === \"object\" && !Array.isArray(columns)) {\r\n for (const key of Object.keys(columns)) {\r\n const col = Object.assign({}, this.defaultColumn);\r\n col.title = columns[key];\r\n col.field = key;\r\n cols.push(col);\r\n }\r\n } else {\r\n for (const item of columns) {\r\n let col = Object.assign({}, this.defaultColumn);\r\n if (typeof item === \"string\") {\r\n col.title = item;\r\n col.field = item;\r\n } else if (typeof item === \"object\") {\r\n col = Object.assign(col, item);\r\n if (!col.field) {\r\n console.error(\"Invalid column definition\", item);\r\n }\r\n if (!col.title) {\r\n col.title = col.field;\r\n }\r\n } else {\r\n console.error(\"Column definition must be a string or an object\");\r\n }\r\n cols.push(col);\r\n }\r\n }\r\n return cols;\r\n }\r\n\r\n /**\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#reflected-dom-attributes\r\n * @returns {Array}\r\n */\r\n static get observedAttributes() {\r\n return [\r\n \"page\",\r\n \"data-filter\",\r\n \"data-sort\",\r\n \"data-debug\",\r\n \"data-reorder\",\r\n \"data-menu\",\r\n \"data-selectable\",\n \"data-single-select\",\r\n \"data-url\",\r\n \"data-per-page\",\r\n \"data-responsive\",\r\n ];\r\n }\r\n\r\n get transformAttributes() {\r\n return {\r\n columns: (v) => this.convertColumns(convertArray(v)),\r\n actions: (v) => convertArray(v),\r\n defaultPage: (v) => Number.parseInt(v),\r\n perPage: (v) => Number.parseInt(v),\r\n };\r\n }\r\n\r\n /** @returns {HTMLTableSectionElement} */\r\n get thead() {\r\n //@ts-ignore\r\n return $(\"thead\", this);\r\n }\r\n\r\n /** @returns {HTMLTableSectionElement} */\r\n get tbody() {\r\n //@ts-ignore\r\n return $(\"tbody\", this);\r\n }\r\n\r\n /** @returns {HTMLTableSectionElement} */\r\n get tfoot() {\r\n //@ts-ignore\r\n return $(\"tfoot\", this);\r\n }\r\n\r\n get page() {\r\n return Number.parseInt(this.getAttribute(\"page\"));\r\n }\r\n\r\n set page(val) {\r\n setAttribute(this, \"page\", this.constrainPageValue(val));\r\n }\r\n\r\n /**\r\n * Loads data and configures the grid.\r\n * @param {Boolean} initOnly\r\n */\r\n urlChanged(initOnly = false) {\r\n if (initOnly && !this.isInit) return this;\r\n this.reconfig();\r\n return this.loadData().then(() => this.configureUi());\r\n }\r\n\r\n /**\r\n * Clears columns, re-renders table, and repopulates columns to ensure consistent column widths rendering.\r\n */\r\n reconfig() {\r\n const cols = this.options.columns;\r\n this.options.columns = [];\r\n this.configureUi();\r\n return this.options.columns = cols, this;\r\n }\r\n\r\n constrainPageValue(v) {\r\n let pv = v;\r\n if (this.pages < pv) {\r\n pv = this.pages;\r\n }\r\n if (pv < 1 || !pv) {\r\n pv = 1;\r\n }\r\n return pv;\r\n }\r\n\r\n fixPage() {\n if (!this.inputPage) return this;\r\n this.pages = this.totalPages();\r\n this.page = this.constrainPageValue(this.page);\r\n\r\n // Show current page in input\r\n setAttribute(this.inputPage, \"max\", this.pages);\r\n this.inputPage.value = `${this.page}`;\r\n return this.inputPage.disabled = this.pages < 2, this;\r\n }\r\n\r\n pageChanged() {\r\n this.reload();\r\n }\r\n\r\n responsiveChanged() {\r\n if (!this.plugins.ResponsiveGrid) {\r\n return;\r\n }\r\n if (this.options.responsive) {\r\n this.plugins.ResponsiveGrid.observe();\r\n } else {\r\n this.plugins.ResponsiveGrid.unobserve();\r\n }\r\n }\r\n\r\n menuChanged() {\r\n this.renderHeader();\r\n }\r\n\r\n /**\r\n * This is the callback for the select control\r\n */\r\n changePerPage() {\r\n this.options.perPage = Number.parseInt(this.selectPerPage.options[this.selectPerPage.selectedIndex].value);\r\n this.perPageChanged();\r\n }\r\n\r\n /**\r\n * This is the actual event triggered on attribute change\r\n */\r\n perPageChanged() {\r\n // Refresh UI\r\n if (\r\n this.options.perPage !== Number.parseInt(this.selectPerPage.options[this.selectPerPage.selectedIndex].value)\r\n ) {\r\n this.perPageValuesChanged();\r\n }\r\n // Make sure current page is still valid\r\n let updatePage = this.page;\r\n while (updatePage > 1 && this.page * this.options.perPage > this.totalRecords()) {\r\n updatePage--;\r\n }\r\n if (updatePage !== this.page) {\r\n // Triggers pageChanged, which will trigger reload\r\n this.page = updatePage;\r\n } else {\r\n // Simply reload current page\r\n this.reload(() => {\r\n // Preserve distance between top of page and select control if no fixed height\r\n if (!this.plugins.FixedHeight || !this.plugins.FixedHeight.hasFixedHeight) {\r\n this.selectPerPage.scrollIntoView();\r\n }\r\n });\r\n }\r\n }\r\n\r\n dirChanged() {\r\n setAttribute(this, \"dir\", this.options.dir);\r\n }\r\n\r\n defaultSortChanged() {\r\n this.sortChanged();\r\n }\r\n\r\n /**\r\n * Populate the select dropdown according to options\r\n */\r\n perPageValuesChanged() {\r\n if (!this.selectPerPage) {\r\n return;\r\n }\r\n while (this.selectPerPage.lastChild) {\r\n this.selectPerPage.removeChild(this.selectPerPage.lastChild);\r\n }\r\n for (const v of this.options.perPageValues) {\r\n addSelectOption(this.selectPerPage, v, v, v === this.options.perPage);\r\n }\r\n }\r\n\r\n async _connected() {\r\n /**\r\n * @type {HTMLTableElement}\r\n */\r\n this.table = this.querySelector(\"table\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnFirst = this.querySelector(\".dg-btn-first\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnPrev = this.querySelector(\".dg-btn-prev\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnNext = this.querySelector(\".dg-btn-next\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.btnLast = this.querySelector(\".dg-btn-last\");\r\n /**\r\n * @type {HTMLSelectElement}\r\n */\r\n this.selectPerPage = this.querySelector(\".dg-select-per-page\");\r\n /**\r\n * @type {HTMLInputElement}\r\n */\r\n this.inputPage = this.querySelector(\".dg-input-page\");\r\n\r\n this.getFirst = this.getFirst.bind(this);\r\n this.getPrev = this.getPrev.bind(this);\r\n this.getNext = this.getNext.bind(this);\r\n this.getLast = this.getLast.bind(this);\r\n this.changePerPage = this.changePerPage.bind(this);\r\n this.gotoPage = this.gotoPage.bind(this);\r\n\r\n this.btnFirst.addEventListener(\"click\", this.getFirst);\r\n this.btnPrev.addEventListener(\"click\", this.getPrev);\r\n this.btnNext.addEventListener(\"click\", this.getNext);\r\n this.btnLast.addEventListener(\"click\", this.getLast);\r\n this.selectPerPage.addEventListener(\"change\", this.changePerPage);\r\n this.selectPerPage.toggleAttribute(\"hidden\", this.options.hidePerPage);\r\n this.inputPage.addEventListener(\"input\", this.gotoPage);\r\n\r\n for (const plugin of Object.values(this.plugins)) {\r\n await plugin.connected();\r\n }\r\n\r\n // Display even if we don't have data\r\n this.dirChanged();\r\n this.perPageValuesChanged();\r\n\n await this.init();\r\n }\r\n\r\n _disconnected() {\r\n this.btnFirst?.removeEventListener(\"click\", this.getFirst);\r\n this.btnPrev?.removeEventListener(\"click\", this.getPrev);\r\n this.btnNext?.removeEventListener(\"click\", this.getNext);\r\n this.btnLast?.removeEventListener(\"click\", this.getLast);\r\n this.selectPerPage?.removeEventListener(\"change\", this.changePerPage);\r\n this.inputPage?.removeEventListener(\"input\", this.gotoPage);\r\n\r\n for (const plugin of Object.values(this.plugins)) {\r\n plugin.disconnected();\r\n }\r\n }\n\n init() {\n return this.loadData().finally(() => {\r\n this.configureUi();\r\n\r\n this.sortChanged();\r\n this.classList.add(\"dg-initialized\"); //acts as a flag to prevent unnecessary server calls down the chain.\r\n\r\n this.filterChanged();\r\n this.reorderChanged();\r\n\r\n this.dirChanged();\r\n this.perPageValuesChanged();\r\n this.pageChanged();\r\n\r\n this.fireEvents = true; // We can now fire attributeChangedCallback events\r\n\r\n this.log(\"initialized\");\r\n });\n }\r\n\r\n /**\r\n * @param {string} field\r\n * @returns {Column}\r\n */\r\n getCol(field) {\r\n let found = null;\r\n\r\n for (const col of this.options.columns) {\r\n if (col.field === field) {\r\n found = col;\r\n }\r\n }\r\n return found;\r\n }\r\n\r\n getColProp(field, prop) {\r\n const c = this.getCol(field);\r\n return c ? c[prop] : null;\r\n }\r\n\r\n setColProp(field, prop, val) {\r\n const c = this.getCol(field);\r\n if (c) {\r\n c[prop] = val;\r\n }\r\n }\r\n\r\n visibleColumns() {\r\n return this.options.columns.filter((col) => {\r\n return !col.hidden;\r\n });\r\n }\r\n\r\n hiddenColumns() {\r\n return this.options.columns.filter((col) => {\r\n return col.hidden === true;\r\n });\r\n }\r\n\r\n showColumn(field, render = true) {\r\n this.setColProp(field, \"hidden\", false);\r\n\r\n // We need to render the whole table otherwise layout fixed won't do its job\r\n if (render) this.renderTable();\r\n\r\n dispatch(this, \"columnVisibility\", {\r\n col: field,\r\n visibility: \"visible\",\r\n });\r\n }\r\n\r\n hideColumn(field, render = true) {\r\n this.setColProp(field, \"hidden\", true);\r\n\r\n // We need to render the whole table otherwise layout fixed won't do its job\r\n if (render) this.renderTable();\r\n\r\n dispatch(this, \"columnVisibility\", {\r\n col: field,\r\n visibility: \"hidden\",\r\n });\r\n }\r\n\r\n /**\r\n * Returns the starting index of actual data\r\n * @returns {Number}\r\n */\r\n startColIndex() {\r\n let start = 1;\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n start++;\r\n }\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n start++;\r\n }\r\n return start;\r\n }\r\n\r\n /**\r\n * @returns {Boolean}\r\n */\r\n isSticky() {\r\n return this.hasAttribute(\"sticky\");\r\n }\r\n\r\n /**\r\n * @param {Boolean} visibleOnly\r\n * @returns {Number}\r\n */\r\n columnsLength(visibleOnly = false) {\r\n let len = 0;\r\n // One column per (visible) column\r\n for (const col of this.options.columns) {\r\n if (visibleOnly && col.hidden) {\r\n continue;\r\n }\r\n if (!col.attr) {\r\n len++;\r\n }\r\n }\r\n // Add one col for selectable checkbox at the beginning\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n len++;\r\n }\r\n // Add one col for actions at the end\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n len++;\r\n }\r\n // Add one col for the responsive toggle\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n len++;\r\n }\r\n return len;\r\n }\r\n\r\n /**\r\n * Global configuration and renderTable\r\n * This should be called after your data has been loaded\r\n */\r\n configureUi() {\r\n if (!this.table) return this;\n this.table.style.visibility = \"hidden\";\r\n this.renderTable();\r\n if (this.options.responsive && this.plugins.ResponsiveGrid) {\r\n // Let the observer make the table visible\r\n } else {\r\n this.table.style.visibility = \"visible\";\r\n }\r\n\r\n // Store row height for later usage\r\n if (!this.rowHeight) {\r\n const tr = find(this, \"tbody tr\") || find(this, \"table tr\");\r\n if (tr) {\r\n this.rowHeight = tr.offsetHeight;\r\n }\r\n }\n this.#setNoData(this.tbody);\r\n return this.fixPage();\r\n }\r\n\r\n filterChanged() {\r\n const row = this.querySelector(\"thead tr.dg-head-filters\");\r\n if (this.options.filter) {\r\n removeAttribute(row, \"hidden\");\r\n } else {\r\n this.clearFilters();\r\n setAttribute(row, \"hidden\", \"\");\r\n }\r\n }\r\n\r\n reorderChanged() {\r\n const headers = findAll(this, \"thead tr.dg-head-columns th\");\r\n for (const th of headers) {\r\n if (th.classList.contains(\"dg-selectable\") || th.classList.contains(\"dg-actions\")) {\r\n continue;\r\n }\r\n if (this.options.reorder && this.plugins.DraggableHeaders) {\r\n th.draggable = true;\r\n } else {\r\n th.removeAttribute(\"draggable\");\r\n }\r\n }\r\n }\r\n\r\n sortChanged() {\r\n this.log(\"toggle sort\");\r\n\r\n const headers = findAll(this, \"thead tr.dg-head-columns th\");\r\n for (const th of headers) {\r\n const fieldName = th.getAttribute(\"field\");\r\n if (\r\n th.classList.contains(\"dg-not-sortable\") ||\r\n (!this.fireEvents && fieldName === this.options.defaultSort)\r\n ) {\r\n return;\r\n }\r\n if (this.options.sort && !this.getColProp(fieldName, \"noSort\")) {\r\n setAttribute(th, \"aria-sort\", \"none\");\r\n } else {\r\n removeAttribute(th, \"aria-sort\");\r\n }\r\n }\r\n }\r\n\r\n selectableChanged() {\r\n this.renderTable();\r\n }\r\n\r\n addRow(row) {\r\n if (!Array.isArray(this.originalData)) {\r\n return;\r\n }\r\n this.log(\"add row\");\r\n this.originalData.push(row);\r\n this.data = this.originalData.slice();\r\n this.sortData();\r\n }\r\n\r\n /**\r\n * @param {any} value Value to remove. Defaults to last row.\r\n * @param {String} key The key of the item to remove. Defaults to first column\r\n */\r\n removeRow(value = null, key = null) {\r\n if (!Array.isArray(this.originalData)) {\r\n return;\r\n }\r\n\r\n let v = value;\r\n let k = key;\r\n if (k === null) {\r\n k = this.options.columns[0].field;\r\n }\r\n if (v === null) {\r\n v = this.originalData[this.originalData.length - 1][k];\r\n }\r\n this.log(`remove row ${k}:${v}`);\r\n for (let i = 0; i < this.originalData.length; i++) {\r\n if (this.originalData[i][k] === v) {\r\n this.originalData.splice(i, 1);\r\n break;\r\n }\r\n }\r\n this.data = this.originalData.slice();\r\n this.sortData();\r\n }\r\n\r\n /**\n * Get selected rows or specific fields from selected rows.\n * If no keys are provided, returns the full row objects.\n * If one key is provided, returns an array of values for that key.\n * If multiple keys are provided, returns an array of objects with those keys and values.\n * In single select mode, returns a single object or value.\n * @param {...String} keys - Field names to select from each row.\n * @returns {Array|Object} Selected rows, values, or objects depending on selection and keys.\n */\n getSelection(...keys) {\n if (!this.plugins.SelectableRows) {\n return [];\n }\n return this.plugins.SelectableRows.getSelection(...keys);\n }\r\n\r\n getData() {\r\n return this.originalData;\r\n }\r\n\r\n clearData(force = false) {\r\n // Already empty\r\n if (!force && this.data.length === 0) {\r\n return;\r\n }\n this.classList.remove(\"dg-empty\", \"dg-network-error\");\n this.tbody?.setAttribute(\"data-empty\", this.noData);\r\n this.data = this.originalData = [];\r\n this.renderBody();\r\n }\r\n\r\n /**\r\n * Preloads the data intended to bypass the initial fetch operation, allowing for faster intial page load time.\r\n * Subsequent grid actions after initialization will operate as normal.\r\n * @param {Object} data - an object with meta ({total, filtered, start}) and data (array of objects) properties.\r\n */\r\n preload(data) {\r\n const metaKey = this.options.serverParams.metaKey;\r\n const dataKey = this.options.serverParams.dataKey;\r\n if (data?.[metaKey]) {\r\n this.meta = data[metaKey];\r\n }\r\n if (data?.[dataKey]) {\r\n this.data = this.originalData = data[dataKey];\r\n }\r\n }\r\n\n /**\n * Clears and reloads data from url.\n * @param {Function|String} callbackOrUrl\n * @returns {DataGrid}\n */\r\n refresh(callbackOrUrl = null) {\r\n this.data = this.originalData = [];\r\n return this.reload(callbackOrUrl);\r\n }\r\n\n /**\n * Reloads data from url.\n * @param {Function|String} callbackOrUrl\n * @returns {DataGrid}\n */\r\n reload(callbackOrUrl = null) {\r\n this.log(\"reload\");\r\n if (typeof callbackOrUrl === \"string\") {\n this.options.url = callbackOrUrl;\n }\r\n // If the data was cleared, we need to render again\r\n const needRender = !this.originalData?.length;\r\n this.fixPage();\r\n // @ts-ignore\r\n return this.loadData().finally(() => {\r\n if (this.hasDataError) return;\r\n // If we load data from the server, we redraw the table body\r\n // Otherwise, we just need to paginate\r\n this.options.server || needRender ? this.renderBody() : this.paginate();\r\n if (typeof callbackOrUrl === \"function\") {\r\n callbackOrUrl();\r\n }\r\n }).then(() => this);\r\n }\r\n\r\n /**\r\n * @returns {Promise}\r\n */\r\n loadData() {\r\n const flagEmpty = () => !this.data.length && this.classList.add(\"dg-empty\");\r\n const tbody = this.tbody;\r\n\r\n // We already have some data\r\n if (this.meta || this.originalData || this.isInit) {\r\n // We don't use server side data\r\n if (!this.options.server || (this.options.server && !this.fireEvents)) {\r\n this.log(\"skip loadData\");\r\n flagEmpty();\r\n return new Promise((resolve) => {\r\n resolve();\r\n });\r\n }\r\n }\r\n this.log(\"loadData\");\r\n this.loading = true;\r\n this.classList.add(\"dg-loading\");\r\n this.classList.remove(\"dg-empty\", \"dg-network-error\");\r\n return (\r\n this.fetchData()\r\n .then((response) => {\r\n // We can get a straight array or an object\r\n if (Array.isArray(response)) {\r\n this.data = response;\r\n } else {\r\n // Object must contain data key\r\n if (!response[this.options.serverParams.dataKey]) {\r\n console.error(\r\n \"Invalid response, it should contain a data key with an array or be a plain array\",\r\n response,\r\n );\r\n this.options.url = null;\r\n return;\r\n }\r\n\r\n // We may have a config object\r\n this.options = Object.assign(\r\n this.options,\r\n response[this.options.serverParams.optionsKey] ?? {},\r\n );\r\n // It should return meta data (see metaFilteredKey)\r\n this.meta = response[this.options.serverParams.metaKey] ?? {};\r\n this.data = response[this.options.serverParams.dataKey];\r\n }\r\n this.originalData = this.data.slice();\r\n this.fixPage();\r\n\r\n // Make sure we have a proper set of columns\r\n if (this.options.columns.length === 0 && this.originalData.length) {\r\n this.options.columns = this.convertColumns(Object.keys(this.originalData[0]));\r\n } else {\r\n this.options.columns = this.convertColumns(this.options.columns);\r\n }\r\n })\r\n .catch((err) => {\r\n this.log(err);\r\n tbody.setAttribute(\r\n \"data-empty\",\r\n this.options.errorMessage ||\r\n err.message?.replace(/^\\s+|\\r\\n|\\n|\\r$/g, \"\") ||\r\n labels.networkError,\r\n );\r\n this.classList.add(\"dg-empty\", \"dg-network-error\");\r\n dispatch(this, \"loadDataFailed\", err);\r\n })\r\n // @ts-ignore\r\n .finally(() => {\r\n flagEmpty();\r\n this.#setNoData(tbody);\r\n this.classList.remove(\"dg-loading\");\r\n setAttribute(this.table, \"aria-rowcount\", this.data.length);\r\n this.loading = false;\r\n })\r\n );\r\n }\r\n\r\n getFirst() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = 1;\r\n }\r\n\r\n getLast() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = this.pages;\r\n }\r\n\r\n getPrev() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = this.page - 1;\r\n }\r\n\r\n getNext() {\r\n if (this.loading) {\r\n return;\r\n }\r\n this.page = this.page + 1;\r\n }\r\n\r\n gotoPage(event) {\r\n if (event.type === \"keypress\") {\r\n const key = event.keyCode || event.key;\r\n if (key === 13 || key === \"Enter\") {\r\n event.preventDefault();\r\n } else {\r\n return;\r\n }\r\n }\r\n this.page = Number.parseInt(this.inputPage.value);\r\n }\r\n\r\n getSort() {\r\n const col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n if (col) {\r\n return col.getAttribute(\"field\");\r\n }\r\n return this.options.defaultSort;\r\n }\r\n\r\n getSortDir() {\r\n const col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n if (col) {\r\n return col.getAttribute(\"aria-sort\") || \"\";\r\n }\r\n return \"\";\r\n }\r\n\r\n getFilters() {\r\n const filters = [];\r\n const inputs = findAll(this, this._filterSelector);\r\n for (const input of inputs) {\r\n filters[input.dataset.name] = input.value;\r\n }\r\n return filters;\r\n }\r\n\r\n clearFilters() {\r\n const inputs = findAll(this, this._filterSelector);\r\n for (const input of inputs) {\r\n input.value = \"\";\r\n }\r\n this.filterData();\r\n }\r\n\r\n filterData() {\r\n this.log(\"filter data\");\r\n\r\n this.page = 1;\r\n\r\n if (this.options.server) {\r\n this.reload();\r\n } else {\r\n this.data = this.originalData?.slice() ?? [];\r\n\r\n // Look for rows matching the filters\r\n const inputs = findAll(this, this._filterSelector);\r\n for (const input of inputs) {\r\n const value = input.value;\r\n if (value) {\r\n const name = input.dataset.name;\r\n this.data = this.data.filter((item) => {\r\n const str = `${item[name]}`;\r\n return str.toLowerCase().indexOf(value.toLowerCase()) !== -1;\r\n });\r\n }\r\n }\r\n this.pageChanged();\r\n\r\n const col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n if (this.options.sort && col) {\r\n this.sortData();\r\n } else {\r\n this.renderBody();\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Data will be sorted then rendered using renderBody\r\n * @param {Element} baseCol The column that was clicked or null to use current sort\r\n */\r\n sortData(baseCol = null) {\r\n this.log(\"sort data\");\r\n\r\n let col = baseCol;\r\n\r\n // Early exit\r\n if (col && this.getColProp(col.getAttribute(\"field\"), \"noSort\")) {\r\n this.log(\"sorting prevented because column is not sortable\");\r\n return;\r\n }\r\n if (this.plugins.ColumnResizer?.isResizing) {\r\n this.log(\"sorting prevented because resizing\");\r\n return;\r\n }\r\n if (this.loading) {\r\n this.log(\"sorting prevented because loading\");\r\n return;\r\n }\r\n\r\n // We clicked on a column, update sort state\r\n if (col !== null) {\r\n // Remove active sort if any\r\n const haveClasses = (c) => [\"dg-selectable\", \"dg-actions\", \"dg-responsive-toggle\"].includes(c);\r\n\r\n const headers = findAll(this, \"thead tr:first-child th\");\r\n for (const th of headers) {\r\n // @ts-ignore\r\n if ([...th.classList].some(haveClasses) || !th.hasAttribute(\"aria-sort\")) {\r\n continue;\r\n }\r\n if (th !== col) {\r\n th.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n }\r\n\r\n // Set tristate col\r\n if (!col.hasAttribute(\"aria-sort\") || col.getAttribute(\"aria-sort\") === \"none\") {\r\n col.setAttribute(\"aria-sort\", \"ascending\");\r\n } else if (col.getAttribute(\"aria-sort\") === \"ascending\") {\r\n col.setAttribute(\"aria-sort\", \"descending\");\r\n } else if (col.getAttribute(\"aria-sort\") === \"descending\") {\r\n col.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n } else {\r\n // Or fetch current sort\r\n col = this.querySelector(\"thead tr.dg-head-columns th[aria-sort$='scending']\");\r\n }\r\n\r\n if (this.options.server) {\r\n // Reload data with updated sort\r\n this.loadData().finally(() => {\r\n this.renderBody();\r\n });\r\n } else {\r\n const sort = col ? col.getAttribute(\"aria-sort\") : \"none\";\r\n if (sort === \"none\") {\r\n const stack = [];\r\n\r\n // Restore order while keeping filters\r\n this.originalData?.some((itemA) => {\r\n this.data.some((itemB) => {\r\n if (JSON.stringify(itemA) === JSON.stringify(itemB)) {\r\n stack.push(itemB);\r\n return true;\r\n }\r\n return false;\r\n });\r\n return stack.length === this.data.length;\r\n });\r\n\r\n this.data = stack;\r\n } else {\r\n const field = col.getAttribute(\"field\");\r\n this.data.sort((a, b) => {\r\n if (!isNaN(a[field]) && !isNaN(b[field])) {\r\n return sort === \"ascending\" ? a[field] - b[field] : b[field] - a[field];\r\n }\r\n const valA = sort === \"ascending\" ? a[field].toUpperCase() : b[field].toUpperCase();\r\n const valB = sort === \"ascending\" ? b[field].toUpperCase() : a[field].toUpperCase();\r\n\r\n switch (true) {\r\n case valA > valB:\r\n return 1;\r\n case valA < valB:\r\n return -1;\r\n case valA === valB:\r\n return 0;\r\n }\r\n });\r\n }\r\n this.renderBody();\r\n }\r\n }\r\n\r\n _sort(columnName, sortDir) {\r\n const col = this.querySelector(`.dg-head-columns th[field=${columnName}]`);\r\n const dir = sortDir === \"ascending\" ? \"none\" : sortDir === \"descending\" ? \"ascending\" : \"descending\";\r\n col?.setAttribute(\"aria-sort\", dir);\r\n this.sortData(col);\r\n }\r\n\r\n sortAsc = (columnName) => this._sort(columnName, \"ascending\");\r\n sortDesc = (columnName) => this._sort(columnName, \"descending\");\r\n sortNone = (columnName) => this._sort(columnName, \"none\");\r\n\r\n fetchData() {\r\n if (!this.options.url) {\r\n return new Promise((resolve, reject) => reject(\"No url set\"));\r\n }\r\n\r\n let base = window.location.href;\r\n // Fix trailing slash if no extension is present\r\n if (!base.split(\"/\").pop().includes(\".\")) {\r\n base += base.endsWith(\"/\") ? \"\" : \"/\";\r\n }\r\n const url = new URL(this.options.url, base);\r\n let params = {\r\n r: Date.now(),\r\n };\r\n if (this.options.server) {\r\n // 0 based\r\n params[this.options.serverParams.start] = this.page - 1;\r\n params[this.options.serverParams.length] = this.options.perPage;\r\n if (this.options.filter) params[this.options.serverParams.search] = this.getFilters();\r\n params[this.options.serverParams.sort] = this.getSort() || \"\";\r\n params[this.options.serverParams.sortDir] = this.getSortDir();\r\n\r\n // extra params ?\r\n if (this.meta?.[this.options.serverParams.paramsKey]) {\r\n params = Object.assign(params, this.meta[this.options.serverParams.paramsKey]);\r\n }\r\n }\r\n\r\n appendParamsToUrl(url, params);\r\n\r\n return fetch(url).then((response) => {\r\n const newError = new Error(response.statusText || labels.networkError);\r\n if (!response.ok) {\r\n // @ts-ignore\r\n newError.response = response;\r\n throw newError;\r\n }\r\n return response\r\n .clone()\r\n .json()\r\n .catch((err) => {\r\n let error = err;\r\n if (!this.options.debug) {\r\n error = newError;\r\n }\r\n error.response = response;\r\n throw error;\r\n });\r\n });\r\n }\r\n\r\n renderTable() {\r\n this.log(\"render table\");\r\n\r\n if (this.options.menu && this.plugins.ContextMenu) {\r\n this.plugins.ContextMenu.createMenu();\r\n }\r\n\r\n let sortedColumn;\r\n\r\n this.renderHeader();\r\n if (this.options.defaultSort) {\r\n // We can have a default sort even with sort disabled\r\n sortedColumn = this.querySelector(`thead tr.dg-head-columns th[field=\"${this.options.defaultSort}\"]`);\r\n }\r\n\r\n if (sortedColumn) {\r\n this.sortData(sortedColumn);\r\n } else {\r\n this.renderBody();\r\n }\r\n\r\n this.renderFooter();\r\n }\r\n\r\n /**\r\n * Create table header\r\n * - One row for the column headers\r\n * - One row for the filters\r\n */\r\n renderHeader() {\r\n this.log(\"render header\");\r\n\r\n const thead = this.thead;\r\n this.createColumnHeaders(thead);\r\n this.createColumnFilters(thead);\r\n\r\n if (this.options.resizable && this.plugins.ColumnResizer) {\r\n this.plugins.ColumnResizer.renderResizer(labels.resizeColumn);\r\n }\r\n\r\n dispatch(this, \"headerRendered\");\r\n }\r\n\r\n renderFooter() {\r\n this.log(\"render footer\");\r\n\r\n const tfoot = this.tfoot;\r\n if (!tfoot) return;\n const td = tfoot.querySelector(\"td\");\r\n tfoot.removeAttribute(\"hidden\");\r\n setAttribute(td, \"colspan\", this.columnsLength(true));\r\n tfoot.style.display = \"\";\r\n }\r\n\r\n /**\r\n * Create the column headers based on column definitions and set options\r\n * @param {HTMLTableSectionElement} thead\r\n */\r\n createColumnHeaders(thead) {\r\n // @link https://stackoverflow.com/questions/21064101/understanding-offsetwidth-clientwidth-scrollwidth-and-height-respectively\r\n const availableWidth = this.clientWidth;\r\n const colMaxWidth = Math.round((availableWidth / this.columnsLength(true)) * 2);\r\n\r\n let idx = 0;\r\n let tr;\r\n\r\n // Create row\r\n tr = ce(\"tr\");\r\n this.headerRow = tr;\r\n tr.setAttribute(\"role\", \"row\");\r\n tr.setAttribute(\"aria-rowindex\", \"1\");\r\n tr.setAttribute(\"class\", \"dg-head-columns\");\r\n\r\n // We need a real th from the dom to compute the size\r\n let sampleTh = thead?.querySelector(\"tr.dg-head-columns th\");\n this.log(\"createColumnHeaders - sampleTh\", sampleTh);\r\n if (!sampleTh) {\r\n sampleTh = ce(\"th\");\r\n thead?.querySelector(\"tr\").appendChild(sampleTh);\r\n }\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.createHeaderCol(tr);\r\n }\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n this.plugins.ResponsiveGrid.createHeaderCol(tr);\r\n }\r\n\r\n // Create columns\r\n idx = 0;\r\n let totalWidth = 0;\r\n this.log(\"createColumnHeaders - columns\", this.options.columns);\r\n\r\n for (const column of this.options.columns) {\r\n if (column.attr) {\r\n continue;\r\n }\r\n const colIdx = idx + this.startColIndex();\r\n const th = ce(\"th\");\r\n th.setAttribute(\"scope\", \"col\");\r\n th.setAttribute(\"role\", \"columnheader button\");\r\n th.setAttribute(\"aria-colindex\", `${colIdx}`);\r\n th.setAttribute(\"id\", randstr(\"dg-col-\"));\r\n if (this.options.sort) {\r\n th.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n th.setAttribute(\"field\", column.field);\r\n if (this.plugins.ResponsiveGrid && this.options.responsive) {\r\n setAttribute(th, \"data-responsive\", column.responsive || \"\");\r\n }\r\n // Make sure the header fits (+ add some room for sort icon if necessary)\r\n const computedWidth = getTextWidth(column.title, sampleTh, true) + 20;\r\n th.dataset.minWidth = `${computedWidth}`;\r\n applyColumnDefinition(th, column);\r\n th.tabIndex = 0;\r\n th.textContent = column.title;\r\n\r\n let w = 0;\r\n // Autosize small based on first/last row ?\r\n // Take into account minWidth of the header and max available size based on col numbers\r\n if (this.options.autosize && this.plugins.AutosizeColumn) {\r\n const colAvailableWidth = Math.min(availableWidth - totalWidth, colMaxWidth);\r\n w = this.plugins.AutosizeColumn.computeSize(\r\n th,\r\n column,\r\n Number.parseInt(th.dataset.minWidth),\r\n colAvailableWidth,\r\n );\r\n } else {\r\n w = Math.max(Number.parseInt(th.dataset.minWidth), Number.parseInt(th.getAttribute(\"width\")));\r\n }\r\n\r\n setAttribute(th, \"width\", w);\r\n if (column.hidden) {\r\n th.setAttribute(\"hidden\", \"\");\r\n } else {\r\n totalWidth += w;\r\n }\r\n\r\n // Reorder columns with drag/drop\r\n if (this.options.reorder && this.plugins.DraggableHeaders) {\r\n this.plugins.DraggableHeaders.makeHeaderDraggable(th);\r\n }\r\n\r\n tr.appendChild(th);\r\n idx++;\r\n }\r\n\r\n // There is too much available width, and we want to avoid fixed layout to split remaining amount\r\n if (totalWidth < availableWidth) {\r\n const visibleCols = findAll(tr, \"th:not([hidden],.dg-not-resizable)\");\r\n if (visibleCols.length) {\r\n const lastCol = visibleCols[visibleCols.length - 1];\r\n removeAttribute(lastCol, \"width\");\r\n }\r\n }\r\n\r\n // Actions\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n this.plugins.RowActions.makeActionHeader(tr);\r\n }\r\n\r\n thead?.replaceChild(tr, thead.querySelector(\"tr.dg-head-columns\"));\r\n\r\n // Once columns are inserted, we have an actual dom to query\r\n if (thead && thead.offsetWidth > availableWidth) {\r\n this.log(`adjust width to fix size, ${thead.offsetWidth} > ${availableWidth}`);\r\n const scrollbarWidth = this.offsetWidth - this.clientWidth;\r\n let diff = thead.offsetWidth - availableWidth - scrollbarWidth;\r\n if (this.options.responsive && this.plugins.ResponsiveGrid) {\r\n diff += scrollbarWidth;\r\n }\r\n // Remove diff for columns that can afford it\r\n const thWithWidth = findAll(tr, \"th[width]\");\r\n\r\n for (const th of thWithWidth) {\r\n if (hasClass(th, \"dg-not-resizable\")) {\r\n continue;\r\n }\r\n if (diff <= 0) {\r\n continue;\r\n }\r\n const actualWidth = Number.parseInt(th.getAttribute(\"width\"));\r\n const minWidth = th.dataset.minWidth ? Number.parseInt(th.dataset.minWidth) : 0;\r\n if (actualWidth > minWidth) {\r\n let newWidth = actualWidth - diff;\r\n if (newWidth < minWidth) {\r\n newWidth = minWidth;\r\n }\r\n diff -= actualWidth - newWidth;\r\n setAttribute(th, \"width\", newWidth);\r\n }\r\n }\r\n }\r\n\r\n // Context menu\r\n if (this.options.menu && this.plugins.ContextMenu) {\r\n this.plugins.ContextMenu.attachContextMenu();\r\n }\r\n\r\n // Sort col on click\r\n const rowsWithSort = findAll(tr, \"[aria-sort]\");\r\n for (const sortableRow of rowsWithSort) {\r\n sortableRow.addEventListener(\"click\", () => this.sortData(sortableRow));\r\n }\r\n\r\n this.table && setAttribute(this.table, \"aria-colcount\", this.columnsLength(true));\r\n }\r\n\r\n createColumnFilters(thead) {\r\n let idx = 0;\r\n let tr;\r\n\r\n // Create row for filters\r\n tr = ce(\"tr\");\r\n this.filterRow = tr;\r\n tr.setAttribute(\"role\", \"row\");\r\n tr.setAttribute(\"aria-rowindex\", \"2\");\r\n tr.setAttribute(\"class\", \"dg-head-filters\");\r\n if (!this.options.filter) {\r\n tr.setAttribute(\"hidden\", \"\");\r\n }\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.createFilterCol(tr);\r\n }\r\n if (this.options.responsive && this.plugins.ResponsiveGrid && this.plugins.ResponsiveGrid.hasHiddenColumns()) {\r\n this.plugins.ResponsiveGrid.createFilterCol(tr);\r\n }\r\n\r\n this.log(\"createColumnFilters - columns\", this.options.columns);\r\n for (const column of this.options.columns) {\r\n if (column.attr) {\r\n continue;\r\n }\r\n const colIdx = idx + this.startColIndex();\r\n const relatedTh = thead?.querySelector(`tr.dg-head-columns th[aria-colindex=\"${colIdx}\"]`);\r\n if (!relatedTh) {\r\n console.warn(\"Related th not found\", colIdx);\r\n continue;\r\n }\r\n const th = ce(\"th\");\r\n th.setAttribute(\"aria-colindex\", `${colIdx}`);\r\n\r\n const filter = this.createFilterElement(column, relatedTh);\r\n if (!this.options.filter) {\r\n th.tabIndex = 0;\r\n } else {\r\n filter.tabIndex = 0;\r\n }\r\n\r\n if (column.hidden) {\r\n th.setAttribute(\"hidden\", \"\");\r\n }\r\n\r\n th.appendChild(filter);\r\n tr.appendChild(th);\r\n idx++;\r\n }\r\n\r\n // Actions\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n this.plugins.RowActions.makeActionFilter(tr);\r\n }\r\n\r\n thead?.replaceChild(tr, thead.querySelector(\"tr.dg-head-filters\"));\r\n\r\n if (typeof this.options.filterKeypressDelay !== \"number\" || this.options.filterOnEnter)\r\n this.options.filterKeypressDelay = 0;\r\n\r\n // Filter content by field events\r\n const filteredRows = findAll(tr, this._filterSelector);\r\n for (const el of filteredRows) {\r\n const eventName = /select/i.test(el.tagName) ? \"change\" : \"keyup\";\r\n const eventHandler = debounce((e) => {\r\n const key = e.keyCode || e.key;\r\n const isKeyPressFilter = !this.options.filterOnEnter && !this._excludedKeys.some((k) => k === key);\r\n if (key === 13 || key === \"Enter\" || isKeyPressFilter || e.type === \"change\") {\r\n this.filterData.call(this);\r\n }\r\n }, this.options.filterKeypressDelay);\r\n el.addEventListener(eventName, eventHandler);\r\n }\r\n }\r\n\r\n createFilterElement(column, relatedTh) {\r\n const isSelect = column.filterType === \"select\";\r\n const filter = isSelect ? ce(\"select\") : ce(\"input\");\r\n if (isSelect) {\r\n if (!Array.isArray(column.filterList)) {\r\n // Gets unique values from column records\r\n const uniqueValues = [...new Set((this.data ?? []).map((e) => e[column.field]))]\r\n .filter((v) => v)\r\n .sort();\r\n column.filterList = [column.firstFilterOption || this.defaultColumn.firstFilterOption].concat(\r\n uniqueValues.map((e) => ({ value: e, text: e })),\r\n );\r\n }\r\n\r\n for (const e of column.filterList) {\r\n const opt = ce(\"option\");\r\n opt.value = e.value;\r\n opt.text = e.text;\r\n\r\n if (filter instanceof HTMLSelectElement) {\r\n filter.add(opt);\r\n }\r\n }\r\n } else {\r\n //@ts-ignore\r\n filter.type = \"text\";\r\n filter.inputMode = \"search\";\r\n filter.autocomplete = \"off\";\r\n filter.spellcheck = false;\r\n }\r\n // Allows binding filter to this column\r\n filter.dataset.name = column.field;\r\n filter.id = randstr(\"dg-filter-\");\r\n // Don't use aria-label as it triggers autocomplete\r\n filter.setAttribute(\"aria-labelledby\", relatedTh.getAttribute(\"id\"));\r\n return filter;\r\n }\r\n\r\n /**\r\n * Render the data as rows in tbody\r\n * It will call paginate() at the end\r\n */\r\n renderBody() {\r\n this.log(\"render body\");\r\n let tr;\r\n let td;\r\n let idx;\r\n const tbody = ce(\"tbody\");\r\n\r\n this.data.forEach((item, i) => {\r\n tr = ce(\"tr\");\r\n setAttribute(tr, \"role\", \"row\");\r\n setAttribute(tr, \"hidden\", \"\");\r\n setAttribute(tr, \"aria-rowindex\", i + 1);\r\n tr.tabIndex = 0;\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.createDataCol(tr);\r\n }\r\n if (\r\n this.options.responsive &&\r\n this.plugins.ResponsiveGrid &&\r\n this.plugins.ResponsiveGrid.hasHiddenColumns()\r\n ) {\r\n this.plugins.ResponsiveGrid.createDataCol(tr);\r\n }\r\n\r\n // Expandable\r\n if (this.options.expand) {\r\n tr.classList.add(\"dg-expandable\");\r\n\r\n on(tr, \"click\", (ev) => {\n if (ev.target.matches(this._excludedRowElementSelector)) return;\r\n if (this.plugins.ResponsiveGrid) {\r\n this.plugins.ResponsiveGrid.blockObserver();\r\n }\r\n toggleClass(ev.currentTarget, \"dg-expanded\");\r\n if (this.plugins.ResponsiveGrid) {\r\n this.plugins.ResponsiveGrid.unblockObserver();\r\n }\r\n });\r\n }\r\n\r\n idx = 0;\r\n\r\n for (const column of this.options.columns) {\r\n if (!column) {\r\n console.error(\"Empty column found!\", this.options.columns);\r\n }\r\n // It should be applied as an attr of the row\r\n if (column.attr) {\r\n if (item[column.field]) {\r\n // Special case if we try to write over the class attr\r\n if (column.attr === \"class\") {\r\n addClass(tr, item[column.field]);\r\n } else {\r\n tr.setAttribute(column.attr, item[column.field]);\r\n }\r\n }\r\n return;\r\n }\r\n td = ce(\"td\");\r\n td.setAttribute(\"role\", \"gridcell\");\r\n td.setAttribute(\"aria-colindex\", `${idx}${this.startColIndex()}`);\r\n applyColumnDefinition(td, column);\r\n // This is required for pure css responsive layout\r\n td.setAttribute(\"data-name\", column.title);\r\n td.tabIndex = -1;\r\n\r\n // Inline editing ...\r\n if (column.editable && this.plugins.EditableColumn) {\r\n addClass(td, \"dg-editable-col\");\r\n this.plugins.EditableColumn.makeEditableInput(td, column, item, i);\r\n } else {\r\n // ... or formatting\r\n const v = item[column.field] ?? \"\";\r\n let tv;\r\n // TODO: make this modular\r\n switch (column.transform) {\r\n case \"uppercase\":\r\n tv = v.toUpperCase();\r\n break;\r\n case \"lowercase\":\r\n tv = v.toLowerCase();\r\n break;\r\n default:\r\n tv = v;\r\n break;\r\n }\r\n if (column.format) {\r\n // Only use formatting with values or if defaultFormatValue is set\r\n if (column.defaultFormatValue !== undefined && (tv === \"\" || tv === null)) {\r\n tv = `${column.defaultFormatValue}`;\r\n }\r\n if (typeof column.format === \"string\" && tv) {\r\n td.innerHTML = interpolate(\r\n // @ts-ignore\r\n column.format,\r\n Object.assign(\r\n {\r\n _v: v,\r\n _tv: tv,\r\n },\r\n item,\r\n ),\r\n );\r\n } else if (column.format instanceof Function) {\r\n const val = column.format.call(this, { column, rowData: item, cellData: tv, td, tr });\r\n td.innerHTML = val || tv || v;\r\n }\r\n } else {\r\n td.textContent = tv;\r\n }\r\n }\r\n tr.appendChild(td);\r\n idx++;\r\n }\r\n\r\n // Actions\r\n if (this.options.actions.length && this.plugins.RowActions) {\r\n this.plugins.RowActions.makeActionRow(tr, item);\r\n }\r\n\r\n tbody.appendChild(tr);\r\n\n dispatch(this, \"rowRendered\", { rowData: item, tr });\r\n });\r\n\r\n tbody.setAttribute(\"role\", \"rowgroup\");\r\n\r\n // Keep data empty message\r\n const prev = this.tbody;\r\n prev && tbody.setAttribute(\"data-empty\", prev.getAttribute(\"data-empty\"));\r\n this.table?.replaceChild(tbody, prev);\r\n\r\n if (this.plugins.FixedHeight) {\r\n this.plugins.FixedHeight.createFakeRow();\r\n }\r\n\r\n this.paginate();\r\n\r\n if (this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.shouldSelectAll(tbody);\r\n }\r\n\r\n this.classList.toggle(\"dg-empty\", !this.data.length);\r\n\r\n dispatch(this, \"bodyRendered\");\r\n }\r\n\r\n paginate() {\r\n this.log(\"paginate\");\r\n\r\n const total = this.totalRecords();\r\n const p = this.page || 1;\r\n const tbody = this.tbody;\r\n const tfoot = this.tfoot;\r\n if (!tbody || !tfoot) return;\n const bodyRows = findAll(tbody, \"tr\");\r\n\r\n // Refresh page count in case we added/removed a page\r\n this.pages = this.totalPages();\r\n\r\n let index;\r\n let high = p * this.options.perPage;\r\n let low = high - this.options.perPage + 1;\r\n\r\n if (high > total) {\r\n high = total;\r\n }\r\n if (!total) {\r\n low = 0;\r\n }\r\n\r\n // Display all rows within the set indexes\r\n // For server side paginated grids, we display everything\r\n // since the server is taking care of actual pagination\r\n for (const tr of bodyRows) {\r\n if (this.options.server) {\r\n removeAttribute(tr, \"hidden\");\r\n continue;\r\n }\r\n index = Number(getAttribute(tr, \"aria-rowindex\"));\r\n if (index > high || index < low) {\r\n setAttribute(tr, \"hidden\", \"\");\r\n } else {\r\n removeAttribute(tr, \"hidden\");\r\n }\r\n }\r\n\r\n if (this.options.selectable && this.plugins.SelectableRows) {\r\n this.plugins.SelectableRows.clearCheckboxes(tbody);\r\n }\r\n\r\n // Store default height and update styles if needed\r\n if (this.plugins.FixedHeight) {\r\n this.plugins.FixedHeight.updateFakeRow();\r\n }\r\n\r\n // Enable/disable buttons if shown\r\n if (this.btnFirst) {\r\n this.btnFirst.disabled = this.page <= 1;\r\n this.btnPrev.disabled = this.page <= 1;\r\n this.btnNext.disabled = this.page >= this.pages;\r\n this.btnLast.disabled = this.page >= this.pages;\r\n }\r\n tfoot.querySelector(\".dg-low\").textContent = low.toString();\r\n tfoot.querySelector(\".dg-high\").textContent = high.toString();\r\n tfoot.querySelector(\".dg-total\").textContent = `${this.totalRecords()}`;\r\n tfoot.toggleAttribute(\"hidden\", this.options.autohidePager && this.options.perPage > this.totalRecords());\r\n }\r\n\r\n /**\r\n * @returns {number}\r\n */\r\n totalPages() {\r\n return Math.ceil(this.totalRecords() / this.options.perPage);\r\n }\r\n\r\n /**\r\n * @returns {number}\r\n */\r\n totalRecords() {\r\n if (this.options.server) {\r\n return this.meta?.[this.options.serverParams.metaFilteredKey] || 0;\r\n }\r\n return this.data.length;\r\n }\r\n}\r\n\r\nexport default DataGrid;\r\n", "/** @typedef {import(\"../data-grid\").default} DataGrid */\r\n\r\nclass BasePlugin {\r\n /**\r\n * @param {DataGrid} grid\r\n */\r\n constructor(grid) {\r\n this.grid = grid;\r\n }\r\n\r\n connected() {}\r\n\r\n disconnected() {}\r\n\r\n /**\r\n * Handle events within the plugin\r\n * @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#handling-events\r\n * @param {Event} event\r\n */\r\n handleEvent(event) {\r\n if (this[`on${event.type}`]) {\r\n this[`on${event.type}`](event);\r\n }\r\n }\r\n}\r\n\r\nexport default BasePlugin;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport elementOffset from \"../utils/elementOffset.js\";\r\nimport {\r\n addClass,\r\n dispatch,\r\n findAll,\r\n getAttribute,\r\n hasClass,\r\n off,\r\n on,\r\n removeAttribute,\r\n removeClass,\r\n setAttribute,\r\n} from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Allows to resize columns\r\n */\r\nclass ColumnResizer extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n this.isResizing = false;\r\n }\r\n\r\n /**\r\n * @param {String} resizeLabel\r\n */\r\n renderResizer(resizeLabel) {\r\n const grid = this.grid;\r\n const table = grid.table;\r\n const cols = findAll(grid, \"thead tr.dg-head-columns th\");\r\n\r\n for (const col of cols) {\r\n if (hasClass(col, \"dg-not-resizable\")) {\r\n continue;\r\n }\r\n // Create a resizer element\r\n const resizer = document.createElement(\"div\");\r\n addClass(resizer, \"dg-resizer\");\r\n resizer.ariaLabel = resizeLabel;\r\n\r\n // Add a resizer element to the column\r\n col.appendChild(resizer);\r\n\r\n // Handle resizing\r\n let startX = 0;\r\n let startW = 0;\r\n let remainingSpace = 0;\r\n let max = 0;\r\n\r\n const mouseMoveHandler = (e) => {\r\n if (e.clientX > max) {\r\n return;\r\n }\r\n const newWidth = startW + (e.clientX - startX);\r\n if (col.dataset.minWidth && newWidth > Number.parseInt(col.dataset.minWidth)) {\r\n setAttribute(col, \"width\", newWidth);\r\n }\r\n };\r\n\r\n // When user releases the mouse, remove the existing event listeners\r\n const mouseUpHandler = () => {\r\n grid.log(\"resized column\");\r\n\r\n // Prevent accidental sorting if mouse is not over resize handler\r\n setTimeout(() => {\r\n this.isResizing = false;\r\n }, 0);\r\n\r\n removeClass(resizer, \"dg-resizer-active\");\r\n if (grid.options.reorder) {\r\n col.draggable = true;\r\n }\r\n col.style.overflow = \"hidden\";\r\n\r\n // Remove handlers\r\n off(document, \"mousemove\", mouseMoveHandler);\r\n off(document, \"mouseup\", mouseUpHandler);\r\n\r\n dispatch(grid, \"columnResized\", {\r\n col: getAttribute(col, \"field\"),\r\n width: getAttribute(col, \"width\"),\r\n });\r\n };\r\n\r\n // Otherwise it could sort the col\r\n on(resizer, \"click\", (e) => {\r\n e.stopPropagation();\r\n });\r\n\r\n on(resizer, \"mousedown\", (e) => {\r\n e.stopPropagation();\r\n\r\n this.isResizing = true;\r\n\r\n const target = e.target;\r\n const currentCols = findAll(grid, \"dg-head-columns th\");\r\n const visibleCols = currentCols.filter((col) => {\r\n return !col.hasAttribute(\"hidden\");\r\n });\r\n const columnIndex = visibleCols.findIndex((column) => column === target.parentNode);\r\n grid.log(\"resize column\");\r\n\r\n addClass(resizer, \"dg-resizer-active\");\r\n\r\n // Make sure we don't drag it\r\n removeAttribute(col, \"draggable\");\r\n\r\n // Allow overflow when resizing\r\n col.style.overflow = \"visible\";\r\n\r\n // Show full column height (-1 to avoid scrollbar)\r\n resizer.style.height = `${table.offsetHeight - 1}px`;\r\n\r\n // Register initial data\r\n startX = e.clientX;\r\n startW = col.offsetWidth;\r\n\r\n remainingSpace = (visibleCols.length - columnIndex) * 30;\r\n max = elementOffset(target).left + grid.offsetWidth - remainingSpace;\r\n\r\n // Remove width from next columns to allow auto layout\r\n setAttribute(col, \"width\", startW);\r\n for (let j = 0; j < visibleCols.length; j++) {\r\n if (j > columnIndex) {\r\n removeAttribute(cols[j], \"width\");\r\n }\r\n }\r\n\r\n // Attach handlers\r\n on(document, \"mousemove\", mouseMoveHandler);\r\n on(document, \"mouseup\", mouseUpHandler);\r\n });\r\n }\r\n }\r\n}\r\n\r\nexport default ColumnResizer;\r\n", "/**\r\n * @param {HTMLElement} el\r\n * @param {String} type\r\n * @param {String} prop\r\n * @returns {HTMLElement}\r\n */\r\nexport default function getParentElement(el, type, prop = \"nodeName\") {\r\n let parent = el;\r\n while (parent[prop] !== type) {\r\n parent = parent.parentElement;\r\n }\r\n return parent;\r\n}\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport getParentElement from \"../utils/getParentElement.js\";\r\nimport { find, off, on, removeAttribute, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Create a right click menu on the headers\r\n */\r\nclass ContextMenu extends BasePlugin {\r\n connected() {\r\n /**\r\n * @type {HTMLUListElement}\r\n */\r\n this.menu = this.grid.querySelector(\".dg-menu\");\r\n }\r\n disconnected() {\r\n if (this.grid.headerRow) {\r\n off(this.grid.headerRow, \"contextmenu\", this);\r\n }\r\n }\r\n\r\n attachContextMenu() {\r\n const grid = this.grid;\r\n on(grid.headerRow, \"contextmenu\", this);\r\n }\r\n\r\n onchange(e) {\r\n const grid = this.grid;\r\n const t = e.target;\r\n const field = t.dataset.name;\r\n if (t.checked) {\r\n grid.showColumn(field);\r\n } else {\r\n // Prevent hidding last\r\n if (grid.visibleColumns().length <= 1) {\r\n // Restore checkbox value\r\n t.checked = true;\r\n return;\r\n }\r\n grid.hideColumn(field);\r\n }\r\n grid.fixPage(); //fixes Chrome footer flexbox resize issues that may appear when there is a large number of columns (i.e. more than 10).\r\n }\r\n\r\n oncontextmenu(e) {\r\n e.preventDefault();\r\n const grid = this.grid;\r\n const target = getParentElement(e.target, \"THEAD\");\r\n const menu = this.menu;\r\n const rect = target.getBoundingClientRect();\r\n let x = e.clientX - rect.left;\r\n const y = e.clientY - rect.top;\r\n\r\n menu.style.top = `${y}px`;\r\n menu.style.left = `${x}px`;\r\n\r\n removeAttribute(menu, \"hidden\");\r\n if (x + 150 > rect.width) {\r\n x -= menu.offsetWidth;\r\n menu.style.left = `${x}px`;\r\n }\r\n\r\n const documentClickHandler = (e) => {\r\n if (!menu.contains(e.target)) {\r\n setAttribute(menu, \"hidden\", \"\");\r\n off(document, \"click\", documentClickHandler);\r\n }\r\n };\r\n on(document, \"click\", documentClickHandler);\r\n }\r\n createMenu() {\r\n const grid = this.grid;\r\n const menu = this.menu;\r\n while (menu.lastChild) {\r\n menu.removeChild(menu.lastChild);\r\n }\r\n menu.addEventListener(\"change\", this);\r\n\r\n for (const col of grid.options.columns) {\r\n if (col.attr) {\r\n continue;\r\n }\r\n const li = document.createElement(\"li\");\r\n const label = document.createElement(\"label\");\r\n const checkbox = document.createElement(\"input\");\r\n setAttribute(checkbox, \"type\", \"checkbox\");\r\n setAttribute(checkbox, \"data-name\", col.field);\r\n if (!col.hidden) {\r\n checkbox.checked = true;\r\n }\r\n const text = document.createTextNode(col.title);\r\n\r\n label.appendChild(checkbox);\r\n label.appendChild(text);\r\n\r\n li.appendChild(label);\r\n menu.appendChild(li);\r\n }\r\n }\r\n}\r\n\r\nexport default ContextMenu;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport getParentElement from \"../utils/getParentElement.js\";\r\nimport { dispatch, findAll, getAttribute, on, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Allows to move headers\r\n */\r\nclass DraggableHeaders extends BasePlugin {\r\n /**\r\n * @param {HTMLTableCellElement} th\r\n */\r\n makeHeaderDraggable(th) {\r\n const grid = this.grid;\r\n th.draggable = true;\r\n on(th, \"dragstart\", (e) => {\r\n if (grid.plugins.ColumnResizer?.isResizing && e.preventDefault) {\r\n e.preventDefault();\r\n return;\r\n }\r\n grid.log(\"reorder col\");\r\n e.dataTransfer.effectAllowed = \"move\";\r\n e.dataTransfer.setData(\"text/plain\", e.target.getAttribute(\"aria-colindex\"));\r\n });\r\n on(th, \"dragover\", (e) => {\r\n if (e.preventDefault) {\r\n e.preventDefault();\r\n }\r\n e.dataTransfer.dropEffect = \"move\";\r\n return false;\r\n });\r\n on(th, \"drop\", (e) => {\r\n if (e.stopPropagation) {\r\n e.stopPropagation();\r\n }\r\n const t = e.target;\r\n const target = getParentElement(t, \"TH\");\r\n const index = Number.parseInt(e.dataTransfer.getData(\"text/plain\"));\r\n const targetIndex = Number.parseInt(target.getAttribute(\"aria-colindex\"));\r\n\r\n if (index === targetIndex) {\r\n grid.log(\"reordered col stayed the same\");\r\n return;\r\n }\r\n grid.log(`reordered col from ${index} to ${targetIndex}`);\r\n\r\n const offset = grid.startColIndex();\r\n const tmp = grid.options.columns[index - offset];\r\n grid.options.columns[index - offset] = grid.options.columns[targetIndex - offset];\r\n grid.options.columns[targetIndex - offset] = tmp;\r\n\r\n const swapNodes = (selector, el1) => {\r\n const rowIndex = el1.parentNode.getAttribute(\"aria-rowindex\");\r\n const el2 = grid.querySelector(\r\n `${selector} tr[aria-rowindex=\"${rowIndex}\"] [aria-colindex=\"${targetIndex}\"]`,\r\n );\r\n setAttribute(el1, \"aria-colindex\", targetIndex);\r\n setAttribute(el2, \"aria-colindex\", index);\r\n const newNode = document.createElement(\"th\");\r\n el1.parentNode.insertBefore(newNode, el1);\r\n el2.parentNode.replaceChild(el1, el2);\r\n newNode.parentNode.replaceChild(el2, newNode);\r\n };\r\n\r\n // Swap all rows in header and body\r\n for (const el1 of findAll(grid, `thead th[aria-colindex=\"${index}\"]`)) {\r\n swapNodes(\"thead\", el1);\r\n }\r\n for (const el1 of findAll(grid, `tbody td[aria-colindex=\"${index}\"]`)) {\r\n swapNodes(\"tbody\", el1);\r\n }\r\n\r\n // Updates the columns\r\n grid.options.columns = findAll(grid, \"thead tr.dg-head-columns th[field]\").map((th) =>\r\n grid.options.columns.find((c) => c.field === getAttribute(th, \"field\")),\r\n );\r\n\r\n dispatch(grid, \"columnReordered\", {\r\n col: tmp.field,\r\n from: index,\r\n to: targetIndex,\r\n });\r\n return false;\r\n });\r\n }\r\n}\r\n\r\nexport default DraggableHeaders;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\n\r\n/**\r\n * Allows to paginate with horizontal swipe motions\r\n */\r\nclass TouchSupport extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n this.touch = null;\r\n }\r\n connected() {\r\n const grid = this.grid;\r\n grid.addEventListener(\"touchstart\", this, { passive: true });\r\n grid.addEventListener(\"touchmove\", this, { passive: true });\r\n }\r\n\r\n disconnected() {\r\n const grid = this.grid;\r\n grid.removeEventListener(\"touchstart\", this);\r\n grid.removeEventListener(\"touchmove\", this);\r\n }\r\n\r\n ontouchstart(e) {\r\n this.touch = e.touches[0];\r\n }\r\n\r\n ontouchmove(e) {\r\n if (!this.touch) {\r\n return;\r\n }\r\n const grid = this.grid;\r\n const xDiff = this.touch.clientX - e.touches[0].clientX;\r\n const yDiff = this.touch.clientY - e.touches[0].clientY;\r\n\r\n if (Math.abs(xDiff) > Math.abs(yDiff)) {\r\n if (xDiff > 0) {\r\n grid.getNext();\r\n } else {\r\n grid.getPrev();\r\n }\r\n }\r\n this.touch = null;\r\n }\r\n}\r\n\r\nexport default TouchSupport;\r\n", "// @ts-nocheck\r\nimport BasePlugin from \"../core/base-plugin.js\";\r\nimport { dispatch, findAll, hasClass, setAttribute, $, $$ } from \"../utils/shortcuts.js\";\r\n\r\nconst SELECTABLE_CLASS = \"dg-selectable\";\r\nconst SELECT_ALL_CLASS = \"dg-select-all\";\r\nconst CHECKBOX_CLASS = \"form-check-input\"; //bs5\n\r\n/**\r\n * Allows to select rows\r\n */\r\nclass SelectableRows extends BasePlugin {\n #cbSelector = `tbody tr${this.visibleOnly ? \":not([hidden])\" : \"\"} .${SELECTABLE_CLASS} input[type=checkbox]`;\n #inputSelector = `tbody .${SELECTABLE_CLASS} input`;\n\r\n disconnected() {\r\n if (this.selectAll) {\r\n this.selectAll.removeEventListener(\"change\", this);\r\n }\r\n }\n\n get isSingleSelect() {\n return this.grid.options.singleSelect;\n }\n\n get visibleOnly() {\n return this.grid.options.selectVisibleOnly;\n }\n\r\n /**\n * Get selected rows or fields.\n * Returns full rows, a single field's values, or objects with specified fields.\n * In single select mode, returns a single item.\n * @param {...string} keys Field names to select.\n * @returns {Array|Object} Selected data.\n */\n getSelection(...keys) {\n const grid = this.grid;\n const selectedData = [];\n\n const inputs = findAll(grid, `${this.#inputSelector}:checked`);\n\n for (const checkbox of inputs) {\n const idx = Number.parseInt(checkbox.dataset.id);\n const item = grid.data[idx - 1];\n if (!item) {\n console.warn(`Item ${idx} not found`);\n continue;\n }\n if (keys.length === 0) {\n selectedData.push(item);\n } else if (keys.length === 1) {\n selectedData.push(item[keys[0]]);\n } else {\n selectedData.push(Object.fromEntries(keys.map(k => [k, item[k]])));\n }\n }\n return this.isSingleSelect ? selectedData[0] ?? {} : selectedData;\n }\r\n\r\n /**\r\n * Uncheck box if hidden and visible only\r\n * @param {HTMLTableSectionElement} tbody\r\n */\r\n clearCheckboxes(tbody) {\r\n const grid = this.grid;\r\n if (!grid.options.selectVisibleOnly) {\r\n return;\r\n }\r\n const inputs = findAll(tbody, `tr[hidden] .${SELECTABLE_CLASS} input`);\r\n for (const input of inputs) {\r\n input.checked = false;\n if (this.isSingleSelect) {\n input.dataset.toggled = \"false\"; // Reset toggled state for radio buttons\n }\r\n }\r\n this.selectAll.checked = false;\n }\r\n\r\n colIndex() {\r\n return this.grid.startColIndex() - 2;\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createHeaderCol(tr) {\r\n const th = document.createElement(\"th\");\r\n setAttribute(th, \"scope\", \"col\");\r\n setAttribute(th, \"role\", \"columnheader button\");\r\n setAttribute(th, \"aria-colindex\", this.colIndex());\r\n th.classList.add(...[SELECTABLE_CLASS, \"dg-not-resizable\", \"dg-not-sortable\"]);\r\n th.tabIndex = 0;\r\n\n this.selectAll = document.createElement(\"input\");\r\n this.selectAll.type = \"checkbox\";\r\n this.selectAll.classList.add(SELECT_ALL_CLASS);\r\n this.selectAll.classList.add(CHECKBOX_CLASS);\r\n this.selectAll.addEventListener(\"change\", this);\r\n\r\n const label = document.createElement(\"label\");\n label.hidden = this.isSingleSelect;\r\n label.appendChild(this.selectAll);\r\n\r\n th.appendChild(label);\n\r\n th.setAttribute(\"width\", \"40\");\r\n tr.appendChild(th);\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createFilterCol(tr) {\r\n const th = document.createElement(\"th\");\r\n setAttribute(th, \"role\", \"columnheader button\");\r\n setAttribute(th, \"aria-colindex\", this.colIndex());\r\n th.classList.add(SELECTABLE_CLASS);\r\n th.tabIndex = 0;\r\n\r\n tr.appendChild(th);\r\n }\r\n\r\n /**\r\n * Handles the selectAll checkbox when any other .dg-selectable checkbox is checked on table body.\r\n * It should check selectAll if all is checked\r\n * It should uncheck selectAll if any is unchecked\r\n * @param {HTMLTableSectionElement} tbody\r\n */\r\n shouldSelectAll(tbody) {\r\n if (!this.selectAll) {\r\n return;\r\n }\r\n // Delegate listener for change events on input checkboxes\r\n tbody.addEventListener(\"change\", this);\r\n // Make sure state is up to date\r\n tbody.dispatchEvent(new Event(\"change\"));\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createDataCol(tr) {\r\n // Create col\r\n const td = document.createElement(\"td\");\r\n setAttribute(td, \"role\", \"gridcell button\");\r\n setAttribute(td, \"aria-colindex\", this.colIndex());\r\n td.classList.add(SELECTABLE_CLASS);\r\n\r\n // Create input\r\n const input = document.createElement(\"input\");\r\n // Alias row id for easy retrieval in getSelection\r\n input.dataset.id = tr.getAttribute(\"aria-rowindex\");\r\n input.type = this.isSingleSelect ? \"radio\" : \"checkbox\";\r\n input.classList.add(CHECKBOX_CLASS);\n if (this.isSingleSelect) {\n input.name = \"dg-row-select\";\n input.dataset.toggled = \"false\";\n }\n\r\n // Label need to take full space thanks to css to make the whole cell clickable\r\n const label = document.createElement(\"label\");\r\n label.classList.add(\"dg-clickable-cell\");\n\r\n label.appendChild(input);\r\n td.appendChild(label);\r\n\r\n // Prevent unwanted click behaviour on row\r\n label.addEventListener(\"click\", this);\r\n\r\n tr.appendChild(td);\r\n }\r\n\r\n /**\r\n * @param {Event} e\r\n */\r\n onclick(e) {\n if (!this.isSingleSelect) return e.stopPropagation();\n\n // Implements radio button toggle behaviour for selecting and unselecting a row\n const el = e.target,\n unchecked = el.dataset.toggled !== \"true\";\n unchecked && $$(`${this.#cbSelector.replace(\"checkbox\", \"radio\")}`, this.grid)?.forEach(r => {\n // Uncheck all other radios in the same group and reset their data-toggled\n if (r.name === el.name && r !== el) r.checked = r.dataset.toggled = false;\n });\r\n el.checked = el.dataset.toggled = unchecked;\n !unchecked && this.onchange(e); // Fires rowsSelected event\r\n }\r\n\r\n /**\r\n * Handle change event on select all or any select checkbox in the table body\r\n * @param {import(\"../utils/shortcuts.js\").FlexibleEvent} e\r\n */\r\n onchange(e) {\n const el = e.target, grid = this.grid;\n if (hasClass(e.target, SELECT_ALL_CLASS)) {\n findAll(grid, this.#inputSelector).forEach(cb => {\n if (!this.visibleOnly || cb.offsetWidth) cb.checked = this.selectAll.checked;\n });\n } else if (el.matches(this.#cbSelector)) {\n if (!el.closest(`.${SELECTABLE_CLASS}`)) return;\n const totalCheckboxes = findAll(grid, this.#cbSelector);\n this.selectAll.checked = totalCheckboxes.every(n => n.checked);\n }\n if (el.matches(`.${SELECT_ALL_CLASS},${this.#inputSelector}`)) {\r\n dispatch(el, \"rowsSelected\", {\r\n selection: grid.getSelection()\n }, true);\r\n }\n }\r\n}\r\n\r\nexport default SelectableRows;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport { setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Support for fixed table height\r\n *\r\n * We should add a fake row to push the footer down in case we don't have enough rows\r\n */\r\nclass FixedHeight extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n\r\n this.hasFixedHeight = false;\r\n // If we have a fixed height, make sure we have overflowY set\r\n if (grid.style.height) {\r\n grid.style.overflowY = \"auto\";\r\n this.hasFixedHeight = true;\r\n }\r\n }\r\n\r\n /**\r\n */\r\n createFakeRow() {\r\n const grid = this.grid;\r\n const tbody = grid.querySelector(\"tbody\");\r\n const tr = document.createElement(\"tr\");\r\n setAttribute(tr, \"role\", \"row\");\r\n setAttribute(tr, \"hidden\", \"\");\r\n tr.classList.add(\"dg-fake-row\");\r\n tr.tabIndex = 0;\r\n tbody?.appendChild(tr);\r\n }\r\n\r\n get fakeRow() {\r\n return this.grid.querySelector(\".dg-fake-row\");\r\n }\r\n\r\n /**\r\n * On last page, use a fake row to push footer down\r\n */\r\n updateFakeRow() {\r\n const grid = this.grid;\r\n const fakeRow = this.fakeRow;\r\n if (!fakeRow) {\r\n return;\r\n }\r\n\r\n // We don't need a fake row if we display everything\r\n if (grid.options.perPage > grid.totalRecords()) {\r\n return;\r\n }\r\n // We are not on last page\r\n if (grid.page !== grid.totalPages()) {\r\n return;\r\n }\r\n if (!grid.options.autoheight) {\r\n return;\r\n }\r\n // Find remaining missing height\r\n const max = grid.options.perPage * grid.rowHeight;\r\n const visibleRows = grid.querySelectorAll(\"tbody tr:not([hidden])\").length;\r\n const fakeHeight = visibleRows > 1 ? max - visibleRows * grid.rowHeight : max;\r\n if (fakeHeight > 0) {\r\n setAttribute(fakeRow, \"height\", fakeHeight);\r\n fakeRow.removeAttribute(\"hidden\");\r\n } else {\r\n fakeRow.removeAttribute(\"height\");\r\n }\r\n }\r\n}\r\n\r\nexport default FixedHeight;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport getTextWidth from \"../utils/getTextWidth.js\";\r\nimport { getAttribute, hasAttribute, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Allows to resize columns\r\n */\r\nclass AutosizeColumn extends BasePlugin {\r\n /**\r\n * Autosize col based on column data\r\n * @param {HTMLTableCellElement} th\r\n * @param {import(\"../data-grid\").Column} column\r\n * @param {Number} min\r\n * @param {Number} max\r\n * @returns {Number}\r\n */\r\n computeSize(th, column, min, max) {\r\n const grid = this.grid;\r\n if (hasAttribute(th, \"width\")) {\r\n return getAttribute(th, \"width\");\r\n }\r\n if (!grid.data.length) {\r\n return;\r\n }\r\n const firstVal = grid.data[0];\r\n const lastVal = grid.data[grid.data.length - 1];\r\n let v = firstVal[column.field] ? firstVal[column.field].toString() : \"\";\r\n const v2 = lastVal[column.field] ? lastVal[column.field].toString() : \"\";\r\n if (v2.length > v.length) {\r\n v = v2;\r\n }\r\n let width = 0;\r\n if (v.length <= 6) {\r\n width = min;\r\n } else if (v.length > 50) {\r\n width = max;\r\n } else {\r\n // Add some extra room to have some spare space\r\n width = getTextWidth(`${v}0000`, th);\r\n }\r\n if (width > max) {\r\n width = max;\r\n }\r\n if (width < min) {\r\n width = min;\r\n }\r\n setAttribute(th, \"width\", width);\r\n return width;\r\n }\r\n}\r\n\r\nexport default AutosizeColumn;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport debounce from \"../utils/debounce.js\";\r\nimport {\r\n addClass,\r\n ce,\r\n find,\r\n findAll,\r\n hasClass,\r\n insertAfter,\r\n removeAttribute,\r\n removeClass,\r\n setAttribute,\r\n} from \"../utils/shortcuts.js\";\r\n\r\nconst RESPONSIVE_CLASS = \"dg-responsive\";\r\n\r\nlet obsTo;\r\n\r\n/**\r\n * @param {Array} list\r\n * @returns {Array}\r\n */\r\nfunction sortByPriority(list) {\r\n return list.sort((a, b) => {\r\n const v1 = Number.parseInt(a.dataset.responsive) || 1;\r\n const v2 = Number.parseInt(b.dataset.responsive) || 1;\r\n return v2 - v1;\r\n });\r\n}\r\n\r\n/**\r\n * @type {ResizeObserverCallback}\r\n */\r\n//@ts-ignore\r\nconst callback = debounce((entries) => {\r\n for (const entry of entries) {\r\n /**\r\n * @type {import(\"../data-grid\").default}\r\n */\r\n // @ts-ignore\r\n const grid = entry.target;\r\n const table = grid.table;\r\n if (grid.plugins.ResponsiveGrid.observerBlocked) {\r\n return;\r\n }\r\n // check inlineSize (width) and not blockSize (height)\r\n const contentBoxSize = Array.isArray(entry.contentBoxSize) ? entry.contentBoxSize[0] : entry.contentBoxSize;\r\n const size = Number.parseInt(contentBoxSize.inlineSize);\r\n const tableWidth = table.offsetWidth;\r\n const realTableWidth = findAll(grid.headerRow, \"th\").reduce((result, th) => {\r\n return result + th.offsetWidth;\r\n }, 0);\r\n const diff = (realTableWidth || tableWidth) - size - 1;\r\n const minWidth = 50;\r\n const prevAction = grid.plugins.ResponsiveGrid.prevAction;\r\n // We have an array with the columns to show/hide are in order, most important first\r\n const headerCols = sortByPriority(\r\n findAll(grid.headerRow, \"th[field]\")\r\n .reverse() // Order takes precedence if no priority is set\r\n .filter((col) => {\r\n // Leave out unresponsive columns\r\n return col.dataset.responsive !== \"0\";\r\n }),\r\n );\r\n let changed = false;\r\n\r\n grid.log(`table is ${tableWidth}/${realTableWidth} and available size is ${size}. Diff: ${diff}`);\r\n\r\n // The table is too big when diff has a high value, otherwise it will be like -1 or -2\r\n if (diff > 0) {\r\n if (prevAction === \"show\") {\r\n return;\r\n }\r\n grid.plugins.ResponsiveGrid.prevAction = \"hide\";\r\n let remaining = diff;\r\n let cols = headerCols.filter((col) => {\r\n return !col.hasAttribute(\"hidden\") && col.hasAttribute(\"data-responsive\");\r\n });\r\n if (cols.length === 0) {\r\n cols = headerCols.filter((col) => {\r\n return !col.hasAttribute(\"hidden\");\r\n });\r\n // Always keep one column\r\n if (cols.length === 1) {\r\n return;\r\n }\r\n }\r\n\r\n for (const col of cols) {\r\n if (remaining < 0) {\r\n continue;\r\n }\r\n\r\n const colWidth = col.offsetWidth;\r\n const field = col.getAttribute(\"field\");\r\n if (!field) {\r\n continue;\r\n }\r\n col.dataset.baseWidth = `${col.offsetWidth}`;\r\n\r\n grid.hideColumn(field, false);\r\n grid.setColProp(field, \"responsiveHidden\", true);\r\n changed = true;\r\n\r\n remaining -= colWidth;\r\n remaining = Math.round(remaining);\r\n }\r\n } else {\r\n if (prevAction === \"hide\") {\r\n return;\r\n }\r\n grid.plugins.ResponsiveGrid.prevAction = \"show\";\r\n\r\n const requiredWidth =\r\n headerCols\r\n .filter((col) => {\r\n return !col.hasAttribute(\"hidden\");\r\n })\r\n .reduce((result, col) => {\r\n const width = col.dataset.minWidth ? Number.parseInt(col.dataset.minWidth) : col.offsetWidth;\r\n return result + width;\r\n }, 0) + minWidth; // Add an offset so that inserting column is smoother\r\n\r\n // Compute available width to insert columns\r\n let remaining = size - requiredWidth;\r\n // Do we have any hidden column that we can restore ?\r\n const filteredHeaderCols = headerCols\r\n .slice()\r\n .reverse() // Reverse the array to restore the columns in the proper order\r\n .filter((col) => {\r\n return col.hasAttribute(\"hidden\");\r\n });\r\n\r\n for (const col of filteredHeaderCols) {\r\n if (remaining < minWidth) {\r\n continue;\r\n }\r\n const colWidth = Number.parseInt(col.dataset.minWidth);\r\n\r\n // We need to have enough space to restore it\r\n if (colWidth > remaining) {\r\n remaining = -1; // break loop to keep restoring in order\r\n continue;\r\n }\r\n\r\n const field = col.getAttribute(\"field\");\r\n if (!field) {\r\n continue;\r\n }\r\n\r\n grid.showColumn(field, false);\r\n grid.setColProp(field, \"responsiveHidden\", false);\r\n changed = true;\r\n\r\n remaining -= colWidth;\r\n remaining = Math.round(remaining);\r\n }\r\n }\r\n\r\n // Check footer\r\n const footer = find(grid.table, \"tfoot\");\r\n const realFooterWidth = findAll(grid.table, \".dg-footer > div\").reduce((result, div) => {\r\n return result + div.offsetWidth;\r\n }, 0);\r\n const availableFooterWidth = footer.offsetWidth - realFooterWidth;\r\n if (realFooterWidth > size) {\r\n addClass(footer, \"dg-footer-compact\");\r\n } else if (availableFooterWidth > 250) {\r\n removeClass(footer, \"dg-footer-compact\");\r\n }\r\n if (changed) {\r\n grid.renderTable();\r\n }\r\n // Prevent resize loop\r\n setTimeout(() => {\r\n grid.plugins.ResponsiveGrid.prevAction = null;\r\n }, 1000);\r\n grid.table.style.visibility = \"visible\";\r\n }\r\n}, 100);\r\nconst resizeObserver = new ResizeObserver(callback);\r\n\r\n/**\r\n * Responsive data grid\r\n */\r\nclass ResponsiveGrid extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n\r\n this.observerBlocked = false;\r\n this.prevAction = null;\r\n }\r\n\r\n connected() {\r\n if (this.grid.options.responsive) {\r\n this.observe();\r\n }\r\n }\r\n\r\n disconnected() {\r\n this.unobserve();\r\n }\r\n\r\n observe() {\r\n if (!this.grid.options.responsive) {\r\n return;\r\n }\r\n resizeObserver.observe(this.grid);\r\n this.grid.style.display = \"block\"; // Otherwise resize doesn't happen\r\n this.grid.style.overflowX = \"hidden\"; // Prevent scrollbars from appearing\r\n }\r\n\r\n unobserve() {\r\n resizeObserver.unobserve(this.grid);\r\n this.grid.style.display = \"unset\";\r\n this.grid.style.overflowX = \"unset\";\r\n }\r\n\r\n blockObserver() {\r\n this.observerBlocked = true;\r\n if (obsTo) {\r\n clearTimeout(obsTo);\r\n }\r\n }\r\n\r\n unblockObserver() {\r\n obsTo = setTimeout(() => {\r\n this.observerBlocked = false;\r\n }, 200); // more than debounce\r\n }\r\n\r\n /**\r\n * @returns {Boolean}\r\n */\r\n hasHiddenColumns() {\r\n let flag = false;\r\n\r\n for (const col of this.grid.options.columns) {\r\n if (col.responsiveHidden) {\r\n flag = true;\r\n }\r\n }\r\n return flag;\r\n }\r\n\r\n colIndex() {\r\n return this.grid.startColIndex() - 1;\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createHeaderCol(tr) {\r\n if (!this.grid.options.responsiveToggle) {\r\n return;\r\n }\r\n const th = ce(\"th\", tr);\r\n setAttribute(th, \"scope\", \"col\");\r\n setAttribute(th, \"role\", \"columnheader button\");\r\n setAttribute(th, \"aria-colindex\", this.colIndex());\r\n setAttribute(th, \"width\", \"40\");\r\n th.classList.add(...[`${RESPONSIVE_CLASS}-toggle`, \"dg-not-resizable\", \"dg-not-sortable\"]);\r\n th.tabIndex = 0;\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createFilterCol(tr) {\r\n if (!this.grid.options.responsiveToggle) {\r\n return;\r\n }\r\n const th = ce(\"th\", tr);\r\n setAttribute(th, \"role\", \"columnheader button\");\r\n setAttribute(th, \"aria-colindex\", this.colIndex());\r\n th.classList.add(`${RESPONSIVE_CLASS}-toggle`);\r\n th.tabIndex = 0;\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n createDataCol(tr) {\r\n if (!this.grid.options.responsiveToggle) {\r\n return;\r\n }\r\n // Create col\r\n const td = document.createElement(\"td\");\r\n setAttribute(td, \"role\", \"gridcell button\");\r\n setAttribute(td, \"aria-colindex\", this.colIndex());\r\n td.classList.add(`${RESPONSIVE_CLASS}-toggle`);\r\n\r\n // Create icon\r\n td.innerHTML = `\r\n \r\n \r\n\r\n\r\n \r\n
`;\r\n tr.appendChild(td);\r\n\r\n td.addEventListener(\"click\", this);\r\n td.addEventListener(\"mousedown\", this);\r\n }\r\n\r\n computeLabelWidth() {\r\n let idealWidth = 0;\r\n let consideredCol = 0;\r\n while (idealWidth < 120) {\r\n consideredCol++;\r\n const hCol = find(this.grid, `.dg-head-columns th[aria-colindex=\"${consideredCol}\"]`);\r\n if (hCol) {\r\n idealWidth += hCol.offsetWidth;\r\n } else {\r\n break;\r\n }\r\n }\r\n return idealWidth;\r\n }\r\n\r\n /**\r\n * @param {Event} ev\r\n */\r\n onmousedown(ev) {\r\n // Avoid selection through double click\r\n ev.preventDefault();\r\n }\r\n\r\n /**\r\n * @param {Event} ev\r\n */\r\n onclick(ev) {\r\n // Prevent expandable\r\n ev.stopPropagation();\r\n\r\n // target is the element that triggered the event (e.g., the user clicked on)\r\n // currentTarget is the element that the event listener is attached to.\r\n\r\n /**\r\n * @type {HTMLTableRowElement}\r\n */\r\n //@ts-ignore\r\n const td = ev.currentTarget;\r\n const tr = td.parentElement;\r\n const open = find(td, `.${RESPONSIVE_CLASS}-open`);\r\n const close = find(td, `.${RESPONSIVE_CLASS}-close`);\r\n\r\n this.blockObserver();\r\n\r\n const isExpanded = hasClass(tr, `${RESPONSIVE_CLASS}-expanded`);\r\n if (isExpanded) {\r\n removeClass(tr, `${RESPONSIVE_CLASS}-expanded`);\r\n open.style.display = \"unset\";\r\n close.style.display = \"none\";\r\n\r\n // Move back rows and cleanup row\r\n const childRow = tr.nextElementSibling;\r\n const hiddenCols = findAll(childRow, `.${RESPONSIVE_CLASS}-hidden`);\r\n\r\n for (const col of hiddenCols) {\r\n // We don't really need to care where we insert them since we are going to redraw anyway\r\n tr.appendChild(col);\r\n setAttribute(col, \"hidden\");\r\n }\r\n\r\n childRow.parentElement.removeChild(childRow);\r\n } else {\r\n addClass(tr, `${RESPONSIVE_CLASS}-expanded`);\r\n open.style.display = \"none\";\r\n close.style.display = \"unset\";\r\n\r\n // Create a child row and move rows into it\r\n const childRow = ce(\"tr\");\r\n insertAfter(childRow, tr);\r\n addClass(childRow, `${RESPONSIVE_CLASS}-child-row`);\r\n\r\n const childRowTd = ce(\"td\", childRow);\r\n setAttribute(childRowTd, \"colspan\", this.grid.columnsLength(true));\r\n\r\n const childTable = ce(\"table\", childRowTd);\r\n addClass(childTable, `${RESPONSIVE_CLASS}-table`);\r\n\r\n const hiddenCols = findAll(tr, `.${RESPONSIVE_CLASS}-hidden`);\r\n const idealWidth = this.computeLabelWidth();\r\n\r\n for (const col of hiddenCols) {\r\n const childTableRow = ce(\"tr\", childTable);\r\n\r\n // Add label\r\n const label = col.dataset.name;\r\n const labelCol = ce(\"th\", childTableRow);\r\n // It looks much better when aligned with an actual col\r\n labelCol.style.width = `${idealWidth}px`;\r\n labelCol.innerHTML = label;\r\n\r\n // Add actual row\r\n childTableRow.appendChild(col);\r\n removeAttribute(col, \"hidden\");\r\n }\r\n }\r\n\r\n this.unblockObserver();\r\n }\r\n}\r\n\r\nexport default ResponsiveGrid;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport interpolate from \"../utils/interpolate.js\";\r\nimport { dispatch, on, setAttribute } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Add action on rows\r\n */\r\nclass RowActions extends BasePlugin {\r\n /**\r\n * @returns {Boolean}\r\n */\r\n hasActions() {\r\n return this.grid.options.actions.length > 0;\r\n }\r\n\r\n /**\r\n *\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n makeActionHeader(tr) {\r\n const actionsTh = document.createElement(\"th\");\r\n setAttribute(actionsTh, \"role\", \"columnheader button\");\r\n setAttribute(actionsTh, \"aria-colindex\", this.grid.columnsLength(true));\r\n actionsTh.classList.add(...[\"dg-actions\", \"dg-not-sortable\", \"dg-not-resizable\", this.actionClass]);\r\n actionsTh.tabIndex = 0;\r\n tr.appendChild(actionsTh);\r\n }\r\n\r\n /**\r\n *\r\n * @param {HTMLTableRowElement} tr\r\n */\r\n makeActionFilter(tr) {\r\n const actionsTh = document.createElement(\"th\");\r\n actionsTh.setAttribute(\"role\", \"columnheader button\");\r\n setAttribute(actionsTh, \"aria-colindex\", this.grid.columnsLength(true));\r\n actionsTh.classList.add(...[\"dg-actions\", this.actionClass]);\r\n actionsTh.tabIndex = 0;\r\n tr.appendChild(actionsTh);\r\n }\r\n\r\n /**\r\n * @param {HTMLTableRowElement} tr\r\n * @param {Object} item\r\n */\r\n makeActionRow(tr, item) {\r\n const labels = this.grid.labels;\r\n const td = document.createElement(\"td\");\r\n setAttribute(td, \"role\", \"gridcell\");\r\n setAttribute(td, \"aria-colindex\", this.grid.columnsLength(true));\r\n td.classList.add(...[\"dg-actions\", this.actionClass]);\r\n td.tabIndex = 0;\r\n\r\n // Add menu toggle\r\n const actionsToggle = document.createElement(\"button\");\r\n actionsToggle.classList.add(\"dg-actions-toggle\");\r\n actionsToggle.innerHTML = \"\u2630\";\r\n td.appendChild(actionsToggle);\r\n on(actionsToggle, \"click\", (ev) => {\r\n ev.stopPropagation();\r\n ev.target.parentElement.classList.toggle(\"dg-actions-expand\");\r\n });\r\n\r\n for (const action of this.grid.options.actions) {\r\n const button = document.createElement(\"button\");\r\n if (action.html) {\r\n button.innerHTML = action.html;\r\n } else {\r\n button.innerText = action.title ?? action.name;\r\n }\r\n if (action.title) {\r\n button.title = action.title;\r\n }\r\n if (action.url) {\r\n button.type = \"submit\";\r\n button.formAction = interpolate(action.url, item);\r\n }\r\n if (action.class) {\r\n button.classList.add(...action.class.split(\" \"));\r\n }\r\n const actionHandler = (ev) => {\r\n ev.stopPropagation();\r\n if (action.confirm) {\r\n const c = confirm(labels.areYouSure);\r\n if (!c) {\r\n ev.preventDefault();\r\n return;\r\n }\r\n }\r\n dispatch(this.grid, \"action\", {\r\n data: item,\r\n action: action.name,\r\n });\r\n };\r\n button.addEventListener(\"click\", actionHandler);\r\n td.appendChild(button);\r\n\r\n // Row action\r\n if (action.default) {\r\n tr.classList.add(\"dg-actionable\");\r\n tr.addEventListener(\"click\", actionHandler);\r\n }\r\n }\r\n\r\n tr.appendChild(td);\r\n }\r\n\r\n get actionClass() {\r\n if (this.grid.options.actions.length < 3 && !this.grid.options.collapseActions) {\r\n return `dg-actions-${this.grid.options.actions.length}`;\r\n }\r\n return \"dg-actions-more\";\r\n }\r\n}\r\n\r\nexport default RowActions;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport { dispatch } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Make editable inputs in rows\r\n */\r\nclass EditableColumn extends BasePlugin {\r\n /**\r\n *\r\n * @param {HTMLTableCellElement} td\r\n * @param {import(\"../data-grid\").Column} column\r\n * @param {Object} item\r\n * @param {number} i\r\n */\r\n makeEditableInput(td, column, item, i) {\r\n const gridId = this.grid.getAttribute(\"id\");\r\n const input = document.createElement(\"input\");\r\n input.type = column.editableType || \"text\";\r\n if (input.type === \"email\") {\r\n input.inputMode = \"email\";\r\n }\r\n if (input.type === \"decimal\") {\r\n input.type = \"text\";\r\n input.inputMode = \"decimal\";\r\n }\r\n input.autocomplete = \"off\";\r\n input.spellcheck = false;\r\n input.tabIndex = 0;\r\n input.classList.add(\"dg-editable\");\r\n input.name = `${gridId.replace(\"-\", \"_\")}[${i + 1}][${column.field}]`;\r\n input.value = item[column.field];\r\n input.dataset.field = column.field;\r\n\r\n // Prevent row action\r\n input.addEventListener(\"click\", (ev) => ev.stopPropagation());\r\n // Enter validates edit\r\n input.addEventListener(\"keypress\", (ev) => {\r\n if (ev.type === \"keypress\") {\r\n const key = ev.keyCode || ev.key;\r\n if (key === 13 || key === \"Enter\") {\r\n input.blur();\r\n ev.preventDefault();\r\n }\r\n }\r\n });\r\n // Save on blur\r\n input.addEventListener(\"blur\", () => {\r\n // Only fire on update\r\n if (input.value === item[input.dataset.field]) {\r\n return;\r\n }\r\n // Update underlying data\r\n item[input.dataset.field] = input.value;\r\n // Notify\r\n dispatch(this.grid, \"edit\", {\r\n data: item,\r\n value: input.value,\r\n });\r\n });\r\n td.appendChild(input);\r\n }\r\n}\r\n\r\nexport default EditableColumn;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport { $ } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * Adds an element for showing a spinning icon on grid loading.\r\n */\r\nclass SpinnerSupport extends BasePlugin {\n connected() {\n // Inserts spinner\r\n if (this.grid.options.spinnerClass && this.grid.plugins.SpinnerSupport) {\r\n this.add();\r\n }\r\n }\n\r\n /**\r\n * Adds a spinner element with its associated css styles.\r\n */\r\n add() {\r\n const grid = this.grid;\r\n const classes = grid.options.spinnerClass;\r\n if (!classes) {\r\n return;\r\n }\r\n const cls = classes\r\n .split(\" \")\r\n .map((e) => `.${e}`)\r\n .join(\"\");\r\n\r\n const template = `\r\n\r\n`;\r\n if (!$(\"#dg-styles\")) {\r\n const styleParent = $(\"head\") ?? $(\"body\");\r\n const position = /head/i.test(styleParent.tagName) ? \"beforeend\" : \"afterbegin\";\r\n styleParent.insertAdjacentHTML(position, template);\r\n }\r\n !$(`i${cls}`, grid) && grid.insertAdjacentHTML(\"afterbegin\", ``);\r\n }\r\n}\r\n\r\nexport default SpinnerSupport;\r\n", "import BasePlugin from \"../core/base-plugin.js\";\r\nimport { findAll } from \"../utils/shortcuts.js\";\r\n\r\n/**\r\n * @typedef GridState\r\n * @property {Object} meta\r\n * @property {Number} pages\r\n * @property {Number} page\r\n * @property {Number} perPage\r\n * @property {Object} filters\r\n * @property {Array} columns\r\n * @property {String} sort\r\n * @property {String} sortDir\r\n * @property {Number} scrollTo\r\n */\r\n\r\nclass SaveState extends BasePlugin {\r\n constructor(grid) {\r\n super(grid);\r\n this.cachedState = null;\r\n this.isFilterSortSet = false;\r\n this.isDataLoaded = false;\r\n this.isScrolled = false;\r\n this.log(\"Init\");\r\n }\r\n\r\n async connected() {\r\n this.log(\"connected\");\r\n const grid = this.grid;\r\n\r\n this.log(grid.options);\n\r\n if (!grid.options.saveState) {\r\n this.log(\"disabled\");\r\n return;\r\n }\r\n\r\n this.log(\"enabled\");\r\n\r\n const cachedState = this._getState();\r\n if (cachedState) {\n const waitForColumns = async () => { // Use async/await to wait for columns to be available\n if (!grid.options.server) return;\n let timeout = 500, // Timeout (in millisecond) to wait for columns to be set\n start = Date.now(), colAbsent;\n while ((colAbsent = !grid.options.columns?.length) && Date.now() - start < timeout) {\n await new Promise(resolve => requestAnimationFrame(resolve));\n }\n colAbsent && this.log(\"Timeout waiting for columns.\");\n };\n const restoreState = async () => { // Ensures columns are loaded before state restoration\n await waitForColumns();\n\r\n this.log(\"hide columns\");\r\n\r\n for (const col of cachedState.columns) {\r\n if (col.hidden) {\r\n const hideCol = grid.options.columns.find((c) => c.field === col.field);\r\n hideCol.hidden = true;\r\n }\r\n }\r\n\r\n this.log(\"set: meta, pages\");\r\n grid.options.perPage = cachedState.perPage;\r\n if (grid.options.server) {\r\n grid.meta = cachedState.meta;\r\n grid.pages = cachedState.pages;\r\n grid.page = cachedState.page;\r\n }\n };\n await restoreState();\n }\r\n\r\n this.cachedState = cachedState;\n this.log(\"cachedState\", this.cachedState);\n\r\n const dgLoadData = grid.loadData;\r\n grid.loadData = function (...args) {\r\n return dgLoadData.apply(this, args).finally(() => {\n const saveState = this.plugins.SaveState;\r\n saveState.log(\"loadData\", this.options.columns);\n\r\n if (!grid.classList.contains(\"dg-initialized\")) {\r\n saveState.log(\"not init, loadData skipped\");\r\n return;\r\n }\r\n\r\n saveState.log(\"loadData finished, set param controls\", this.options.columns);\r\n\r\n if (saveState.cachedState && !saveState.isFilterSortSet) {\r\n saveState.log(\"set sort and filters\");\r\n\r\n const sortableHeaders = findAll(grid, \"thead tr.dg-head-columns th[aria-sort]\");\r\n for (const el of sortableHeaders) {\r\n el.setAttribute(\"aria-sort\", \"none\");\r\n }\r\n\r\n grid.querySelector(`thead tr.dg-head-columns th[field='${saveState.cachedState.sort}']`)\n ?.setAttribute(\"aria-sort\", saveState.cachedState.sortDir);\r\n\r\n const filters = findAll(grid.filterRow, \"[id^=dg-filter]\");\r\n saveState.log(\"filters\", filters);\r\n\r\n for (const el of filters) {\r\n el.value = saveState?.cachedState?.filters?.[el.dataset.name] ?? \"\";\r\n saveState.log({ name: el.dataset.name, val: el.value, saveState });\r\n }\r\n saveState.isFilterSortSet = true;\r\n }\r\n\r\n /** @type {GridState} */\r\n const newState = {\r\n meta: grid.meta,\r\n pages: grid.pages,\r\n page: grid.page,\r\n perPage: grid.options.perPage,\r\n filters: {},\r\n columns: grid.options.columns.map((col) => ({ field: col.field, hidden: col.hidden })),\r\n sort: grid.getSort(),\r\n sortDir: grid.getSortDir(),\r\n scrollTo: window.scrollY,\r\n };\r\n\r\n const filters = grid.getFilters();\r\n saveState.log(\"filters\", filters);\r\n\r\n for (const key of Object.keys(filters)) {\r\n newState.filters[key] = filters[key] ?? \"\";\r\n saveState.log({ key, val: filters[key], newState, filters });\r\n }\r\n\r\n saveState.log(\"store new state\", newState);\r\n saveState._setState(newState);\r\n\r\n if (!grid.options.server && saveState.cachedState && !saveState.isDataLoaded) {\r\n saveState.isDataLoaded = true;\r\n grid.filterData();\r\n grid.page = saveState.cachedState.page;\r\n grid.pageChanged();\r\n saveState.log(\"data loaded\");\r\n }\r\n });\r\n };\r\n\r\n const updateState = () => {\r\n const saveState = grid.plugins.SaveState;\r\n const state = saveState._getState();\r\n if (!state) {\r\n return;\r\n }\r\n state.columns = grid.options.columns.map((col) => ({ field: col.field, hidden: col.hidden }));\r\n state.sort = grid.getSort();\r\n state.sortDir = grid.getSortDir();\r\n state.scrollTo = window.scrollY;\r\n saveState._setState(state);\r\n };\r\n\r\n document.addEventListener(\"scrollend\", updateState);\r\n grid.addEventListener(\"headerRendered\", updateState);\r\n\r\n grid.addEventListener(\"bodyRendered\", (ev) => {\r\n if (!grid.classList.contains(\"dg-initialized\") || grid.classList.contains(\"dg-loading\")) {\r\n return;\r\n }\r\n\r\n if (!grid.options.server) {\r\n updateState();\r\n }\r\n\r\n const saveState = grid.plugins.SaveState;\r\n if (!saveState.cachedState || !saveState.isFilterSortSet) {\r\n return;\r\n }\r\n\r\n if (!saveState.isDataLoaded) {\r\n saveState.isDataLoaded = true;\n grid.reload();\r\n saveState.log(\"***grid reloaded\");\r\n } else if (!saveState.isScrolled) {\r\n saveState.isScrolled = true;\r\n window.scrollTo({ top: saveState.cachedState.scrollTo, left: 0, behavior: \"instant\" });\r\n }\r\n });\r\n }\r\n\r\n log(...data) {\r\n this.grid.log(\"[Save-State] \", ...data);\r\n }\r\n\r\n /**\r\n * @returns {GridState}\r\n */\r\n _getState() {\r\n let state;\r\n try {\r\n state = JSON.parse(sessionStorage.getItem(`gridSaveState_${this.grid.id}`));\r\n } catch (_) {}\r\n return state;\r\n }\r\n\r\n /**\r\n * @param {GridState} state\r\n */\r\n _setState(state) {\r\n sessionStorage.setItem(`gridSaveState_${this.grid.id}`, JSON.stringify(state));\r\n }\r\n}\r\n\r\nexport default SaveState;\r\n", "/**\r\n * Data Grid custom element\r\n * https://github.com/lekoala/data-grid/\r\n * @license MIT\r\n */\r\n\r\nimport DataGrid from \"./src/data-grid.js\";\r\n// Optional plugins\r\nimport ColumnResizer from \"./src/plugins/column-resizer.js\";\r\nimport ContextMenu from \"./src/plugins/context-menu.js\";\r\nimport DraggableHeaders from \"./src/plugins/draggable-headers.js\";\r\nimport TouchSupport from \"./src/plugins/touch-support.js\";\r\nimport SelectableRows from \"./src/plugins/selectable-rows.js\";\r\nimport FixedHeight from \"./src/plugins/fixed-height.js\";\r\nimport AutosizeColumn from \"./src/plugins/autosize-column.js\";\r\nimport ResponsiveGrid from \"./src/plugins/responsive-grid.js\";\r\nimport RowActions from \"./src/plugins/row-actions.js\";\r\nimport EditableColumn from \"./src/plugins/editable-column.js\";\r\nimport SpinnerSupport from \"./src/plugins/spinner-support.js\";\r\nimport SaveState from \"./src/plugins/save-state.js\";\r\n\r\n// Using shorthand property names\r\n// This make them reserved and keys will be preserved\r\n// Actual class names are renamed\r\nDataGrid.registerPlugins({\r\n ColumnResizer,\r\n ContextMenu,\r\n DraggableHeaders,\r\n TouchSupport,\r\n SelectableRows,\r\n FixedHeight,\r\n AutosizeColumn,\r\n ResponsiveGrid,\r\n RowActions,\r\n EditableColumn,\r\n SpinnerSupport,\r\n SaveState\r\n});\r\n\r\n// Prevent errors if included multiple times\r\nif (!customElements.get(\"data-grid\")) {\r\n customElements.define(\"data-grid\", DataGrid);\r\n}\r\n\r\nexport default DataGrid;\r\n\r\nconst global = typeof globalThis !== \"undefined\" ? globalThis : self;\r\nglobal.DataGrid = DataGrid;"],
+ "mappings": "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",
+ "names": ["camelize", "str", "m", "chr", "normalizeData", "v", "val", "supportedPassiveTypes", "passiveOpts", "type", "getAttribute", "el", "name", "hasAttribute", "setAttribute", "v", "check", "removeAttribute", "on", "listener", "off", "dispatch", "el", "name", "data", "bubbles", "opts", "hasClass", "addClass", "removeClass", "toggleClass", "$", "selector", "base", "$$", "find", "findAll", "ce", "tagName", "parent", "el", "insertAfter", "newNode", "existingNode", "BaseElement", "options", "opt", "v", "setAttribute", "jsonConfig", "data", "key", "normalizeData", "getAttribute", "event", "template", "dispatch", "attributeName", "oldValue", "newValue", "isOption", "transformer", "attr", "camelize", "base_element_default", "addSelectOption", "el", "value", "label", "checked", "opt", "appendParamsToUrl", "url", "params", "key", "k", "convertArray", "v", "bv", "elementOffset", "el", "rect", "scrollLeft", "scrollTop", "interpolate", "str", "data", "$1", "$2", "canvas", "getTextWidth", "text", "el", "withPadding", "styles", "fontWeight", "fontSize", "fontFamily", "padding", "paddingLeft", "paddingRight", "context", "metrics", "randstr", "prefix", "debounce", "handler", "timeout", "timer", "args", "plugins", "labels", "applyColumnDefinition", "el", "column", "setAttribute", "addClass", "DataGrid", "_DataGrid", "base_element_default", "randstr", "pluginName", "pluginClass", "attr", "camelize", "v", "#setNoData", "tbody", "list", "plugin", "columns", "cols", "key", "col", "item", "convertArray", "$", "val", "initOnly", "pv", "updatePage", "addSelectOption", "field", "found", "prop", "c", "render", "dispatch", "start", "visibleOnly", "len", "tr", "find", "row", "removeAttribute", "headers", "findAll", "th", "fieldName", "value", "k", "i", "keys", "force", "data", "metaKey", "dataKey", "callbackOrUrl", "needRender", "flagEmpty", "resolve", "response", "err", "event", "filters", "inputs", "input", "name", "baseCol", "haveClasses", "sort", "stack", "itemA", "itemB", "a", "b", "valA", "valB", "columnName", "sortDir", "dir", "reject", "base", "url", "params", "appendParamsToUrl", "newError", "error", "sortedColumn", "thead", "tfoot", "td", "availableWidth", "colMaxWidth", "idx", "ce", "sampleTh", "totalWidth", "colIdx", "computedWidth", "getTextWidth", "w", "colAvailableWidth", "visibleCols", "lastCol", "scrollbarWidth", "diff", "thWithWidth", "hasClass", "actualWidth", "minWidth", "newWidth", "rowsWithSort", "sortableRow", "relatedTh", "filter", "filteredRows", "eventName", "eventHandler", "debounce", "e", "isKeyPressFilter", "isSelect", "uniqueValues", "opt", "on", "ev", "toggleClass", "tv", "interpolate", "prev", "total", "p", "bodyRows", "index", "high", "low", "getAttribute", "data_grid_default", "BasePlugin", "grid", "event", "base_plugin_default", "ColumnResizer", "base_plugin_default", "grid", "resizeLabel", "table", "cols", "findAll", "col", "hasClass", "resizer", "addClass", "startX", "startW", "remainingSpace", "max", "mouseMoveHandler", "e", "newWidth", "setAttribute", "mouseUpHandler", "removeClass", "off", "dispatch", "getAttribute", "on", "target", "visibleCols", "columnIndex", "column", "removeAttribute", "elementOffset", "j", "column_resizer_default", "getParentElement", "el", "type", "prop", "parent", "ContextMenu", "base_plugin_default", "off", "grid", "on", "e", "t", "field", "target", "getParentElement", "menu", "rect", "x", "y", "removeAttribute", "documentClickHandler", "setAttribute", "col", "li", "label", "checkbox", "text", "context_menu_default", "DraggableHeaders", "base_plugin_default", "th", "grid", "on", "e", "t", "target", "getParentElement", "index", "targetIndex", "offset", "tmp", "swapNodes", "selector", "el1", "rowIndex", "el2", "setAttribute", "newNode", "findAll", "c", "getAttribute", "dispatch", "draggable_headers_default", "TouchSupport", "base_plugin_default", "grid", "e", "xDiff", "yDiff", "touch_support_default", "SELECTABLE_CLASS", "SELECT_ALL_CLASS", "CHECKBOX_CLASS", "SelectableRows", "base_plugin_default", "#cbSelector", "#inputSelector", "keys", "grid", "selectedData", "inputs", "findAll", "checkbox", "idx", "item", "k", "tbody", "input", "tr", "th", "setAttribute", "label", "td", "e", "el", "unchecked", "$$", "r", "hasClass", "cb", "totalCheckboxes", "dispatch", "selectable_rows_default", "FixedHeight", "base_plugin_default", "grid", "tbody", "tr", "setAttribute", "fakeRow", "max", "visibleRows", "fakeHeight", "fixed_height_default", "AutosizeColumn", "base_plugin_default", "th", "column", "min", "max", "grid", "hasAttribute", "getAttribute", "firstVal", "lastVal", "v", "v2", "width", "getTextWidth", "setAttribute", "autosize_column_default", "RESPONSIVE_CLASS", "obsTo", "sortByPriority", "list", "a", "b", "v1", "callback", "debounce", "entries", "entry", "grid", "table", "contentBoxSize", "size", "tableWidth", "realTableWidth", "findAll", "result", "th", "diff", "minWidth", "prevAction", "headerCols", "col", "changed", "remaining", "cols", "colWidth", "field", "requiredWidth", "width", "filteredHeaderCols", "footer", "find", "realFooterWidth", "div", "availableFooterWidth", "addClass", "removeClass", "resizeObserver", "ResponsiveGrid", "base_plugin_default", "flag", "tr", "ce", "setAttribute", "td", "idealWidth", "consideredCol", "hCol", "ev", "open", "close", "hasClass", "childRow", "hiddenCols", "insertAfter", "childRowTd", "childTable", "childTableRow", "label", "labelCol", "removeAttribute", "responsive_grid_default", "RowActions", "base_plugin_default", "tr", "actionsTh", "setAttribute", "item", "labels", "td", "actionsToggle", "on", "ev", "action", "button", "interpolate", "actionHandler", "dispatch", "row_actions_default", "EditableColumn", "base_plugin_default", "td", "column", "item", "i", "gridId", "input", "ev", "key", "dispatch", "editable_column_default", "SpinnerSupport", "base_plugin_default", "grid", "classes", "cls", "e", "template", "$", "styleParent", "position", "spinner_support_default", "SaveState", "base_plugin_default", "grid", "cachedState", "waitForColumns", "timeout", "start", "colAbsent", "resolve", "col", "hideCol", "c", "dgLoadData", "args", "saveState", "sortableHeaders", "findAll", "el", "filters", "newState", "key", "updateState", "state", "ev", "data", "save_state_default", "data_grid_default", "column_resizer_default", "context_menu_default", "draggable_headers_default", "touch_support_default", "selectable_rows_default", "fixed_height_default", "autosize_column_default", "responsive_grid_default", "row_actions_default", "editable_column_default", "spinner_support_default", "save_state_default", "global"]
}
diff --git a/package-lock.json b/package-lock.json
index bd684f0..2b3fd71 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "data-grid-component",
- "version": "2.0.12",
+ "version": "2.0.13",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "data-grid-component",
- "version": "2.0.12",
+ "version": "2.0.13",
"license": "MIT",
"dependencies": {
"autoprefixer": "^10.4.21",
@@ -17,7 +17,7 @@
"devDependencies": {
"@happy-dom/global-registrator": "^17.4.4",
"ava": "^6.2.0",
- "esbuild": "^0.25.2",
+ "esbuild": "*",
"jsdoc": "^4.0.4",
"jsdoc-plugin-intersection": "^1.0.4",
"jsdoc-to-markdown": "^9.1.1",
@@ -71,9 +71,9 @@
}
},
"node_modules/@esbuild/aix-ppc64": {
- "version": "0.25.2",
- "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.2.tgz",
- "integrity": "sha512-wCIboOL2yXZym2cgm6mlA742s9QeJ8DjGVaL39dLN4rRwrOgOyYSnOaFPhKZGLb2ngj4EyfAFjsNJwPXZvseag==",
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.8.tgz",
+ "integrity": "sha512-urAvrUedIqEiFR3FYSLTWQgLu5tb+m0qZw0NBEasUeo6wuqatkMDaRT+1uABiGXEu5vqgPd7FGE1BhsAIy9QVA==",
"cpu": [
"ppc64"
],
@@ -88,9 +88,9 @@
}
},
"node_modules/@esbuild/android-arm": {
- "version": "0.25.2",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.2.tgz",
- "integrity": "sha512-NQhH7jFstVY5x8CKbcfa166GoV0EFkaPkCKBQkdPJFvo5u+nGXLEH/ooniLb3QI8Fk58YAx7nsPLozUWfCBOJA==",
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.8.tgz",
+ "integrity": "sha512-RONsAvGCz5oWyePVnLdZY/HHwA++nxYWIX1atInlaW6SEkwq6XkP3+cb825EUcRs5Vss/lGh/2YxAb5xqc07Uw==",
"cpu": [
"arm"
],
@@ -105,9 +105,9 @@
}
},
"node_modules/@esbuild/android-arm64": {
- "version": "0.25.2",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.2.tgz",
- "integrity": "sha512-5ZAX5xOmTligeBaeNEPnPaeEuah53Id2tX4c2CVP3JaROTH+j4fnfHCkr1PjXMd78hMst+TlkfKcW/DlTq0i4w==",
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.8.tgz",
+ "integrity": "sha512-OD3p7LYzWpLhZEyATcTSJ67qB5D+20vbtr6vHlHWSQYhKtzUYrETuWThmzFpZtFsBIxRvhO07+UgVA9m0i/O1w==",
"cpu": [
"arm64"
],
@@ -122,9 +122,9 @@
}
},
"node_modules/@esbuild/android-x64": {
- "version": "0.25.2",
- "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.2.tgz",
- "integrity": "sha512-Ffcx+nnma8Sge4jzddPHCZVRvIfQ0kMsUsCMcJRHkGJ1cDmhe4SsrYIjLUKn1xpHZybmOqCWwB0zQvsjdEHtkg==",
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.8.tgz",
+ "integrity": "sha512-yJAVPklM5+4+9dTeKwHOaA+LQkmrKFX96BM0A/2zQrbS6ENCmxc4OVoBs5dPkCCak2roAD+jKCdnmOqKszPkjA==",
"cpu": [
"x64"
],
@@ -139,9 +139,9 @@
}
},
"node_modules/@esbuild/darwin-arm64": {
- "version": "0.25.2",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.2.tgz",
- "integrity": "sha512-MpM6LUVTXAzOvN4KbjzU/q5smzryuoNjlriAIx+06RpecwCkL9JpenNzpKd2YMzLJFOdPqBpuub6eVRP5IgiSA==",
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.8.tgz",
+ "integrity": "sha512-Jw0mxgIaYX6R8ODrdkLLPwBqHTtYHJSmzzd+QeytSugzQ0Vg4c5rDky5VgkoowbZQahCbsv1rT1KW72MPIkevw==",
"cpu": [
"arm64"
],
@@ -156,9 +156,9 @@
}
},
"node_modules/@esbuild/darwin-x64": {
- "version": "0.25.2",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.2.tgz",
- "integrity": "sha512-5eRPrTX7wFyuWe8FqEFPG2cU0+butQQVNcT4sVipqjLYQjjh8a8+vUTfgBKM88ObB85ahsnTwF7PSIt6PG+QkA==",
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.8.tgz",
+ "integrity": "sha512-Vh2gLxxHnuoQ+GjPNvDSDRpoBCUzY4Pu0kBqMBDlK4fuWbKgGtmDIeEC081xi26PPjn+1tct+Bh8FjyLlw1Zlg==",
"cpu": [
"x64"
],
@@ -173,9 +173,9 @@
}
},
"node_modules/@esbuild/freebsd-arm64": {
- "version": "0.25.2",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.2.tgz",
- "integrity": "sha512-mLwm4vXKiQ2UTSX4+ImyiPdiHjiZhIaE9QvC7sw0tZ6HoNMjYAqQpGyui5VRIi5sGd+uWq940gdCbY3VLvsO1w==",
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.8.tgz",
+ "integrity": "sha512-YPJ7hDQ9DnNe5vxOm6jaie9QsTwcKedPvizTVlqWG9GBSq+BuyWEDazlGaDTC5NGU4QJd666V0yqCBL2oWKPfA==",
"cpu": [
"arm64"
],
@@ -190,9 +190,9 @@
}
},
"node_modules/@esbuild/freebsd-x64": {
- "version": "0.25.2",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.2.tgz",
- "integrity": "sha512-6qyyn6TjayJSwGpm8J9QYYGQcRgc90nmfdUb0O7pp1s4lTY+9D0H9O02v5JqGApUyiHOtkz6+1hZNvNtEhbwRQ==",
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.8.tgz",
+ "integrity": "sha512-MmaEXxQRdXNFsRN/KcIimLnSJrk2r5H8v+WVafRWz5xdSVmWLoITZQXcgehI2ZE6gioE6HirAEToM/RvFBeuhw==",
"cpu": [
"x64"
],
@@ -207,9 +207,9 @@
}
},
"node_modules/@esbuild/linux-arm": {
- "version": "0.25.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.2.tgz",
- "integrity": "sha512-UHBRgJcmjJv5oeQF8EpTRZs/1knq6loLxTsjc3nxO9eXAPDLcWW55flrMVc97qFPbmZP31ta1AZVUKQzKTzb0g==",
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.8.tgz",
+ "integrity": "sha512-FuzEP9BixzZohl1kLf76KEVOsxtIBFwCaLupVuk4eFVnOZfU+Wsn+x5Ryam7nILV2pkq2TqQM9EZPsOBuMC+kg==",
"cpu": [
"arm"
],
@@ -224,9 +224,9 @@
}
},
"node_modules/@esbuild/linux-arm64": {
- "version": "0.25.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.2.tgz",
- "integrity": "sha512-gq/sjLsOyMT19I8obBISvhoYiZIAaGF8JpeXu1u8yPv8BE5HlWYobmlsfijFIZ9hIVGYkbdFhEqC0NvM4kNO0g==",
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.8.tgz",
+ "integrity": "sha512-WIgg00ARWv/uYLU7lsuDK00d/hHSfES5BzdWAdAig1ioV5kaFNrtK8EqGcUBJhYqotlUByUKz5Qo6u8tt7iD/w==",
"cpu": [
"arm64"
],
@@ -241,9 +241,9 @@
}
},
"node_modules/@esbuild/linux-ia32": {
- "version": "0.25.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.2.tgz",
- "integrity": "sha512-bBYCv9obgW2cBP+2ZWfjYTU+f5cxRoGGQ5SeDbYdFCAZpYWrfjjfYwvUpP8MlKbP0nwZ5gyOU/0aUzZ5HWPuvQ==",
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.8.tgz",
+ "integrity": "sha512-A1D9YzRX1i+1AJZuFFUMP1E9fMaYY+GnSQil9Tlw05utlE86EKTUA7RjwHDkEitmLYiFsRd9HwKBPEftNdBfjg==",
"cpu": [
"ia32"
],
@@ -258,9 +258,9 @@
}
},
"node_modules/@esbuild/linux-loong64": {
- "version": "0.25.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.2.tgz",
- "integrity": "sha512-SHNGiKtvnU2dBlM5D8CXRFdd+6etgZ9dXfaPCeJtz+37PIUlixvlIhI23L5khKXs3DIzAn9V8v+qb1TRKrgT5w==",
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.8.tgz",
+ "integrity": "sha512-O7k1J/dwHkY1RMVvglFHl1HzutGEFFZ3kNiDMSOyUrB7WcoHGf96Sh+64nTRT26l3GMbCW01Ekh/ThKM5iI7hQ==",
"cpu": [
"loong64"
],
@@ -275,9 +275,9 @@
}
},
"node_modules/@esbuild/linux-mips64el": {
- "version": "0.25.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.2.tgz",
- "integrity": "sha512-hDDRlzE6rPeoj+5fsADqdUZl1OzqDYow4TB4Y/3PlKBD0ph1e6uPHzIQcv2Z65u2K0kpeByIyAjCmjn1hJgG0Q==",
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.8.tgz",
+ "integrity": "sha512-uv+dqfRazte3BzfMp8PAQXmdGHQt2oC/y2ovwpTteqrMx2lwaksiFZ/bdkXJC19ttTvNXBuWH53zy/aTj1FgGw==",
"cpu": [
"mips64el"
],
@@ -292,9 +292,9 @@
}
},
"node_modules/@esbuild/linux-ppc64": {
- "version": "0.25.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.2.tgz",
- "integrity": "sha512-tsHu2RRSWzipmUi9UBDEzc0nLc4HtpZEI5Ba+Omms5456x5WaNuiG3u7xh5AO6sipnJ9r4cRWQB2tUjPyIkc6g==",
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.8.tgz",
+ "integrity": "sha512-GyG0KcMi1GBavP5JgAkkstMGyMholMDybAf8wF5A70CALlDM2p/f7YFE7H92eDeH/VBtFJA5MT4nRPDGg4JuzQ==",
"cpu": [
"ppc64"
],
@@ -309,9 +309,9 @@
}
},
"node_modules/@esbuild/linux-riscv64": {
- "version": "0.25.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.2.tgz",
- "integrity": "sha512-k4LtpgV7NJQOml/10uPU0s4SAXGnowi5qBSjaLWMojNCUICNu7TshqHLAEbkBdAszL5TabfvQ48kK84hyFzjnw==",
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.8.tgz",
+ "integrity": "sha512-rAqDYFv3yzMrq7GIcen3XP7TUEG/4LK86LUPMIz6RT8A6pRIDn0sDcvjudVZBiiTcZCY9y2SgYX2lgK3AF+1eg==",
"cpu": [
"riscv64"
],
@@ -326,9 +326,9 @@
}
},
"node_modules/@esbuild/linux-s390x": {
- "version": "0.25.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.2.tgz",
- "integrity": "sha512-GRa4IshOdvKY7M/rDpRR3gkiTNp34M0eLTaC1a08gNrh4u488aPhuZOCpkF6+2wl3zAN7L7XIpOFBhnaE3/Q8Q==",
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.8.tgz",
+ "integrity": "sha512-Xutvh6VjlbcHpsIIbwY8GVRbwoviWT19tFhgdA7DlenLGC/mbc3lBoVb7jxj9Z+eyGqvcnSyIltYUrkKzWqSvg==",
"cpu": [
"s390x"
],
@@ -343,9 +343,9 @@
}
},
"node_modules/@esbuild/linux-x64": {
- "version": "0.25.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.2.tgz",
- "integrity": "sha512-QInHERlqpTTZ4FRB0fROQWXcYRD64lAoiegezDunLpalZMjcUcld3YzZmVJ2H/Cp0wJRZ8Xtjtj0cEHhYc/uUg==",
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.8.tgz",
+ "integrity": "sha512-ASFQhgY4ElXh3nDcOMTkQero4b1lgubskNlhIfJrsH5OKZXDpUAKBlNS0Kx81jwOBp+HCeZqmoJuihTv57/jvQ==",
"cpu": [
"x64"
],
@@ -360,9 +360,9 @@
}
},
"node_modules/@esbuild/netbsd-arm64": {
- "version": "0.25.2",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.2.tgz",
- "integrity": "sha512-talAIBoY5M8vHc6EeI2WW9d/CkiO9MQJ0IOWX8hrLhxGbro/vBXJvaQXefW2cP0z0nQVTdQ/eNyGFV1GSKrxfw==",
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.8.tgz",
+ "integrity": "sha512-d1KfruIeohqAi6SA+gENMuObDbEjn22olAR7egqnkCD9DGBG0wsEARotkLgXDu6c4ncgWTZJtN5vcgxzWRMzcw==",
"cpu": [
"arm64"
],
@@ -377,9 +377,9 @@
}
},
"node_modules/@esbuild/netbsd-x64": {
- "version": "0.25.2",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.2.tgz",
- "integrity": "sha512-voZT9Z+tpOxrvfKFyfDYPc4DO4rk06qamv1a/fkuzHpiVBMOhpjK+vBmWM8J1eiB3OLSMFYNaOaBNLXGChf5tg==",
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.8.tgz",
+ "integrity": "sha512-nVDCkrvx2ua+XQNyfrujIG38+YGyuy2Ru9kKVNyh5jAys6n+l44tTtToqHjino2My8VAY6Lw9H7RI73XFi66Cg==",
"cpu": [
"x64"
],
@@ -394,9 +394,9 @@
}
},
"node_modules/@esbuild/openbsd-arm64": {
- "version": "0.25.2",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.2.tgz",
- "integrity": "sha512-dcXYOC6NXOqcykeDlwId9kB6OkPUxOEqU+rkrYVqJbK2hagWOMrsTGsMr8+rW02M+d5Op5NNlgMmjzecaRf7Tg==",
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.8.tgz",
+ "integrity": "sha512-j8HgrDuSJFAujkivSMSfPQSAa5Fxbvk4rgNAS5i3K+r8s1X0p1uOO2Hl2xNsGFppOeHOLAVgYwDVlmxhq5h+SQ==",
"cpu": [
"arm64"
],
@@ -411,9 +411,9 @@
}
},
"node_modules/@esbuild/openbsd-x64": {
- "version": "0.25.2",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.2.tgz",
- "integrity": "sha512-t/TkWwahkH0Tsgoq1Ju7QfgGhArkGLkF1uYz8nQS/PPFlXbP5YgRpqQR3ARRiC2iXoLTWFxc6DJMSK10dVXluw==",
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.8.tgz",
+ "integrity": "sha512-1h8MUAwa0VhNCDp6Af0HToI2TJFAn1uqT9Al6DJVzdIBAd21m/G0Yfc77KDM3uF3T/YaOgQq3qTJHPbTOInaIQ==",
"cpu": [
"x64"
],
@@ -427,10 +427,27 @@
"node": ">=18"
}
},
+ "node_modules/@esbuild/openharmony-arm64": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.8.tgz",
+ "integrity": "sha512-r2nVa5SIK9tSWd0kJd9HCffnDHKchTGikb//9c7HX+r+wHYCpQrSgxhlY6KWV1nFo1l4KFbsMlHk+L6fekLsUg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
"node_modules/@esbuild/sunos-x64": {
- "version": "0.25.2",
- "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.2.tgz",
- "integrity": "sha512-cfZH1co2+imVdWCjd+D1gf9NjkchVhhdpgb1q5y6Hcv9TP6Zi9ZG/beI3ig8TvwT9lH9dlxLq5MQBBgwuj4xvA==",
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.8.tgz",
+ "integrity": "sha512-zUlaP2S12YhQ2UzUfcCuMDHQFJyKABkAjvO5YSndMiIkMimPmxA+BYSBikWgsRpvyxuRnow4nS5NPnf9fpv41w==",
"cpu": [
"x64"
],
@@ -445,9 +462,9 @@
}
},
"node_modules/@esbuild/win32-arm64": {
- "version": "0.25.2",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.2.tgz",
- "integrity": "sha512-7Loyjh+D/Nx/sOTzV8vfbB3GJuHdOQyrOryFdZvPHLf42Tk9ivBU5Aedi7iyX+x6rbn2Mh68T4qq1SDqJBQO5Q==",
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.8.tgz",
+ "integrity": "sha512-YEGFFWESlPva8hGL+zvj2z/SaK+pH0SwOM0Nc/d+rVnW7GSTFlLBGzZkuSU9kFIGIo8q9X3ucpZhu8PDN5A2sQ==",
"cpu": [
"arm64"
],
@@ -462,9 +479,9 @@
}
},
"node_modules/@esbuild/win32-ia32": {
- "version": "0.25.2",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.2.tgz",
- "integrity": "sha512-WRJgsz9un0nqZJ4MfhabxaD9Ft8KioqU3JMinOTvobbX6MOSUigSBlogP8QB3uxpJDsFS6yN+3FDBdqE5lg9kg==",
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.8.tgz",
+ "integrity": "sha512-hiGgGC6KZ5LZz58OL/+qVVoZiuZlUYlYHNAmczOm7bs2oE1XriPFi5ZHHrS8ACpV5EjySrnoCKmcbQMN+ojnHg==",
"cpu": [
"ia32"
],
@@ -479,9 +496,9 @@
}
},
"node_modules/@esbuild/win32-x64": {
- "version": "0.25.2",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.2.tgz",
- "integrity": "sha512-kM3HKb16VIXZyIeVrM1ygYmZBKybX8N4p754bw390wGO3Tf2j4L2/WYL+4suWujpgf6GBYs3jv7TyUivdd05JA==",
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.8.tgz",
+ "integrity": "sha512-cn3Yr7+OaaZq1c+2pe+8yxC8E144SReCQjN6/2ynubzYjvyqZjTXfQJpAcQpsdJq3My7XADANiYGHoFC69pLQw==",
"cpu": [
"x64"
],
@@ -2021,9 +2038,9 @@
}
},
"node_modules/esbuild": {
- "version": "0.25.2",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.2.tgz",
- "integrity": "sha512-16854zccKPnC+toMywC+uKNeYSv+/eXkevRAfwRD/G9Cleq66m8XFIrigkbvauLLlCfDL45Q2cWegSg53gGBnQ==",
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.8.tgz",
+ "integrity": "sha512-vVC0USHGtMi8+R4Kz8rt6JhEWLxsv9Rnu/lGYbPR8u47B+DCBksq9JarW0zOO7bs37hyOK1l2/oqtbciutL5+Q==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
@@ -2034,31 +2051,32 @@
"node": ">=18"
},
"optionalDependencies": {
- "@esbuild/aix-ppc64": "0.25.2",
- "@esbuild/android-arm": "0.25.2",
- "@esbuild/android-arm64": "0.25.2",
- "@esbuild/android-x64": "0.25.2",
- "@esbuild/darwin-arm64": "0.25.2",
- "@esbuild/darwin-x64": "0.25.2",
- "@esbuild/freebsd-arm64": "0.25.2",
- "@esbuild/freebsd-x64": "0.25.2",
- "@esbuild/linux-arm": "0.25.2",
- "@esbuild/linux-arm64": "0.25.2",
- "@esbuild/linux-ia32": "0.25.2",
- "@esbuild/linux-loong64": "0.25.2",
- "@esbuild/linux-mips64el": "0.25.2",
- "@esbuild/linux-ppc64": "0.25.2",
- "@esbuild/linux-riscv64": "0.25.2",
- "@esbuild/linux-s390x": "0.25.2",
- "@esbuild/linux-x64": "0.25.2",
- "@esbuild/netbsd-arm64": "0.25.2",
- "@esbuild/netbsd-x64": "0.25.2",
- "@esbuild/openbsd-arm64": "0.25.2",
- "@esbuild/openbsd-x64": "0.25.2",
- "@esbuild/sunos-x64": "0.25.2",
- "@esbuild/win32-arm64": "0.25.2",
- "@esbuild/win32-ia32": "0.25.2",
- "@esbuild/win32-x64": "0.25.2"
+ "@esbuild/aix-ppc64": "0.25.8",
+ "@esbuild/android-arm": "0.25.8",
+ "@esbuild/android-arm64": "0.25.8",
+ "@esbuild/android-x64": "0.25.8",
+ "@esbuild/darwin-arm64": "0.25.8",
+ "@esbuild/darwin-x64": "0.25.8",
+ "@esbuild/freebsd-arm64": "0.25.8",
+ "@esbuild/freebsd-x64": "0.25.8",
+ "@esbuild/linux-arm": "0.25.8",
+ "@esbuild/linux-arm64": "0.25.8",
+ "@esbuild/linux-ia32": "0.25.8",
+ "@esbuild/linux-loong64": "0.25.8",
+ "@esbuild/linux-mips64el": "0.25.8",
+ "@esbuild/linux-ppc64": "0.25.8",
+ "@esbuild/linux-riscv64": "0.25.8",
+ "@esbuild/linux-s390x": "0.25.8",
+ "@esbuild/linux-x64": "0.25.8",
+ "@esbuild/netbsd-arm64": "0.25.8",
+ "@esbuild/netbsd-x64": "0.25.8",
+ "@esbuild/openbsd-arm64": "0.25.8",
+ "@esbuild/openbsd-x64": "0.25.8",
+ "@esbuild/openharmony-arm64": "0.25.8",
+ "@esbuild/sunos-x64": "0.25.8",
+ "@esbuild/win32-arm64": "0.25.8",
+ "@esbuild/win32-ia32": "0.25.8",
+ "@esbuild/win32-x64": "0.25.8"
}
},
"node_modules/escalade": {
diff --git a/package.json b/package.json
index 99c4708..b336025 100644
--- a/package.json
+++ b/package.json
@@ -1,13 +1,13 @@
{
"name": "data-grid-component",
- "version": "2.0.12",
+ "version": "2.0.13",
"description": "Standalone data grid web component",
"type": "module",
"main": "data-grid",
"scripts": {
"test": "ava",
"build-min": "esbuild --bundle --minify --loader:.css=text --loader:.html=text --sourcemap --format=esm data-grid.js --outfile=dist/data-grid.min.js",
- "build-dev": "esbuild --bundle --loader:.css=text --loader:.html=text --sourcemap --format=esm data-grid.js --outfile=dist/data-grid.js --banner:js=\"/*** Data Grid Web Component v2.0.12 * https://github.com/lekoala/data-grid ***/\"",
+ "build-dev": "esbuild --bundle --loader:.css=text --loader:.html=text --sourcemap --format=esm data-grid.js --outfile=dist/data-grid.js --banner:js=\"/*** Data Grid Web Component v2.0.13 * https://github.com/lekoala/data-grid ***/\"",
"build": "npm run build-min && npm run build-dev",
"start": "npm run build-dev -- --servedir=.",
"watch": "npm run build-dev -- --watch",
@@ -49,7 +49,7 @@
"devDependencies": {
"@happy-dom/global-registrator": "^17.4.4",
"ava": "^6.2.0",
- "esbuild": "^0.25.2",
+ "esbuild": "*",
"jsdoc": "^4.0.4",
"jsdoc-plugin-intersection": "^1.0.4",
"jsdoc-to-markdown": "^9.1.1",
diff --git a/readme.md b/readme.md
index 37c75e2..284bba1 100644
--- a/readme.md
+++ b/readme.md
@@ -95,40 +95,42 @@ data-grid {
These are the options accessibles through the components data attributes. Some options only work if the proper plugin is loaded.
You can also pass them as a json string in data-config.
-| Name | Type | Description |
-|---------------------|----------------------------------------------|--------------------------------------------------------------------------------|
-| id | String | Custom id for the grid |
-| url | String | An URL with data to display in JSON format |
-| debug | Boolean | Log actions in DevTools console |
-| filter | Boolean | Allows a filtering functionality |
-| sort | Boolean | Allows a sort by column functionality |
-| defaultSort | String | Default sort field if sorting is enabled |
-| server | Boolean | Is a server side powered grid |
-| serverParams | [ServerParams](#ServerParams) | Describe keys passed to the server backend |
-| dir | String | Dir |
-| perPageValues | Array | Available per page options |
-| hidePerPage | Boolean | Hides the page size select element |
-| columns | [Array.<Column>](#Column) | Available columns |
-| defaultPage | Number | Starting page |
-| perPage | Number | Number of records displayed per page (page size) |
-| expand | Boolean | Allow cell content to spawn over multiple lines |
-| actions | [Array.<Action>](#Action) | Row actions (RowActions module) |
-| collapseActions | Boolean | Group actions (RowActions module) |
-| resizable | Boolean | Make columns resizable (ColumnResizer module) |
-| selectable | Boolean | Allow selecting rows with a checkbox (SelectableRows module) |
-| selectVisibleOnly | Boolean | Select all only selects visible rows (SelectableRows module) |
-| autosize | Boolean | Compute column sizes based on given data (Autosize module) |
-| autoheight | Boolean | Adjust height so that it matches table size (FixedHeight module) |
-| autohidePager | Boolean | auto-hides the pager when number of records falls below the selected page size |
-| menu | Boolean | Right click menu on column headers (ContextMenu module) |
-| reorder | Boolean | Allows a column reordering functionality (DraggableHeaders module) |
-| responsive | Boolean | Change display mode on small screens (ResponsiveGrid module) |
-| responsiveToggle | Boolean | Show toggle column (ResponsiveGrid module) |
-| filterOnEnter | Boolean | Toggles the ability to filter column data by pressing the Enter or Return key |
-| spinnerClass | String | Sets a space-delimited string of css classes for a spinner |
-| filterKeypressDelay | Number | Sets a keypress delay time in milliseconds before triggering filter operation. |
-| saveState | Boolean | Enable/disable save state plugin (SaveState module) |
-| errorMessage | String | A generic text to be displayed in footer when error occurs. |
+| Name | Type | Description |
+|---------------------|----------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------|
+| id | String | Custom id for the grid |
+| url | String | An URL with data to display in JSON format |
+| debug | Boolean | Log actions in DevTools console |
+| filter | Boolean | Allows a filtering functionality |
+| sort | Boolean | Allows a sort by column functionality |
+| defaultSort | String | Default sort field if sorting is enabled |
+| server | Boolean | Is a server side powered grid |
+| serverParams | [ServerParams](#ServerParams) | Describe keys passed to the server backend |
+| dir | String | Dir |
+| perPageValues | Array | Available per page options |
+| hidePerPage | Boolean | Hides the page size select element |
+| columns | [Array.<Column>](#Column) | Available columns |
+| defaultPage | Number | Starting page |
+| perPage | Number | Number of records displayed per page (page size) |
+| expand | Boolean | Allow cell content to spawn over multiple lines |
+| actions | [Array.<Action>](#Action) | Row actions (RowActions module) |
+| collapseActions | Boolean | Group actions (RowActions module) |
+| resizable | Boolean | Make columns resizable (ColumnResizer module) |
+| selectable | Boolean | Allow multi-selecting rows with a checkboxes (SelectableRows module) |
+| selectVisibleOnly | Boolean | Select all only selects visible rows (SelectableRows module) |
+| singleSelect | Boolean | Enables single row select with radio buttons - no need to set selectable (SelectableRows module) |
+| autosize | Boolean | Compute column sizes based on given data (Autosize module) |
+| autoheight | Boolean | Adjust height so that it matches table size (FixedHeight module) |
+| autohidePager | Boolean | auto-hides the pager when number of records falls below the selected page size |
+| menu | Boolean | Right click menu on column headers (ContextMenu module) |
+| reorder | Boolean | Allows a column reordering functionality (DraggableHeaders module) |
+| responsive | Boolean | Change display mode on small screens (ResponsiveGrid module) |
+| responsiveToggle | Boolean | Show toggle column (ResponsiveGrid module) |
+| filterOnEnter | Boolean | Toggles the ability to filter column data by pressing the Enter or Return key |
+| spinnerClass | String | Sets a space-delimited string of css classes for a spinner |
+| filterKeypressDelay | Number | Sets a keypress delay time in milliseconds before triggering filter operation. |
+| saveState | Boolean | Enable/disable save state plugin (SaveState module) |
+| errorMessage | String | A generic text to be displayed in footer when error occurs. |
+| noData | String | A custom text to be displayed when no data is loaded. This is different from the generic labels.noData that applies for data-grid as a component. | |
@@ -325,8 +327,8 @@ You can check `demo-server.html` to get a sample usage with saving functionnalit
| **getSelection** | gets selected data |
| **clearData** | clears loaded data |
| **preload** | preloads the data intended to bypass the initial fetch operation, allowing for faster intial page load time. |
-| **refresh** | clears and reloads data from url |
-| **reload** | reloads data from url |
+| **refresh** | clears and reloads data from url that can be optionally specified as a parameter. |
+| **reload** | reloads data from url that can be optionally specified as a parameter. |
| **clearFilter** | clears current filters |
| **addRow** | adds a new row |
| **removeRow** | removes a row |
diff --git a/scss/_core.scss b/scss/_core.scss
index a644b64..ba35e6e 100644
--- a/scss/_core.scss
+++ b/scss/_core.scss
@@ -1,5 +1,5 @@
/**
- * Data Grid Web Component v2.0.12
+ * Data Grid Web Component v2.0.13
* https://github.com/lekoala/data-grid
*/
@@ -23,6 +23,7 @@ data-grid {
--color: rgb(var(--color-rgb));
--highlight-color: #fffcee;
+ --selected-bgcolor: var(--bs-primary-bg-subtle, #cfe2ff);
--body-background: var(--bs-table-bg, #fff);
--striped-background: rgba(0, 0, 0, 0.05);
--header-background: var(--bs-gray-200, #e9ecef);
@@ -198,6 +199,7 @@ data-grid {
}
.dg-selectable {
+ font-size: 1em;
label {
display: flex;
align-items: center;
@@ -324,7 +326,7 @@ data-grid {
padding: 0;
}
- input:not([type="checkbox"]),
+ input:not([type="checkbox"],[type="radio"]),
select {
background-color: var(--input-background, "#fff");
color: currentColor;
@@ -370,23 +372,29 @@ data-grid {
}
}
- // Editable
- tbody td.dg-editable-col {
- padding: 0;
- height: 0; // it needs a height for height 100%
- }
+ tbody {
+ // Editable
+ td.dg-editable-col {
+ padding: 0;
+ height: 0; // it needs a height for height 100%
+ }
- tbody td input.dg-editable {
- width: 100%;
- background: transparent;
- border: 0;
- border-radius: 0;
- margin: 0;
- box-shadow: none;
- height: 100%;
+ td input.dg-editable {
+ width: 100%;
+ background: transparent;
+ border: 0;
+ border-radius: 0;
+ margin: 0;
+ box-shadow: none;
+ height: 100%;
- &:focus {
- box-shadow: inset 0px 0px 0px 1px var(--color);
+ &:focus {
+ box-shadow: inset 0px 0px 0px 1px var(--color);
+ }
+ }
+
+ tr:has(.dg-selectable [type=radio]:checked) {
+ background-color: var(--selected-bgcolor);
}
}
@@ -565,6 +573,7 @@ data-grid {
[data-bs-theme="dark"] data-grid {
--scroller-color-lightness: 20%;
--highlight-color: #43423e;
+ --selected-bgcolor: var(--bs-primary-bg-subtle, #031633);
--body-background: #212529;
--striped-background: #2c3034;
--header-background: var(--bs-gray-800, #34373b);
diff --git a/src/core/base-element.js b/src/core/base-element.js
index beea644..27e5079 100644
--- a/src/core/base-element.js
+++ b/src/core/base-element.js
@@ -58,7 +58,7 @@ class BaseElement extends HTMLElement {
const jsonConfig = this.dataset.config ? JSON.parse(this.dataset.config) : {};
const data = { ...this.dataset };
for (const key in data) {
- if (key === "config") {
+ if (key === "config" || !data.hasOwnProperty(key) || typeof data[key] === "function") {
continue;
}
data[key] = normalizeData(data[key]);
@@ -112,7 +112,7 @@ class BaseElement extends HTMLElement {
}
this.setup = true;
// ensure whenDefined callbacks run first
- setTimeout(() => {
+ setTimeout(async () => {
this.log("connectedCallback");
// Append only when labels had the opportunity to be set
@@ -122,7 +122,8 @@ class BaseElement extends HTMLElement {
template.innerHTML = this.constructor.template();
this.appendChild(template.content.cloneNode(true));
- this._connected();
+ await this._connected();
+
// @link https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4#life-cycle-events
dispatch(this, "connected");
}, 0);
diff --git a/src/data-grid.js b/src/data-grid.js
index 10b6d6e..18fb51d 100644
--- a/src/data-grid.js
+++ b/src/data-grid.js
@@ -133,8 +133,9 @@ import {
* @property {Action[]} actions Row actions (RowActions module)
* @property {Boolean} collapseActions Group actions (RowActions module)
* @property {Boolean} resizable Make columns resizable (ColumnResizer module)
- * @property {Boolean} selectable Allow selecting rows with a checkbox (SelectableRows module)
+ * @property {Boolean} selectable Allow multi-selecting rows with a checkboxes (SelectableRows module)
* @property {Boolean} selectVisibleOnly Select all only selects visible rows (SelectableRows module)
+ * @property {Boolean} singleSelect Enables single row select with radio buttons - no need to set selectable (SelectableRows module)
* @property {Boolean} autosize Compute column sizes based on given data (Autosize module)
* @property {Boolean} autoheight Adjust height so that it matches table size (FixedHeight module)
* @property {Boolean} autohidePager auto-hides the pager when number of records falls below the selected page size
@@ -147,6 +148,7 @@ import {
* @property {Number} filterKeypressDelay Sets a keypress delay time in milliseconds before triggering filter operation.
* @property {Boolean} saveState Enable/disable save state plugin (SaveState module)
* @property {?String} errorMessage A generic text to be displayed in footer when error occurs.
+ * @property {?String} noData A custom text to be displayed when no data is loaded. This is different from the generic labels.noData that applies for data-grid as a component.
*/
/**
@@ -214,6 +216,7 @@ function applyColumnDefinition(el, column) {
*/
class DataGrid extends BaseElement {
_filterSelector = "[id^=dg-filter]";
+ _excludedRowElementSelector = "a,button,input,select,textarea";
_excludedKeys = [
37,
39,
@@ -273,6 +276,7 @@ class DataGrid extends BaseElement {
* @type {Options}
*/
this.options = this.options || this.defaultOptions;
+ if (this.options.singleSelect) this.options.selectable = true; // singleSelect implies selectable
// Init values
this.fireEvents = false;
@@ -361,6 +365,20 @@ class DataGrid extends BaseElement {
labels = Object.assign(labels, v);
}
+ /** Gets the text to be displayed when no data is loaded. */
+ get noData() {
+ return this.options.noData || this.labels.noData;
+ }
+
+ /**
+ * @param {HTMLTableSectionElement} tbody
+ */
+ #setNoData(tbody) {
+ if (!this.hasDataError && tbody.getAttribute("data-empty") !== this.noData) {
+ tbody.setAttribute("data-empty", this.noData);
+ }
+ }
+
/**
* @returns {Column}
*/
@@ -389,7 +407,7 @@ class DataGrid extends BaseElement {
get defaultOptions() {
return {
id: null,
- url: null,
+ url: "",
perPage: 10,
debug: false,
filter: false,
@@ -419,6 +437,7 @@ class DataGrid extends BaseElement {
collapseActions: false,
selectable: false,
selectVisibleOnly: true,
+ singleSelect: false,
defaultPage: 1,
resizable: false,
autosize: true,
@@ -432,6 +451,7 @@ class DataGrid extends BaseElement {
spinnerClass: "",
saveState: false,
errorMessage: "",
+ noData: ""
};
}
@@ -526,6 +546,7 @@ class DataGrid extends BaseElement {
"data-reorder",
"data-menu",
"data-selectable",
+ "data-single-select",
"data-url",
"data-per-page",
"data-responsive",
@@ -572,11 +593,9 @@ class DataGrid extends BaseElement {
* @param {Boolean} initOnly
*/
urlChanged(initOnly = false) {
- if (initOnly && !this.isInit) return;
+ if (initOnly && !this.isInit) return this;
this.reconfig();
- this.loadData().then(() => {
- this.configureUi();
- });
+ return this.loadData().then(() => this.configureUi());
}
/**
@@ -586,7 +605,7 @@ class DataGrid extends BaseElement {
const cols = this.options.columns;
this.options.columns = [];
this.configureUi();
- this.options.columns = cols;
+ return this.options.columns = cols, this;
}
constrainPageValue(v) {
@@ -601,13 +620,14 @@ class DataGrid extends BaseElement {
}
fixPage() {
+ if (!this.inputPage) return this;
this.pages = this.totalPages();
this.page = this.constrainPageValue(this.page);
// Show current page in input
setAttribute(this.inputPage, "max", this.pages);
this.inputPage.value = `${this.page}`;
- this.inputPage.disabled = this.pages < 2;
+ return this.inputPage.disabled = this.pages < 2, this;
}
pageChanged() {
@@ -689,7 +709,7 @@ class DataGrid extends BaseElement {
}
}
- _connected() {
+ async _connected() {
/**
* @type {HTMLTableElement}
*/
@@ -735,33 +755,14 @@ class DataGrid extends BaseElement {
this.inputPage.addEventListener("input", this.gotoPage);
for (const plugin of Object.values(this.plugins)) {
- plugin.connected();
+ await plugin.connected();
}
// Display even if we don't have data
this.dirChanged();
this.perPageValuesChanged();
- setTimeout(() => { //ensures all registered plugins are connected before loading data
- // @ts-ignore
- this.loadData().finally(() => {
- this.configureUi();
-
- this.sortChanged();
- this.classList.add("dg-initialized"); //acts as a flag to prevent unnecessary server calls down the chain.
-
- this.filterChanged();
- this.reorderChanged();
-
- this.dirChanged();
- this.perPageValuesChanged();
- this.pageChanged();
-
- this.fireEvents = true; // We can now fire attributeChangedCallback events
-
- this.log("initialized");
- });
- }, 0);
+ await this.init();
}
_disconnected() {
@@ -777,6 +778,26 @@ class DataGrid extends BaseElement {
}
}
+ init() {
+ return this.loadData().finally(() => {
+ this.configureUi();
+
+ this.sortChanged();
+ this.classList.add("dg-initialized"); //acts as a flag to prevent unnecessary server calls down the chain.
+
+ this.filterChanged();
+ this.reorderChanged();
+
+ this.dirChanged();
+ this.perPageValuesChanged();
+ this.pageChanged();
+
+ this.fireEvents = true; // We can now fire attributeChangedCallback events
+
+ this.log("initialized");
+ });
+ }
+
/**
* @param {string} field
* @returns {Column}
@@ -897,6 +918,7 @@ class DataGrid extends BaseElement {
* This should be called after your data has been loaded
*/
configureUi() {
+ if (!this.table) return this;
this.table.style.visibility = "hidden";
this.renderTable();
if (this.options.responsive && this.plugins.ResponsiveGrid) {
@@ -912,7 +934,8 @@ class DataGrid extends BaseElement {
this.rowHeight = tr.offsetHeight;
}
}
- this.fixPage();
+ this.#setNoData(this.tbody);
+ return this.fixPage();
}
filterChanged() {
@@ -1002,25 +1025,32 @@ class DataGrid extends BaseElement {
}
/**
- * @param {String} key Return a specific key (eg: id) instead of the whole row
- * @returns {Array}
+ * Get selected rows or specific fields from selected rows.
+ * If no keys are provided, returns the full row objects.
+ * If one key is provided, returns an array of values for that key.
+ * If multiple keys are provided, returns an array of objects with those keys and values.
+ * In single select mode, returns a single object or value.
+ * @param {...String} keys - Field names to select from each row.
+ * @returns {Array|Object} Selected rows, values, or objects depending on selection and keys.
*/
- getSelection(key = null) {
+ getSelection(...keys) {
if (!this.plugins.SelectableRows) {
return [];
}
- return this.plugins.SelectableRows.getSelection(key);
+ return this.plugins.SelectableRows.getSelection(...keys);
}
getData() {
return this.originalData;
}
- clearData() {
+ clearData(force = false) {
// Already empty
- if (this.data.length === 0) {
+ if (!force && this.data.length === 0) {
return;
}
+ this.classList.remove("dg-empty", "dg-network-error");
+ this.tbody?.setAttribute("data-empty", this.noData);
this.data = this.originalData = [];
this.renderBody();
}
@@ -1041,27 +1071,39 @@ class DataGrid extends BaseElement {
}
}
- refresh(cb = null) {
+ /**
+ * Clears and reloads data from url.
+ * @param {Function|String} callbackOrUrl
+ * @returns {DataGrid}
+ */
+ refresh(callbackOrUrl = null) {
this.data = this.originalData = [];
- return this.reload(cb);
+ return this.reload(callbackOrUrl);
}
- reload(cb = null) {
+ /**
+ * Reloads data from url.
+ * @param {Function|String} callbackOrUrl
+ * @returns {DataGrid}
+ */
+ reload(callbackOrUrl = null) {
this.log("reload");
-
+ if (typeof callbackOrUrl === "string") {
+ this.options.url = callbackOrUrl;
+ }
// If the data was cleared, we need to render again
const needRender = !this.originalData?.length;
this.fixPage();
// @ts-ignore
- this.loadData().finally(() => {
+ return this.loadData().finally(() => {
if (this.hasDataError) return;
// If we load data from the server, we redraw the table body
// Otherwise, we just need to paginate
this.options.server || needRender ? this.renderBody() : this.paginate();
- if (cb) {
- cb();
+ if (typeof callbackOrUrl === "function") {
+ callbackOrUrl();
}
- });
+ }).then(() => this);
}
/**
@@ -1136,9 +1178,7 @@ class DataGrid extends BaseElement {
// @ts-ignore
.finally(() => {
flagEmpty();
- if (!this.hasDataError && tbody.getAttribute("data-empty") !== this.labels.noData) {
- tbody.setAttribute("data-empty", this.labels.noData);
- }
+ this.#setNoData(tbody);
this.classList.remove("dg-loading");
setAttribute(this.table, "aria-rowcount", this.data.length);
this.loading = false;
@@ -1283,7 +1323,7 @@ class DataGrid extends BaseElement {
const headers = findAll(this, "thead tr:first-child th");
for (const th of headers) {
// @ts-ignore
- if ([...th.classList].some(haveClasses)) {
+ if ([...th.classList].some(haveClasses) || !th.hasAttribute("aria-sort")) {
continue;
}
if (th !== col) {
@@ -1459,6 +1499,7 @@ class DataGrid extends BaseElement {
this.log("render footer");
const tfoot = this.tfoot;
+ if (!tfoot) return;
const td = tfoot.querySelector("td");
tfoot.removeAttribute("hidden");
setAttribute(td, "colspan", this.columnsLength(true));
@@ -1485,11 +1526,11 @@ class DataGrid extends BaseElement {
tr.setAttribute("class", "dg-head-columns");
// We need a real th from the dom to compute the size
- let sampleTh = thead.querySelector("tr.dg-head-columns th");
+ let sampleTh = thead?.querySelector("tr.dg-head-columns th");
this.log("createColumnHeaders - sampleTh", sampleTh);
if (!sampleTh) {
sampleTh = ce("th");
- thead.querySelector("tr").appendChild(sampleTh);
+ thead?.querySelector("tr").appendChild(sampleTh);
}
if (this.options.selectable && this.plugins.SelectableRows) {
@@ -1573,10 +1614,10 @@ class DataGrid extends BaseElement {
this.plugins.RowActions.makeActionHeader(tr);
}
- thead.replaceChild(tr, thead.querySelector("tr.dg-head-columns"));
+ thead?.replaceChild(tr, thead.querySelector("tr.dg-head-columns"));
// Once columns are inserted, we have an actual dom to query
- if (thead.offsetWidth > availableWidth) {
+ if (thead && thead.offsetWidth > availableWidth) {
this.log(`adjust width to fix size, ${thead.offsetWidth} > ${availableWidth}`);
const scrollbarWidth = this.offsetWidth - this.clientWidth;
let diff = thead.offsetWidth - availableWidth - scrollbarWidth;
@@ -1617,7 +1658,7 @@ class DataGrid extends BaseElement {
sortableRow.addEventListener("click", () => this.sortData(sortableRow));
}
- setAttribute(this.table, "aria-colcount", this.columnsLength(true));
+ this.table && setAttribute(this.table, "aria-colcount", this.columnsLength(true));
}
createColumnFilters(thead) {
@@ -1647,7 +1688,7 @@ class DataGrid extends BaseElement {
continue;
}
const colIdx = idx + this.startColIndex();
- const relatedTh = thead.querySelector(`tr.dg-head-columns th[aria-colindex="${colIdx}"]`);
+ const relatedTh = thead?.querySelector(`tr.dg-head-columns th[aria-colindex="${colIdx}"]`);
if (!relatedTh) {
console.warn("Related th not found", colIdx);
continue;
@@ -1676,7 +1717,7 @@ class DataGrid extends BaseElement {
this.plugins.RowActions.makeActionFilter(tr);
}
- thead.replaceChild(tr, thead.querySelector("tr.dg-head-filters"));
+ thead?.replaceChild(tr, thead.querySelector("tr.dg-head-filters"));
if (typeof this.options.filterKeypressDelay !== "number" || this.options.filterOnEnter)
this.options.filterKeypressDelay = 0;
@@ -1768,6 +1809,7 @@ class DataGrid extends BaseElement {
tr.classList.add("dg-expandable");
on(tr, "click", (ev) => {
+ if (ev.target.matches(this._excludedRowElementSelector)) return;
if (this.plugins.ResponsiveGrid) {
this.plugins.ResponsiveGrid.blockObserver();
}
@@ -1867,8 +1909,8 @@ class DataGrid extends BaseElement {
// Keep data empty message
const prev = this.tbody;
- tbody.setAttribute("data-empty", prev.getAttribute("data-empty"));
- this.table.replaceChild(tbody, prev);
+ prev && tbody.setAttribute("data-empty", prev.getAttribute("data-empty"));
+ this.table?.replaceChild(tbody, prev);
if (this.plugins.FixedHeight) {
this.plugins.FixedHeight.createFakeRow();
@@ -1880,7 +1922,7 @@ class DataGrid extends BaseElement {
this.plugins.SelectableRows.shouldSelectAll(tbody);
}
- this.data.length && this.classList.remove("dg-empty");
+ this.classList.toggle("dg-empty", !this.data.length);
dispatch(this, "bodyRendered");
}
@@ -1892,6 +1934,7 @@ class DataGrid extends BaseElement {
const p = this.page || 1;
const tbody = this.tbody;
const tfoot = this.tfoot;
+ if (!tbody || !tfoot) return;
const bodyRows = findAll(tbody, "tr");
// Refresh page count in case we added/removed a page
diff --git a/src/plugins/fixed-height.js b/src/plugins/fixed-height.js
index 2809aaa..0ac0b88 100644
--- a/src/plugins/fixed-height.js
+++ b/src/plugins/fixed-height.js
@@ -28,7 +28,7 @@ class FixedHeight extends BasePlugin {
setAttribute(tr, "hidden", "");
tr.classList.add("dg-fake-row");
tr.tabIndex = 0;
- tbody.appendChild(tr);
+ tbody?.appendChild(tr);
}
get fakeRow() {
diff --git a/src/plugins/save-state.js b/src/plugins/save-state.js
index 16a81ac..71f71d8 100644
--- a/src/plugins/save-state.js
+++ b/src/plugins/save-state.js
@@ -24,7 +24,7 @@ class SaveState extends BasePlugin {
this.log("Init");
}
- connected() {
+ async connected() {
this.log("connected");
const grid = this.grid;
@@ -39,96 +39,108 @@ class SaveState extends BasePlugin {
const cachedState = this._getState();
if (cachedState) {
- this.log("hide columns");
+ const waitForColumns = async () => { // Use async/await to wait for columns to be available
+ if (!grid.options.server) return;
+ let timeout = 500, // Timeout (in millisecond) to wait for columns to be set
+ start = Date.now(), colAbsent;
+ while ((colAbsent = !grid.options.columns?.length) && Date.now() - start < timeout) {
+ await new Promise(resolve => requestAnimationFrame(resolve));
+ }
+ colAbsent && this.log("Timeout waiting for columns.");
+ };
+ const restoreState = async () => { // Ensures columns are loaded before state restoration
+ await waitForColumns();
+
+ this.log("hide columns");
- for (const col of cachedState.columns) {
- if (col.hidden) {
- const hideCol = grid.options.columns.find((c) => c.field === col.field);
- hideCol.hidden = true;
+ for (const col of cachedState.columns) {
+ if (col.hidden) {
+ const hideCol = grid.options.columns.find((c) => c.field === col.field);
+ hideCol.hidden = true;
+ }
}
- }
- this.log("set: meta, pages");
- grid.options.perPage = cachedState.perPage;
- if (grid.options.server) {
- grid.meta = cachedState.meta;
- grid.pages = cachedState.pages;
- grid.page = cachedState.page;
- }
+ this.log("set: meta, pages");
+ grid.options.perPage = cachedState.perPage;
+ if (grid.options.server) {
+ grid.meta = cachedState.meta;
+ grid.pages = cachedState.pages;
+ grid.page = cachedState.page;
+ }
+ };
+ await restoreState();
}
this.cachedState = cachedState;
this.log("cachedState", this.cachedState);
- setTimeout(() => {
- const dgLoadData = grid.loadData;
- grid.loadData = function (...args) {
- return dgLoadData.apply(this, args).finally(() => {
- const saveState = this.plugins.SaveState;
- saveState.log("loadData", this.options.columns);
-
- if (!grid.classList.contains("dg-initialized")) {
- saveState.log("not init, loadData skipped");
- return;
- }
-
- saveState.log("loadData finished, set param controls", this.options.columns);
+ const dgLoadData = grid.loadData;
+ grid.loadData = function (...args) {
+ return dgLoadData.apply(this, args).finally(() => {
+ const saveState = this.plugins.SaveState;
+ saveState.log("loadData", this.options.columns);
- if (saveState.cachedState && !saveState.isFilterSortSet) {
- saveState.log("set sort and filters");
-
- const sortableHeaders = findAll(grid, "thead tr.dg-head-columns th[aria-sort]");
- for (const el of sortableHeaders) {
- el.setAttribute("aria-sort", "none");
- }
+ if (!grid.classList.contains("dg-initialized")) {
+ saveState.log("not init, loadData skipped");
+ return;
+ }
- grid.querySelector(`thead tr.dg-head-columns th[field='${saveState.cachedState.sort}']`)
- ?.setAttribute("aria-sort", saveState.cachedState.sortDir);
+ saveState.log("loadData finished, set param controls", this.options.columns);
- const filters = findAll(grid.filterRow, "[id^=dg-filter]");
- saveState.log("filters", filters);
+ if (saveState.cachedState && !saveState.isFilterSortSet) {
+ saveState.log("set sort and filters");
- for (const el of filters) {
- el.value = saveState?.cachedState?.filters?.[el.dataset.name] ?? "";
- saveState.log({ name: el.dataset.name, val: el.value, saveState });
- }
- saveState.isFilterSortSet = true;
+ const sortableHeaders = findAll(grid, "thead tr.dg-head-columns th[aria-sort]");
+ for (const el of sortableHeaders) {
+ el.setAttribute("aria-sort", "none");
}
- /** @type {GridState} */
- const newState = {
- meta: grid.meta,
- pages: grid.pages,
- page: grid.page,
- perPage: grid.options.perPage,
- filters: {},
- columns: grid.options.columns.map((col) => ({ field: col.field, hidden: col.hidden })),
- sort: grid.getSort(),
- sortDir: grid.getSortDir(),
- scrollTo: window.scrollY,
- };
-
- const filters = grid.getFilters();
+ grid.querySelector(`thead tr.dg-head-columns th[field='${saveState.cachedState.sort}']`)
+ ?.setAttribute("aria-sort", saveState.cachedState.sortDir);
+
+ const filters = findAll(grid.filterRow, "[id^=dg-filter]");
saveState.log("filters", filters);
- for (const key of Object.keys(filters)) {
- newState.filters[key] = filters[key] ?? "";
- saveState.log({ key, val: filters[key], newState, filters });
+ for (const el of filters) {
+ el.value = saveState?.cachedState?.filters?.[el.dataset.name] ?? "";
+ saveState.log({ name: el.dataset.name, val: el.value, saveState });
}
+ saveState.isFilterSortSet = true;
+ }
+
+ /** @type {GridState} */
+ const newState = {
+ meta: grid.meta,
+ pages: grid.pages,
+ page: grid.page,
+ perPage: grid.options.perPage,
+ filters: {},
+ columns: grid.options.columns.map((col) => ({ field: col.field, hidden: col.hidden })),
+ sort: grid.getSort(),
+ sortDir: grid.getSortDir(),
+ scrollTo: window.scrollY,
+ };
+
+ const filters = grid.getFilters();
+ saveState.log("filters", filters);
+
+ for (const key of Object.keys(filters)) {
+ newState.filters[key] = filters[key] ?? "";
+ saveState.log({ key, val: filters[key], newState, filters });
+ }
- saveState.log("store new state", newState);
- saveState._setState(newState);
+ saveState.log("store new state", newState);
+ saveState._setState(newState);
- if (!grid.options.server && saveState.cachedState && !saveState.isDataLoaded) {
- saveState.isDataLoaded = true;
- grid.filterData();
- grid.page = saveState.cachedState.page;
- grid.pageChanged();
- saveState.log("data loaded");
- }
- });
- };
- }, 0);
+ if (!grid.options.server && saveState.cachedState && !saveState.isDataLoaded) {
+ saveState.isDataLoaded = true;
+ grid.filterData();
+ grid.page = saveState.cachedState.page;
+ grid.pageChanged();
+ saveState.log("data loaded");
+ }
+ });
+ };
const updateState = () => {
const saveState = grid.plugins.SaveState;
diff --git a/src/plugins/selectable-rows.js b/src/plugins/selectable-rows.js
index 286f709..f6d3065 100644
--- a/src/plugins/selectable-rows.js
+++ b/src/plugins/selectable-rows.js
@@ -1,5 +1,6 @@
+// @ts-nocheck
import BasePlugin from "../core/base-plugin.js";
-import { dispatch, findAll, hasClass, setAttribute } from "../utils/shortcuts.js";
+import { dispatch, findAll, hasClass, setAttribute, $, $$ } from "../utils/shortcuts.js";
const SELECTABLE_CLASS = "dg-selectable";
const SELECT_ALL_CLASS = "dg-select-all";
@@ -9,35 +10,52 @@ const CHECKBOX_CLASS = "form-check-input"; //bs5
* Allows to select rows
*/
class SelectableRows extends BasePlugin {
+ #cbSelector = `tbody tr${this.visibleOnly ? ":not([hidden])" : ""} .${SELECTABLE_CLASS} input[type=checkbox]`;
+ #inputSelector = `tbody .${SELECTABLE_CLASS} input`;
+
disconnected() {
if (this.selectAll) {
this.selectAll.removeEventListener("change", this);
}
}
+ get isSingleSelect() {
+ return this.grid.options.singleSelect;
+ }
+
+ get visibleOnly() {
+ return this.grid.options.selectVisibleOnly;
+ }
+
/**
- * @param {String} key Return a specific key (eg: id) instead of the whole row
- * @returns {Array}
+ * Get selected rows or fields.
+ * Returns full rows, a single field's values, or objects with specified fields.
+ * In single select mode, returns a single item.
+ * @param {...string} keys Field names to select.
+ * @returns {Array|Object} Selected data.
*/
- getSelection(key = null) {
+ getSelection(...keys) {
const grid = this.grid;
const selectedData = [];
- const inputs = findAll(grid, `tbody .${SELECTABLE_CLASS} input:checked`);
+ const inputs = findAll(grid, `${this.#inputSelector}:checked`);
for (const checkbox of inputs) {
const idx = Number.parseInt(checkbox.dataset.id);
const item = grid.data[idx - 1];
if (!item) {
console.warn(`Item ${idx} not found`);
+ continue;
}
- if (key) {
- selectedData.push(item[key]);
- } else {
+ if (keys.length === 0) {
selectedData.push(item);
+ } else if (keys.length === 1) {
+ selectedData.push(item[keys[0]]);
+ } else {
+ selectedData.push(Object.fromEntries(keys.map(k => [k, item[k]])));
}
}
- return selectedData;
+ return this.isSingleSelect ? selectedData[0] ?? {} : selectedData;
}
/**
@@ -52,6 +70,9 @@ class SelectableRows extends BasePlugin {
const inputs = findAll(tbody, `tr[hidden] .${SELECTABLE_CLASS} input`);
for (const input of inputs) {
input.checked = false;
+ if (this.isSingleSelect) {
+ input.dataset.toggled = "false"; // Reset toggled state for radio buttons
+ }
}
this.selectAll.checked = false;
}
@@ -78,6 +99,7 @@ class SelectableRows extends BasePlugin {
this.selectAll.addEventListener("change", this);
const label = document.createElement("label");
+ label.hidden = this.isSingleSelect;
label.appendChild(this.selectAll);
th.appendChild(label);
@@ -126,15 +148,21 @@ class SelectableRows extends BasePlugin {
td.classList.add(SELECTABLE_CLASS);
// Create input
- const selectOne = document.createElement("input");
+ const input = document.createElement("input");
// Alias row id for easy retrieval in getSelection
- selectOne.dataset.id = tr.getAttribute("aria-rowindex");
- selectOne.type = "checkbox";
- selectOne.classList.add(CHECKBOX_CLASS);
+ input.dataset.id = tr.getAttribute("aria-rowindex");
+ input.type = this.isSingleSelect ? "radio" : "checkbox";
+ input.classList.add(CHECKBOX_CLASS);
+ if (this.isSingleSelect) {
+ input.name = "dg-row-select";
+ input.dataset.toggled = "false";
+ }
+
// Label need to take full space thanks to css to make the whole cell clickable
const label = document.createElement("label");
label.classList.add("dg-clickable-cell");
- label.appendChild(selectOne);
+
+ label.appendChild(input);
td.appendChild(label);
// Prevent unwanted click behaviour on row
@@ -147,7 +175,17 @@ class SelectableRows extends BasePlugin {
* @param {Event} e
*/
onclick(e) {
- e.stopPropagation();
+ if (!this.isSingleSelect) return e.stopPropagation();
+
+ // Implements radio button toggle behaviour for selecting and unselecting a row
+ const el = e.target,
+ unchecked = el.dataset.toggled !== "true";
+ unchecked && $$(`${this.#cbSelector.replace("checkbox", "radio")}`, this.grid)?.forEach(r => {
+ // Uncheck all other radios in the same group and reset their data-toggled
+ if (r.name === el.name && r !== el) r.checked = r.dataset.toggled = false;
+ });
+ el.checked = el.dataset.toggled = unchecked;
+ !unchecked && this.onchange(e); // Fires rowsSelected event
}
/**
@@ -155,31 +193,20 @@ class SelectableRows extends BasePlugin {
* @param {import("../utils/shortcuts.js").FlexibleEvent} e
*/
onchange(e) {
- const grid = this.grid;
+ const el = e.target, grid = this.grid;
if (hasClass(e.target, SELECT_ALL_CLASS)) {
- const visibleOnly = grid.options.selectVisibleOnly;
- const inputs = findAll(grid, `tbody .${SELECTABLE_CLASS} input`);
- for (const cb of inputs) {
- if (visibleOnly && !cb.offsetWidth) {
- return;
- }
- cb.checked = this.selectAll.checked;
- }
- dispatch(grid, "rowsSelected", {
- selection: this.getSelection(),
- });
- } else {
- if (!e.target.closest(`.${SELECTABLE_CLASS}`)) {
- return;
- }
- const totalCheckboxes = findAll(grid, `tbody .${SELECTABLE_CLASS} input[type=checkbox]`);
- // @ts-ignore
- const totalChecked = totalCheckboxes.filter((n) => n.checked);
- this.selectAll.checked = totalChecked.length === totalCheckboxes.length;
-
- dispatch(grid, "rowsSelected", {
- selection: grid.getSelection(),
+ findAll(grid, this.#inputSelector).forEach(cb => {
+ if (!this.visibleOnly || cb.offsetWidth) cb.checked = this.selectAll.checked;
});
+ } else if (el.matches(this.#cbSelector)) {
+ if (!el.closest(`.${SELECTABLE_CLASS}`)) return;
+ const totalCheckboxes = findAll(grid, this.#cbSelector);
+ this.selectAll.checked = totalCheckboxes.every(n => n.checked);
+ }
+ if (el.matches(`.${SELECT_ALL_CLASS},${this.#inputSelector}`)) {
+ dispatch(el, "rowsSelected", {
+ selection: grid.getSelection()
+ }, true);
}
}
}
diff --git a/src/utils/normalizeData.js b/src/utils/normalizeData.js
index b9464fa..3a17060 100644
--- a/src/utils/normalizeData.js
+++ b/src/utils/normalizeData.js
@@ -20,7 +20,7 @@ export default function normalizeData(v) {
return Number(v);
}
// Only attempt json parsing for array or objects
- if (v && ["[", "{"].includes(v.substring(0, 1))) {
+ if (v && typeof v.substring === "function" && ["[", "{"].includes(v.substring(0, 1))) {
try {
// In case we have only single quoted values, like ['one', 'two', 'three']
let val = v;