@nanoporetech-digital/components 5.1.2 → 5.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (218) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/dist/cjs/{component-store-74d25f63.js → component-store-f1dc1276.js} +2 -2
  3. package/dist/cjs/{component-store-74d25f63.js.map → component-store-f1dc1276.js.map} +1 -1
  4. package/dist/cjs/index.cjs.js +1 -1
  5. package/dist/cjs/loader.cjs.js +1 -1
  6. package/dist/cjs/nano-algolia-filter.cjs.entry.js +2 -2
  7. package/dist/cjs/nano-algolia-input.cjs.entry.js +2 -2
  8. package/dist/cjs/nano-algolia.cjs.entry.js +2 -2
  9. package/dist/cjs/nano-checkbox-group.cjs.entry.js +5 -1
  10. package/dist/cjs/nano-checkbox-group.cjs.entry.js.map +1 -1
  11. package/dist/cjs/nano-components.cjs.js +1 -1
  12. package/dist/cjs/nano-datalist_3.cjs.entry.js +14 -5
  13. package/dist/cjs/nano-datalist_3.cjs.entry.js.map +1 -1
  14. package/dist/cjs/nano-dialog.cjs.entry.js +2 -2
  15. package/dist/cjs/nano-global-nav-user-profile_3.cjs.entry.js +8 -5
  16. package/dist/cjs/nano-global-nav-user-profile_3.cjs.entry.js.map +1 -1
  17. package/dist/cjs/nano-global-nav.cjs.entry.js +2 -2
  18. package/dist/cjs/nano-input.cjs.entry.js +3 -3
  19. package/dist/cjs/nano-input.cjs.entry.js.map +1 -1
  20. package/dist/cjs/nano-overflow-nav.cjs.entry.js +1 -1
  21. package/dist/cjs/nano-range.cjs.entry.js +1 -1
  22. package/dist/cjs/nano-resize-observe_2.cjs.entry.js +3 -1
  23. package/dist/cjs/nano-resize-observe_2.cjs.entry.js.map +1 -1
  24. package/dist/cjs/nano-sortable.cjs.entry.js +18 -8
  25. package/dist/cjs/nano-sortable.cjs.entry.js.map +1 -1
  26. package/dist/cjs/nano-split-pane.cjs.entry.js +1 -1
  27. package/dist/cjs/nano-sticker.cjs.entry.js +4 -2
  28. package/dist/cjs/nano-sticker.cjs.entry.js.map +1 -1
  29. package/dist/cjs/nano-tab-group.cjs.entry.js +2 -2
  30. package/dist/cjs/{nano-table-0a720c5f.js → nano-table-04993bb4.js} +560 -186
  31. package/dist/cjs/nano-table-04993bb4.js.map +1 -0
  32. package/dist/cjs/nano-table.cjs.entry.js +2 -2
  33. package/dist/cjs/{table.worker-347d4d31.js → table.worker-85877b23.js} +4 -4
  34. package/dist/cjs/table.worker-85877b23.js.map +1 -0
  35. package/dist/cjs/{table.worker-bd51e29f.js → table.worker-f258383d.js} +1 -1
  36. package/dist/cjs/{throttle-f55496c8.js → throttle-dfa64b9e.js} +17 -20
  37. package/dist/cjs/throttle-dfa64b9e.js.map +1 -0
  38. package/dist/collection/components/checkbox/checkbox-group.js +4 -0
  39. package/dist/collection/components/checkbox/checkbox-group.js.map +1 -1
  40. package/dist/collection/components/datalist/datalist.js +13 -4
  41. package/dist/collection/components/datalist/datalist.js.map +1 -1
  42. package/dist/collection/components/input/input.css +1 -1
  43. package/dist/collection/components/input/input.js +1 -1
  44. package/dist/collection/components/input/input.js.map +1 -1
  45. package/dist/collection/components/nav-item/nav-item.js +6 -3
  46. package/dist/collection/components/nav-item/nav-item.js.map +1 -1
  47. package/dist/collection/components/resize-observe/resize-observe.js +21 -1
  48. package/dist/collection/components/resize-observe/resize-observe.js.map +1 -1
  49. package/dist/collection/components/select/select.css +1 -2
  50. package/dist/collection/components/sortable/sortable.js +5 -7
  51. package/dist/collection/components/sortable/sortable.js.map +1 -1
  52. package/dist/collection/components/sticker/sticker.js +11 -5
  53. package/dist/collection/components/sticker/sticker.js.map +1 -1
  54. package/dist/collection/components/table/table-interface.js.map +1 -1
  55. package/dist/collection/components/table/table.cell.js +43 -10
  56. package/dist/collection/components/table/table.cell.js.map +1 -1
  57. package/dist/collection/components/table/table.css +38 -55
  58. package/dist/collection/components/table/table.header.js +4 -9
  59. package/dist/collection/components/table/table.header.js.map +1 -1
  60. package/dist/collection/components/table/table.js +104 -48
  61. package/dist/collection/components/table/table.js.map +1 -1
  62. package/dist/collection/components/table/table.pin-service.js +382 -0
  63. package/dist/collection/components/table/table.pin-service.js.map +1 -0
  64. package/dist/collection/components/table/table.row.js +39 -46
  65. package/dist/collection/components/table/table.row.js.map +1 -1
  66. package/dist/collection/components/table/table.utils.js +0 -124
  67. package/dist/collection/components/table/table.utils.js.map +1 -1
  68. package/dist/collection/components/table/table.worker.js +1 -0
  69. package/dist/collection/components/table/table.worker.js.map +1 -1
  70. package/dist/collection/utils/events.js +27 -0
  71. package/dist/collection/utils/events.js.map +1 -0
  72. package/dist/collection/utils/throttle.js +16 -19
  73. package/dist/collection/utils/throttle.js.map +1 -1
  74. package/dist/components/datalist.js +13 -4
  75. package/dist/components/datalist.js.map +1 -1
  76. package/dist/components/input.js +2 -2
  77. package/dist/components/input.js.map +1 -1
  78. package/dist/components/nano-checkbox-group.js +4 -0
  79. package/dist/components/nano-checkbox-group.js.map +1 -1
  80. package/dist/components/nano-sortable.js +17 -7
  81. package/dist/components/nano-sortable.js.map +1 -1
  82. package/dist/components/nav-item.js +6 -3
  83. package/dist/components/nav-item.js.map +1 -1
  84. package/dist/components/resize-observe.js +3 -1
  85. package/dist/components/resize-observe.js.map +1 -1
  86. package/dist/components/select.js +1 -1
  87. package/dist/components/select.js.map +1 -1
  88. package/dist/components/sticker.js +3 -1
  89. package/dist/components/sticker.js.map +1 -1
  90. package/dist/components/table.js +533 -188
  91. package/dist/components/table.js.map +1 -1
  92. package/dist/components/table.worker.js +1 -1
  93. package/dist/components/throttle.js +16 -19
  94. package/dist/components/throttle.js.map +1 -1
  95. package/dist/esm/{component-store-244a8431.js → component-store-c23ebc9c.js} +2 -2
  96. package/dist/esm/{component-store-244a8431.js.map → component-store-c23ebc9c.js.map} +1 -1
  97. package/dist/esm/index.js +1 -1
  98. package/dist/esm/loader.js +1 -1
  99. package/dist/esm/nano-algolia-filter.entry.js +2 -2
  100. package/dist/esm/nano-algolia-input.entry.js +2 -2
  101. package/dist/esm/nano-algolia.entry.js +2 -2
  102. package/dist/esm/nano-checkbox-group.entry.js +5 -1
  103. package/dist/esm/nano-checkbox-group.entry.js.map +1 -1
  104. package/dist/esm/nano-components.js +1 -1
  105. package/dist/esm/nano-datalist_3.entry.js +14 -5
  106. package/dist/esm/nano-datalist_3.entry.js.map +1 -1
  107. package/dist/esm/nano-dialog.entry.js +2 -2
  108. package/dist/esm/nano-global-nav-user-profile_3.entry.js +8 -5
  109. package/dist/esm/nano-global-nav-user-profile_3.entry.js.map +1 -1
  110. package/dist/esm/nano-global-nav.entry.js +2 -2
  111. package/dist/esm/nano-input.entry.js +3 -3
  112. package/dist/esm/nano-input.entry.js.map +1 -1
  113. package/dist/esm/nano-overflow-nav.entry.js +1 -1
  114. package/dist/esm/nano-range.entry.js +1 -1
  115. package/dist/esm/nano-resize-observe_2.entry.js +3 -1
  116. package/dist/esm/nano-resize-observe_2.entry.js.map +1 -1
  117. package/dist/esm/nano-sortable.entry.js +18 -8
  118. package/dist/esm/nano-sortable.entry.js.map +1 -1
  119. package/dist/esm/nano-split-pane.entry.js +1 -1
  120. package/dist/esm/nano-sticker.entry.js +4 -2
  121. package/dist/esm/nano-sticker.entry.js.map +1 -1
  122. package/dist/esm/nano-tab-group.entry.js +2 -2
  123. package/dist/esm/{nano-table-9767860f.js → nano-table-91f09583.js} +561 -187
  124. package/dist/esm/nano-table-91f09583.js.map +1 -0
  125. package/dist/esm/nano-table.entry.js +2 -2
  126. package/dist/esm/{table.worker-d252307c.js → table.worker-625475ba.js} +4 -4
  127. package/dist/esm/table.worker-625475ba.js.map +1 -0
  128. package/dist/esm/{table.worker-bd51e29f.js → table.worker-f258383d.js} +1 -1
  129. package/dist/esm/{throttle-7836544e.js → throttle-ac4fcefa.js} +17 -20
  130. package/dist/esm/throttle-ac4fcefa.js.map +1 -0
  131. package/dist/nano-components/index.esm.js +1 -1
  132. package/dist/nano-components/nano-components.esm.js +1 -1
  133. package/dist/nano-components/nano-components.esm.js.map +1 -1
  134. package/dist/nano-components/{p-7d6065c6.entry.js → p-0697795a.entry.js} +2 -2
  135. package/dist/nano-components/p-0697795a.entry.js.map +1 -0
  136. package/dist/nano-components/p-17ee0c07.entry.js +5 -0
  137. package/dist/nano-components/{p-6975f110.entry.js → p-192902e0.entry.js} +2 -2
  138. package/dist/nano-components/{p-a6ff5ca6.js → p-1a0b5bc3.js} +2 -2
  139. package/dist/nano-components/{p-3a761d77.entry.js → p-1b791810.entry.js} +2 -2
  140. package/dist/nano-components/p-3de3449e.js +5 -0
  141. package/dist/nano-components/p-3de3449e.js.map +1 -0
  142. package/dist/nano-components/p-3eb6d833.entry.js +5 -0
  143. package/dist/nano-components/p-3eb6d833.entry.js.map +1 -0
  144. package/dist/nano-components/{p-a1c0afb6.entry.js → p-4884b65a.entry.js} +2 -2
  145. package/dist/nano-components/{p-75735a91.entry.js → p-565793a2.entry.js} +2 -2
  146. package/dist/nano-components/p-565793a2.entry.js.map +1 -0
  147. package/dist/nano-components/p-5aae2588.entry.js +5 -0
  148. package/dist/nano-components/p-5aae2588.entry.js.map +1 -0
  149. package/dist/nano-components/{p-935aef3d.entry.js → p-6920ad69.entry.js} +2 -2
  150. package/dist/nano-components/{p-1c6c94cb.entry.js → p-7baa9e14.entry.js} +2 -2
  151. package/dist/nano-components/p-7bff5224.js +5 -0
  152. package/dist/nano-components/p-7bff5224.js.map +1 -0
  153. package/dist/nano-components/{p-f60fe933.entry.js → p-898cbac7.entry.js} +2 -2
  154. package/dist/nano-components/{p-ace1ffc2.entry.js → p-a362bd23.entry.js} +2 -2
  155. package/dist/nano-components/{p-eb6c9191.entry.js → p-b72df1aa.entry.js} +2 -2
  156. package/dist/nano-components/p-bf18e298.entry.js +5 -0
  157. package/dist/nano-components/p-bf18e298.entry.js.map +1 -0
  158. package/dist/nano-components/p-ce5efc3f.entry.js +5 -0
  159. package/dist/nano-components/p-ce5efc3f.entry.js.map +1 -0
  160. package/dist/nano-components/{p-1b687f96.entry.js → p-d0eefd52.entry.js} +2 -2
  161. package/dist/nano-components/{p-2d43a82b.entry.js → p-d74e2642.entry.js} +2 -2
  162. package/dist/nano-components/p-d74e2642.entry.js.map +1 -0
  163. package/dist/nano-components/p-dfbf0d56.js +5 -0
  164. package/dist/nano-components/{p-bd51e29f.js → p-f258383d.js} +1 -1
  165. package/dist/types/components/datalist/datalist.d.ts +1 -0
  166. package/dist/types/components/nav-item/nav-item.d.ts +1 -1
  167. package/dist/types/components/resize-observe/resize-observe.d.ts +2 -0
  168. package/dist/types/components/sortable/sortable.d.ts +0 -1
  169. package/dist/types/components/sticker/sticker.d.ts +2 -2
  170. package/dist/types/components/table/table-interface.d.ts +23 -11
  171. package/dist/types/components/table/table.cell.d.ts +0 -7
  172. package/dist/types/components/table/table.d.ts +10 -7
  173. package/dist/types/components/table/table.header.d.ts +0 -1
  174. package/dist/types/components/table/table.pin-service.d.ts +90 -0
  175. package/dist/types/components/table/table.row.d.ts +3 -2
  176. package/dist/types/components/table/table.utils.d.ts +0 -27
  177. package/dist/types/components.d.ts +29 -11
  178. package/dist/types/utils/events.d.ts +15 -0
  179. package/dist/types/utils/throttle.d.ts +1 -1
  180. package/docs-json.json +59 -24
  181. package/docs-vscode.json +2 -2
  182. package/hydrate/index.js +610 -204
  183. package/package.json +2 -2
  184. package/dist/cjs/nano-table-0a720c5f.js.map +0 -1
  185. package/dist/cjs/table.worker-347d4d31.js.map +0 -1
  186. package/dist/cjs/throttle-f55496c8.js.map +0 -1
  187. package/dist/esm/nano-table-9767860f.js.map +0 -1
  188. package/dist/esm/table.worker-d252307c.js.map +0 -1
  189. package/dist/esm/throttle-7836544e.js.map +0 -1
  190. package/dist/nano-components/p-15217442.entry.js +0 -5
  191. package/dist/nano-components/p-15217442.entry.js.map +0 -1
  192. package/dist/nano-components/p-2d43a82b.entry.js.map +0 -1
  193. package/dist/nano-components/p-633c778c.js +0 -5
  194. package/dist/nano-components/p-633c778c.js.map +0 -1
  195. package/dist/nano-components/p-66631f50.js +0 -5
  196. package/dist/nano-components/p-75735a91.entry.js.map +0 -1
  197. package/dist/nano-components/p-7d6065c6.entry.js.map +0 -1
  198. package/dist/nano-components/p-8a79a7ca.entry.js +0 -5
  199. package/dist/nano-components/p-9746b0a5.js +0 -5
  200. package/dist/nano-components/p-9746b0a5.js.map +0 -1
  201. package/dist/nano-components/p-b0c60290.entry.js +0 -5
  202. package/dist/nano-components/p-b0c60290.entry.js.map +0 -1
  203. package/dist/nano-components/p-c8ccb57a.entry.js +0 -5
  204. package/dist/nano-components/p-c8ccb57a.entry.js.map +0 -1
  205. package/dist/nano-components/p-d1a5326f.entry.js +0 -5
  206. package/dist/nano-components/p-d1a5326f.entry.js.map +0 -1
  207. /package/dist/nano-components/{p-66631f50.js.map → p-17ee0c07.entry.js.map} +0 -0
  208. /package/dist/nano-components/{p-6975f110.entry.js.map → p-192902e0.entry.js.map} +0 -0
  209. /package/dist/nano-components/{p-a6ff5ca6.js.map → p-1a0b5bc3.js.map} +0 -0
  210. /package/dist/nano-components/{p-3a761d77.entry.js.map → p-1b791810.entry.js.map} +0 -0
  211. /package/dist/nano-components/{p-a1c0afb6.entry.js.map → p-4884b65a.entry.js.map} +0 -0
  212. /package/dist/nano-components/{p-935aef3d.entry.js.map → p-6920ad69.entry.js.map} +0 -0
  213. /package/dist/nano-components/{p-1c6c94cb.entry.js.map → p-7baa9e14.entry.js.map} +0 -0
  214. /package/dist/nano-components/{p-f60fe933.entry.js.map → p-898cbac7.entry.js.map} +0 -0
  215. /package/dist/nano-components/{p-ace1ffc2.entry.js.map → p-a362bd23.entry.js.map} +0 -0
  216. /package/dist/nano-components/{p-eb6c9191.entry.js.map → p-b72df1aa.entry.js.map} +0 -0
  217. /package/dist/nano-components/{p-1b687f96.entry.js.map → p-d0eefd52.entry.js.map} +0 -0
  218. /package/dist/nano-components/{p-8a79a7ca.entry.js.map → p-dfbf0d56.js.map} +0 -0
@@ -0,0 +1,382 @@
1
+ /*!
2
+ * Web Components for Nanopore digital Web Apps
3
+ */
4
+ import { readTask, writeTask } from '@stencil/core';
5
+ import { CSSNAMESPACE } from './table.constants';
6
+ function addStyleSheet(id, css) {
7
+ const styleSheet = document.getElementById(id) ||
8
+ document.createElement('style');
9
+ styleSheet.id = id;
10
+ styleSheet.innerHTML = css;
11
+ if (!styleSheet.isConnected)
12
+ document.head.append(styleSheet);
13
+ }
14
+ /**
15
+ * Manages the complex business of table 'pinning'; sticking columns and rows to the scrolling parent element.
16
+ *
17
+ * *knowing* when an element is pinned is tricky.
18
+ * Managing the display of multiple, side-by-side pinned elements is trickier still.
19
+ *
20
+ * Pinning table columns are very different from pinning table rows:
21
+ * - Rows are actual elements we can select, measure and apply styles to.
22
+ * - Columns are disparate collections of elements that are much harder to select, measure and apply styles to.
23
+ *
24
+ * With this in mind, how columns and rows are pinned is different:
25
+ * Rows can have changes applied directly, Columns have changes applied via dynamic stylesheets.
26
+ *
27
+ * The service is slightly opinionated on how it pins rows and columns (with some room for override):
28
+ * - Pinned columns are stuck consecutively, without overlapping.
29
+ * e.g. If column 'name' and 'surname' are both `pin: 'start'`; 'surname' will display **next** to name.
30
+ * Both columns are important for context
31
+ *
32
+ * - Pinned rows are set to overlap *when* they have the same ancestor,
33
+ * and stuck consecutively when they have a different ancestor.
34
+ * e.g. `tbody > tr.pin ~ tr.pin` the second row will **overlap** the first; it's unlikely both rows will be important for context.
35
+ * `thead > tr.pin`, `tbody > tr.pin`. Both rows are required for context so will require next to each other.
36
+ *
37
+ * Devs can override this behaviour by setting `--pin-start`, `--pin-end`, `--pin-top`, `--pin-bottom` custom vars.
38
+ */
39
+ export class TablePinService {
40
+ constructor(table, scrollElement) {
41
+ // Private state
42
+ this.cachedColMeta = new WeakMap();
43
+ this._pinnedStart = [];
44
+ this._pinnedEnd = [];
45
+ this._cssColDimensionCacheKey = '';
46
+ this.cacheX = 0;
47
+ this.cacheY = 0;
48
+ this.tableEle = table;
49
+ this.tableId = this.tableEle.id;
50
+ this.scrollElement = scrollElement;
51
+ // Secret sauce - `getElementsByClassName` is a live collection.
52
+ // An HTMLCollection will keep itself up-to-date as elements come and go
53
+ // So we can keep assessing on scroll
54
+ this.startColumns = table
55
+ .querySelector('thead')
56
+ .getElementsByClassName(`${CSSNAMESPACE}__pin--start`);
57
+ this.endColumns = table
58
+ .querySelector('thead')
59
+ .getElementsByClassName(`${CSSNAMESPACE}__pin--end`);
60
+ this.topRows = table.getElementsByClassName(`${CSSNAMESPACE}__pin--top`);
61
+ this.bottomRows = table.getElementsByClassName(`${CSSNAMESPACE}__pin--bottom`);
62
+ this.onResize();
63
+ }
64
+ // Pinned cols & change detection
65
+ get pinnedStart() {
66
+ return this._pinnedStart;
67
+ }
68
+ set pinnedStart(cols) {
69
+ this._pinnedStart = cols;
70
+ this.handlePinnedStartChange();
71
+ }
72
+ /**
73
+ * Called when columns are either pinned or unpinned.
74
+ * Attaches a tiny stylesheet to target the 'last' start column.
75
+ * (e.g. We only want to apply drop shadow on last pinned start column - not all pinned columns)
76
+ */
77
+ handlePinnedStartChange() {
78
+ writeTask(() => {
79
+ if (this.pinnedStart.length) {
80
+ this.tableEle.classList.add(`${CSSNAMESPACE}__pinned--start`);
81
+ const lastActiveCol = this.cachedColMeta.get(this.pinnedStart[this.pinnedStart.length - 1]);
82
+ addStyleSheet(`${this.tableId}-col-start-active-style`,
83
+ /* css */ `
84
+ #${this.tableId} tr > :nth-child(${lastActiveCol.idx + 1}) {
85
+ --pin-start-active: 1;
86
+ }
87
+ `);
88
+ }
89
+ else {
90
+ this.tableEle.classList.remove(`${CSSNAMESPACE}__pinned--start`);
91
+ addStyleSheet(`${this.tableId}-col-start-active-style`, ``);
92
+ }
93
+ });
94
+ }
95
+ get pinnedEnd() {
96
+ return this._pinnedEnd;
97
+ }
98
+ set pinnedEnd(cols) {
99
+ this._pinnedEnd = cols;
100
+ this.handlePinnedEndChange();
101
+ }
102
+ /**
103
+ * Called when columns are either pinned or unpinned.
104
+ * Attaches a tiny stylesheet to target the 'first' end column.
105
+ * (e.g. We only want to apply drop shadow on first pinned end column - not all pinned columns)
106
+ */
107
+ handlePinnedEndChange() {
108
+ writeTask(() => {
109
+ if (this.pinnedEnd.length) {
110
+ this.tableEle.classList.add(`${CSSNAMESPACE}__pinned--end`);
111
+ const firstActiveCol = this.cachedColMeta.get(this.pinnedEnd[0]);
112
+ addStyleSheet(`${this.tableId}-col-end-active-style`,
113
+ /* css */ `
114
+ #${this.tableId} tr > :nth-child(${firstActiveCol.idx + 1}) { --pin-end-active: 1; }
115
+ `);
116
+ }
117
+ else {
118
+ this.tableEle.classList.remove(`${CSSNAMESPACE}__pinned--end`);
119
+ addStyleSheet(`${this.tableId}-col-end-active-style`, ``);
120
+ }
121
+ });
122
+ }
123
+ get cssColDimensionCacheKey() {
124
+ return this._cssColDimensionCacheKey;
125
+ }
126
+ set cssColDimensionCacheKey(key) {
127
+ if (key === this._cssColDimensionCacheKey)
128
+ return;
129
+ this._cssColDimensionCacheKey = key;
130
+ this.createPinnedColDimensionStyles();
131
+ }
132
+ /**
133
+ * To only generate column dimension styles when necessary we
134
+ * maintain a cache key string via serialised column meta.
135
+ * Only when this key changes do we generate a new stylesheet
136
+ */
137
+ generateCssCacheKey() {
138
+ let key = '';
139
+ for (const col of this.startColumns) {
140
+ const colMeta = this.cachedColMeta.get(col);
141
+ key += `${colMeta.idx}-start-${colMeta.width}`;
142
+ }
143
+ for (const col of this.endColumns) {
144
+ const colMeta = this.cachedColMeta.get(col);
145
+ key += `${colMeta.idx}-start-${colMeta.width}`;
146
+ }
147
+ this.cssColDimensionCacheKey = key;
148
+ }
149
+ /**
150
+ * Generates pinned column width offset styles
151
+ * so pinned columns can appear stuck together,
152
+ * then attaches a stylesheet.
153
+ */
154
+ createPinnedColDimensionStyles() {
155
+ let widthS = 0;
156
+ let widthE = 0;
157
+ const startCols = Array.from(this.startColumns);
158
+ const endCols = Array.from(this.endColumns).reverse();
159
+ const css = /* css */ `
160
+ ${startCols
161
+ .map((col) => {
162
+ const colMeta = this.cachedColMeta.get(col);
163
+ widthS += colMeta.width || 0;
164
+ return /* css */ `
165
+ #${this.tableId} tr > :nth-child(${colMeta.idx + 1}) ~ td,
166
+ #${this.tableId} tr > :nth-child(${colMeta.idx + 1}) ~ th {
167
+ --pin-start: ${widthS - 1}px;
168
+ }
169
+ `;
170
+ })
171
+ .join('')}
172
+ ${endCols
173
+ .map((col) => {
174
+ const colMeta = this.cachedColMeta.get(col);
175
+ widthE += colMeta.width;
176
+ return /* css */ `
177
+ #${this.tableId} tr > td:has(~ :nth-child(${colMeta.idx + 1})),
178
+ #${this.tableId} tr > th:has(~ :nth-child(${colMeta.idx + 1})) {
179
+ --pin-end: ${widthE - 1}px;
180
+ }
181
+ `;
182
+ })
183
+ .join('')}
184
+ `;
185
+ addStyleSheet(`${this.tableId}-dimension-style`, css);
186
+ }
187
+ getParentOffsets() {
188
+ const { x, y } = this.scrollElement.getBoundingClientRect();
189
+ let offsetX = x;
190
+ let offsetY = y;
191
+ if (this.scrollElement === document.documentElement) {
192
+ offsetX = this.scrollElement.offsetLeft;
193
+ offsetY = this.scrollElement.offsetTop;
194
+ }
195
+ return { offsetX, offsetY };
196
+ }
197
+ /**
198
+ * Loops through all 'top' & 'bottom' rows (on scroll or resize)
199
+ * Manages their visual state by applying classes on stuck / unstuck
200
+ * And their pinned offset / distance
201
+ */
202
+ assessRows() {
203
+ if (!this.topRows.length && !this.bottomRows.length)
204
+ return;
205
+ // top rows
206
+ if (this.topRows.length) {
207
+ readTask(async () => {
208
+ let heightAggregate = 0;
209
+ let cacheParent;
210
+ const { offsetY } = this.getParentOffsets();
211
+ for (const topRow of this.topRows) {
212
+ const { y, height } = topRow.getBoundingClientRect();
213
+ const currParent = topRow.parentElement;
214
+ // we'll use the applied `--pin-top` css var to decide row offset.
215
+ // This allows devs to override this behaviour through selector specificity
216
+ const pinTop = getComputedStyle(topRow).getPropertyValue('--pin-top');
217
+ const offset = pinTop !== '' ? parseFloat(pinTop) : heightAggregate;
218
+ // we need to wait for the row to finish sticking
219
+ // and generating it's offset (`--pin-top`) so we can see, on
220
+ // subsequent rows *if* the offset was applied
221
+ await new Promise((resolve) => writeTask(() => {
222
+ if (y - offsetY <= offset) {
223
+ topRow.classList.add(`${CSSNAMESPACE}__pinned`, `${CSSNAMESPACE}__pinned--top`);
224
+ }
225
+ else {
226
+ topRow.classList.remove(`${CSSNAMESPACE}__pinned`, `${CSSNAMESPACE}__pinned--top`);
227
+ }
228
+ // by default, we only want to stick one row from each parental block (thead, tbody, tfoot)
229
+ // so only aggregate height / offset when cacheParent is different from current parent.
230
+ // Devs can override this behaviour by manually setting `--pin-bottom` on the table row
231
+ if (cacheParent !== currParent) {
232
+ currParent.style.setProperty('--pin-top', `${heightAggregate}px`);
233
+ heightAggregate += height;
234
+ cacheParent = currParent;
235
+ }
236
+ resolve();
237
+ }));
238
+ }
239
+ });
240
+ }
241
+ // bottom rows
242
+ if (this.bottomRows.length) {
243
+ const bottomRows = Array.from(this.bottomRows).reverse();
244
+ readTask(async () => {
245
+ let cacheParent;
246
+ let heightAggregate = 0;
247
+ const { offsetY } = this.getParentOffsets();
248
+ for (const bottomRow of bottomRows) {
249
+ if (!bottomRow.isConnected)
250
+ continue;
251
+ const { y, height } = bottomRow.getBoundingClientRect();
252
+ const currParent = bottomRow.parentElement;
253
+ // we'll use the applied `--pin-bottom` css var to decide row offset.
254
+ // This allows devs to override this behaviour through selector specificity
255
+ const pinBottom = getComputedStyle(bottomRow).getPropertyValue('--pin-bottom');
256
+ const offset = pinBottom !== '' ? parseFloat(pinBottom) : heightAggregate;
257
+ // we need to wait for the row to finish sticking
258
+ // and generating it's offset (`--pin-bottom`) to we can see, on
259
+ // subsequent rows *if* the offset was applied
260
+ await new Promise((resolve) => writeTask(() => {
261
+ if (this.tableDims.height + offsetY - (y + height) <= offset) {
262
+ bottomRow.classList.add(`${CSSNAMESPACE}__pinned`, `${CSSNAMESPACE}__pinned--bottom`);
263
+ }
264
+ else {
265
+ bottomRow.classList.remove(`${CSSNAMESPACE}__pinned`, `${CSSNAMESPACE}__pinned--bottom`);
266
+ }
267
+ // by default, we only want to stick one row from each parental block (thead, tbody, tfoot)
268
+ // so only aggregate height / offset when cacheParent is different from current parent.
269
+ // Devs can override this behaviour by manually setting `--pin-bottom` on the table row
270
+ if (cacheParent !== currParent) {
271
+ currParent.style.setProperty('--pin-bottom', `${heightAggregate}px`);
272
+ heightAggregate += height;
273
+ cacheParent = currParent;
274
+ }
275
+ resolve();
276
+ }));
277
+ }
278
+ });
279
+ }
280
+ }
281
+ /**
282
+ * Loops through all 'start' & 'end' columns (on scroll or resize)
283
+ * Caches meta about each column (e.g. size, position-index)
284
+ * and decides which columns are pinned
285
+ */
286
+ async assessCols() {
287
+ if (!this.startColumns.length && !this.endColumns.length)
288
+ return;
289
+ let boundBox;
290
+ let currPinned;
291
+ let parentEles;
292
+ const done = new Promise((resolve) => {
293
+ // start cols
294
+ if (this.startColumns.length) {
295
+ readTask(() => {
296
+ const { offsetX } = this.getParentOffsets();
297
+ // cumulatively add widths of columns together
298
+ // 'cos columns stick together
299
+ let widthAggregate = offsetX;
300
+ parentEles = Array.from(this.startColumns[0].parentElement.children);
301
+ for (const startCol of this.startColumns) {
302
+ boundBox = startCol.getBoundingClientRect();
303
+ // cache meta for later
304
+ this.cachedColMeta.set(startCol, {
305
+ width: boundBox.width,
306
+ idx: parentEles.indexOf(startCol),
307
+ });
308
+ currPinned = this.pinnedStart.find((c) => c === startCol);
309
+ if (boundBox.x < widthAggregate) {
310
+ // this column is pinned
311
+ if (!currPinned)
312
+ this.pinnedStart = [
313
+ ...this.pinnedStart,
314
+ startCol,
315
+ ];
316
+ }
317
+ else if (currPinned) {
318
+ // this column is unpinned
319
+ this.pinnedStart = this.pinnedStart.filter((c) => c !== startCol);
320
+ }
321
+ widthAggregate += boundBox.width;
322
+ }
323
+ if (!this.endColumns.length)
324
+ resolve();
325
+ });
326
+ }
327
+ // end cols
328
+ if (this.endColumns.length) {
329
+ readTask(() => {
330
+ const endCols = Array.from(this.endColumns).reverse();
331
+ parentEles = Array.from(this.endColumns[0].parentElement.children);
332
+ const { offsetX } = this.getParentOffsets();
333
+ // cumulatively add widths of columns together
334
+ // 'cos columns stick together
335
+ let widthAggregate = 0;
336
+ for (const endCol of endCols) {
337
+ boundBox = endCol.getBoundingClientRect();
338
+ // cache meta for later
339
+ this.cachedColMeta.set(endCol, {
340
+ width: boundBox.width,
341
+ idx: parentEles.indexOf(endCol),
342
+ });
343
+ currPinned = this.pinnedEnd.find((c) => c === endCol);
344
+ if (this.tableDims.width + offsetX - boundBox.right <=
345
+ widthAggregate) {
346
+ // this column is pinned
347
+ if (!currPinned)
348
+ this.pinnedEnd = [endCol, ...this.pinnedEnd];
349
+ }
350
+ else if (currPinned) {
351
+ // this column is unpinned
352
+ this.pinnedEnd = this.pinnedEnd.filter((c) => c !== endCol);
353
+ }
354
+ widthAggregate += boundBox.width;
355
+ }
356
+ resolve();
357
+ });
358
+ }
359
+ });
360
+ await done;
361
+ // potentially generate a new css stylesheet if anything changed
362
+ this.generateCssCacheKey();
363
+ }
364
+ onScroll(pos) {
365
+ if (this.cacheX !== pos.x) {
366
+ this.cacheX = pos.x;
367
+ this.assessCols();
368
+ }
369
+ if (this.cacheY !== pos.y) {
370
+ this.cacheY = pos.y;
371
+ this.assessRows();
372
+ }
373
+ }
374
+ onResize() {
375
+ const width = this.scrollElement.clientWidth;
376
+ const height = this.scrollElement.clientHeight;
377
+ this.tableDims = { width, height };
378
+ this.assessCols();
379
+ this.assessRows();
380
+ }
381
+ }
382
+ //# sourceMappingURL=table.pin-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"table.pin-service.js","sourceRoot":"","sources":["../../../src/components/table/table.pin-service.ts"],"names":[],"mappings":"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","sourcesContent":["import { readTask, writeTask } from '@stencil/core';\nimport { CSSNAMESPACE } from './table.constants';\n\nfunction addStyleSheet(id, css) {\n const styleSheet =\n (document.getElementById(id) as HTMLStyleElement) ||\n document.createElement('style');\n styleSheet.id = id;\n styleSheet.innerHTML = css;\n if (!styleSheet.isConnected) document.head.append(styleSheet);\n}\n\n/**\n * Manages the complex business of table 'pinning'; sticking columns and rows to the scrolling parent element.\n *\n * *knowing* when an element is pinned is tricky.\n * Managing the display of multiple, side-by-side pinned elements is trickier still.\n *\n * Pinning table columns are very different from pinning table rows:\n * - Rows are actual elements we can select, measure and apply styles to.\n * - Columns are disparate collections of elements that are much harder to select, measure and apply styles to.\n *\n * With this in mind, how columns and rows are pinned is different:\n * Rows can have changes applied directly, Columns have changes applied via dynamic stylesheets.\n *\n * The service is slightly opinionated on how it pins rows and columns (with some room for override):\n * - Pinned columns are stuck consecutively, without overlapping.\n * e.g. If column 'name' and 'surname' are both `pin: 'start'`; 'surname' will display **next** to name.\n * Both columns are important for context\n *\n * - Pinned rows are set to overlap *when* they have the same ancestor,\n * and stuck consecutively when they have a different ancestor.\n * e.g. `tbody > tr.pin ~ tr.pin` the second row will **overlap** the first; it's unlikely both rows will be important for context.\n * `thead > tr.pin`, `tbody > tr.pin`. Both rows are required for context so will require next to each other.\n *\n * Devs can override this behaviour by setting `--pin-start`, `--pin-end`, `--pin-top`, `--pin-bottom` custom vars.\n */\nexport class TablePinService {\n // Private state\n\n private cachedColMeta: WeakMap<HTMLElement, { width: number; idx: number }> =\n new WeakMap();\n private tableId: string;\n private tableEle: HTMLTableElement;\n private scrollElement: HTMLElement;\n private startColumns: HTMLCollection;\n private endColumns: HTMLCollection;\n private topRows: HTMLCollection;\n private bottomRows: HTMLCollection;\n private tableDims: { height: number; width: number };\n\n constructor(table: HTMLTableElement, scrollElement: HTMLElement) {\n this.tableEle = table;\n this.tableId = this.tableEle.id;\n this.scrollElement = scrollElement;\n\n // Secret sauce - `getElementsByClassName` is a live collection.\n // An HTMLCollection will keep itself up-to-date as elements come and go\n // So we can keep assessing on scroll\n\n this.startColumns = table\n .querySelector('thead')\n .getElementsByClassName(`${CSSNAMESPACE}__pin--start`);\n this.endColumns = table\n .querySelector('thead')\n .getElementsByClassName(`${CSSNAMESPACE}__pin--end`);\n this.topRows = table.getElementsByClassName(`${CSSNAMESPACE}__pin--top`);\n this.bottomRows = table.getElementsByClassName(\n `${CSSNAMESPACE}__pin--bottom`\n );\n this.onResize();\n }\n\n // Pinned cols & change detection\n private get pinnedStart() {\n return this._pinnedStart;\n }\n private set pinnedStart(cols: HTMLElement[]) {\n this._pinnedStart = cols;\n this.handlePinnedStartChange();\n }\n private _pinnedStart: HTMLElement[] = [];\n\n /**\n * Called when columns are either pinned or unpinned.\n * Attaches a tiny stylesheet to target the 'last' start column.\n * (e.g. We only want to apply drop shadow on last pinned start column - not all pinned columns)\n */\n private handlePinnedStartChange() {\n writeTask(() => {\n if (this.pinnedStart.length) {\n this.tableEle.classList.add(`${CSSNAMESPACE}__pinned--start`);\n const lastActiveCol = this.cachedColMeta.get(\n this.pinnedStart[this.pinnedStart.length - 1]\n );\n\n addStyleSheet(\n `${this.tableId}-col-start-active-style`,\n /* css */ `\n #${this.tableId} tr > :nth-child(${lastActiveCol.idx + 1}) {\n --pin-start-active: 1;\n }\n `\n );\n } else {\n this.tableEle.classList.remove(`${CSSNAMESPACE}__pinned--start`);\n addStyleSheet(`${this.tableId}-col-start-active-style`, ``);\n }\n });\n }\n\n private get pinnedEnd() {\n return this._pinnedEnd;\n }\n private set pinnedEnd(cols: HTMLElement[]) {\n this._pinnedEnd = cols;\n this.handlePinnedEndChange();\n }\n private _pinnedEnd: HTMLElement[] = [];\n\n /**\n * Called when columns are either pinned or unpinned.\n * Attaches a tiny stylesheet to target the 'first' end column.\n * (e.g. We only want to apply drop shadow on first pinned end column - not all pinned columns)\n */\n private handlePinnedEndChange() {\n writeTask(() => {\n if (this.pinnedEnd.length) {\n this.tableEle.classList.add(`${CSSNAMESPACE}__pinned--end`);\n const firstActiveCol = this.cachedColMeta.get(this.pinnedEnd[0]);\n\n addStyleSheet(\n `${this.tableId}-col-end-active-style`,\n /* css */ `\n #${this.tableId} tr > :nth-child(${\n firstActiveCol.idx + 1\n }) { --pin-end-active: 1; }\n `\n );\n } else {\n this.tableEle.classList.remove(`${CSSNAMESPACE}__pinned--end`);\n addStyleSheet(`${this.tableId}-col-end-active-style`, ``);\n }\n });\n }\n\n private get cssColDimensionCacheKey() {\n return this._cssColDimensionCacheKey;\n }\n private set cssColDimensionCacheKey(key: string) {\n if (key === this._cssColDimensionCacheKey) return;\n this._cssColDimensionCacheKey = key;\n this.createPinnedColDimensionStyles();\n }\n private _cssColDimensionCacheKey: string = '';\n\n /**\n * To only generate column dimension styles when necessary we\n * maintain a cache key string via serialised column meta.\n * Only when this key changes do we generate a new stylesheet\n */\n private generateCssCacheKey() {\n let key = '';\n for (const col of this.startColumns) {\n const colMeta = this.cachedColMeta.get(col as HTMLElement);\n key += `${colMeta.idx}-start-${colMeta.width}`;\n }\n for (const col of this.endColumns) {\n const colMeta = this.cachedColMeta.get(col as HTMLElement);\n key += `${colMeta.idx}-start-${colMeta.width}`;\n }\n this.cssColDimensionCacheKey = key;\n }\n\n /**\n * Generates pinned column width offset styles\n * so pinned columns can appear stuck together,\n * then attaches a stylesheet.\n */\n private createPinnedColDimensionStyles() {\n let widthS = 0;\n let widthE = 0;\n const startCols = Array.from(this.startColumns);\n const endCols = Array.from(this.endColumns).reverse();\n\n const css = /* css */ `\n ${startCols\n .map((col) => {\n const colMeta = this.cachedColMeta.get(col as HTMLElement);\n widthS += colMeta.width || 0;\n return /* css */ `\n #${this.tableId} tr > :nth-child(${colMeta.idx + 1}) ~ td,\n #${this.tableId} tr > :nth-child(${colMeta.idx + 1}) ~ th {\n --pin-start: ${widthS - 1}px;\n }\n `;\n })\n .join('')}\n ${endCols\n .map((col) => {\n const colMeta = this.cachedColMeta.get(col as HTMLElement);\n widthE += colMeta.width;\n return /* css */ `\n #${this.tableId} tr > td:has(~ :nth-child(${colMeta.idx + 1})),\n #${this.tableId} tr > th:has(~ :nth-child(${colMeta.idx + 1})) {\n --pin-end: ${widthE - 1}px;\n }\n `;\n })\n .join('')}\n `;\n addStyleSheet(`${this.tableId}-dimension-style`, css);\n }\n\n private getParentOffsets() {\n const { x, y } = this.scrollElement.getBoundingClientRect();\n\n let offsetX = x;\n let offsetY = y;\n\n if (this.scrollElement === document.documentElement) {\n offsetX = this.scrollElement.offsetLeft;\n offsetY = this.scrollElement.offsetTop;\n }\n return { offsetX, offsetY };\n }\n\n /**\n * Loops through all 'top' & 'bottom' rows (on scroll or resize)\n * Manages their visual state by applying classes on stuck / unstuck\n * And their pinned offset / distance\n */\n public assessRows() {\n if (!this.topRows.length && !this.bottomRows.length) return;\n\n // top rows\n if (this.topRows.length) {\n readTask(async () => {\n let heightAggregate = 0;\n let cacheParent: HTMLElement;\n const { offsetY } = this.getParentOffsets();\n\n for (const topRow of this.topRows) {\n const { y, height } = topRow.getBoundingClientRect();\n const currParent = topRow.parentElement;\n // we'll use the applied `--pin-top` css var to decide row offset.\n // This allows devs to override this behaviour through selector specificity\n const pinTop = getComputedStyle(topRow).getPropertyValue('--pin-top');\n const offset = pinTop !== '' ? parseFloat(pinTop) : heightAggregate;\n\n // we need to wait for the row to finish sticking\n // and generating it's offset (`--pin-top`) so we can see, on\n // subsequent rows *if* the offset was applied\n await new Promise<void>((resolve) =>\n writeTask(() => {\n if (y - offsetY <= offset) {\n topRow.classList.add(\n `${CSSNAMESPACE}__pinned`,\n `${CSSNAMESPACE}__pinned--top`\n );\n } else {\n topRow.classList.remove(\n `${CSSNAMESPACE}__pinned`,\n `${CSSNAMESPACE}__pinned--top`\n );\n }\n\n // by default, we only want to stick one row from each parental block (thead, tbody, tfoot)\n // so only aggregate height / offset when cacheParent is different from current parent.\n // Devs can override this behaviour by manually setting `--pin-bottom` on the table row\n if (cacheParent !== currParent) {\n currParent.style.setProperty(\n '--pin-top',\n `${heightAggregate}px`\n );\n heightAggregate += height;\n cacheParent = currParent;\n }\n resolve();\n })\n );\n }\n });\n }\n\n // bottom rows\n if (this.bottomRows.length) {\n const bottomRows = Array.from(this.bottomRows).reverse();\n readTask(async () => {\n let cacheParent: HTMLElement;\n let heightAggregate = 0;\n const { offsetY } = this.getParentOffsets();\n\n for (const bottomRow of bottomRows) {\n if (!bottomRow.isConnected) continue;\n\n const { y, height } = bottomRow.getBoundingClientRect();\n const currParent = bottomRow.parentElement;\n // we'll use the applied `--pin-bottom` css var to decide row offset.\n // This allows devs to override this behaviour through selector specificity\n const pinBottom =\n getComputedStyle(bottomRow).getPropertyValue('--pin-bottom');\n const offset =\n pinBottom !== '' ? parseFloat(pinBottom) : heightAggregate;\n\n // we need to wait for the row to finish sticking\n // and generating it's offset (`--pin-bottom`) to we can see, on\n // subsequent rows *if* the offset was applied\n await new Promise<void>((resolve) =>\n writeTask(() => {\n if (this.tableDims.height + offsetY - (y + height) <= offset) {\n bottomRow.classList.add(\n `${CSSNAMESPACE}__pinned`,\n `${CSSNAMESPACE}__pinned--bottom`\n );\n } else {\n bottomRow.classList.remove(\n `${CSSNAMESPACE}__pinned`,\n `${CSSNAMESPACE}__pinned--bottom`\n );\n }\n\n // by default, we only want to stick one row from each parental block (thead, tbody, tfoot)\n // so only aggregate height / offset when cacheParent is different from current parent.\n // Devs can override this behaviour by manually setting `--pin-bottom` on the table row\n if (cacheParent !== currParent) {\n currParent.style.setProperty(\n '--pin-bottom',\n `${heightAggregate}px`\n );\n heightAggregate += height;\n cacheParent = currParent;\n }\n resolve();\n })\n );\n }\n });\n }\n }\n\n /**\n * Loops through all 'start' & 'end' columns (on scroll or resize)\n * Caches meta about each column (e.g. size, position-index)\n * and decides which columns are pinned\n */\n public async assessCols() {\n if (!this.startColumns.length && !this.endColumns.length) return;\n\n let boundBox: DOMRect;\n let currPinned: HTMLElement;\n let parentEles: Element[];\n\n const done = new Promise<void>((resolve) => {\n // start cols\n if (this.startColumns.length) {\n readTask(() => {\n const { offsetX } = this.getParentOffsets();\n // cumulatively add widths of columns together\n // 'cos columns stick together\n let widthAggregate = offsetX;\n parentEles = Array.from(this.startColumns[0].parentElement.children);\n\n for (const startCol of this.startColumns) {\n boundBox = startCol.getBoundingClientRect();\n // cache meta for later\n this.cachedColMeta.set(startCol as HTMLElement, {\n width: boundBox.width,\n idx: parentEles.indexOf(startCol),\n });\n\n currPinned = this.pinnedStart.find((c) => c === startCol);\n if (boundBox.x < widthAggregate) {\n // this column is pinned\n if (!currPinned)\n this.pinnedStart = [\n ...this.pinnedStart,\n startCol as HTMLElement,\n ];\n } else if (currPinned) {\n // this column is unpinned\n this.pinnedStart = this.pinnedStart.filter((c) => c !== startCol);\n }\n widthAggregate += boundBox.width;\n }\n if (!this.endColumns.length) resolve();\n });\n }\n\n // end cols\n if (this.endColumns.length) {\n readTask(() => {\n const endCols = Array.from(this.endColumns).reverse();\n parentEles = Array.from(this.endColumns[0].parentElement.children);\n const { offsetX } = this.getParentOffsets();\n // cumulatively add widths of columns together\n // 'cos columns stick together\n let widthAggregate = 0;\n\n for (const endCol of endCols) {\n boundBox = endCol.getBoundingClientRect();\n // cache meta for later\n this.cachedColMeta.set(endCol as HTMLElement, {\n width: boundBox.width,\n idx: parentEles.indexOf(endCol),\n });\n\n currPinned = this.pinnedEnd.find((c) => c === endCol);\n if (\n this.tableDims.width + offsetX - boundBox.right <=\n widthAggregate\n ) {\n // this column is pinned\n if (!currPinned)\n this.pinnedEnd = [endCol as HTMLElement, ...this.pinnedEnd];\n } else if (currPinned) {\n // this column is unpinned\n this.pinnedEnd = this.pinnedEnd.filter((c) => c !== endCol);\n }\n widthAggregate += boundBox.width;\n }\n resolve();\n });\n }\n });\n\n await done;\n // potentially generate a new css stylesheet if anything changed\n this.generateCssCacheKey();\n }\n\n private cacheX = 0;\n private cacheY = 0;\n\n public onScroll(pos: { x: number; y: number }) {\n if (this.cacheX !== pos.x) {\n this.cacheX = pos.x;\n this.assessCols();\n }\n if (this.cacheY !== pos.y) {\n this.cacheY = pos.y;\n this.assessRows();\n }\n }\n\n public onResize() {\n const width = this.scrollElement.clientWidth;\n const height = this.scrollElement.clientHeight;\n\n this.tableDims = { width, height };\n this.assessCols();\n this.assessRows();\n }\n}\n"]}
@@ -2,17 +2,21 @@
2
2
  * Web Components for Nanopore digital Web Apps
3
3
  */
4
4
  import { h } from '@stencil/core';
5
- import { addHObserver, addVObserver, headerPinClasses, mergeProperties, rowDataModel, } from './table.utils';
5
+ import { headerPinClasses, mergeProperties, rowDataModel } from './table.utils';
6
6
  import { baseCellClasses } from './table.cell';
7
7
  import { CSSNAMESPACE } from './table.constants';
8
- const TableCell = ({ header, wrap }, children) => {
9
- const cell = (h("div", { class: {
8
+ const tableCellContent = (props, children, ctx) => {
9
+ const cell = (h("div", Object.assign({}, props.wrapperProps, { class: {
10
10
  [`${CSSNAMESPACE}__cell-content`]: true,
11
- [`${CSSNAMESPACE}__cell-content--wrap`]: wrap,
12
- } }, children));
13
- return header ? h("th", { scope: "row" }, cell) : h("td", null, cell);
11
+ [`${CSSNAMESPACE}__cell-content--wrap`]: props.wrap,
12
+ } }), children));
13
+ return props.header ? (h("th", Object.assign({ scope: ctx }, props.cellProps), cell)) : (h("td", Object.assign({}, props.cellProps), cell));
14
14
  };
15
- export const TableRow = ({ rowRenderer, rowIndex, rowModel, onColumnPinned }, children, utils) => {
15
+ export const TableRow = ({ rowRenderer, rowIndex, rowModel }, children, utils) => {
16
+ // helper, generates <td> or <th>
17
+ const TableCell = ({ header, wrap, cellProps, wrapperProps }, children) => {
18
+ return tableCellContent({ header, wrap, cellProps, wrapperProps }, children, 'row');
19
+ };
16
20
  let extraProps = {};
17
21
  if (!rowModel) {
18
22
  const model = rowDataModel(rowIndex);
@@ -22,13 +26,28 @@ export const TableRow = ({ rowRenderer, rowIndex, rowModel, onColumnPinned }, ch
22
26
  extraProps =
23
27
  rowRenderer.rowProperties({ rowModel, rowIndex }) || extraProps;
24
28
  }
25
- let pinned;
29
+ let rowPinned;
26
30
  if ((rowRenderer === null || rowRenderer === void 0 ? void 0 : rowRenderer.pinned) && typeof rowRenderer.pinned === 'function') {
27
- pinned = rowRenderer.pinned();
31
+ rowPinned = rowRenderer.pinned({ rowModel, rowIndex });
28
32
  }
29
- const baseProps = { class: headerPinClasses('tr', pinned) };
30
- const props = extraProps ? mergeProperties(baseProps, extraProps) : baseProps;
33
+ const props = mergeProperties({ class: headerPinClasses('tr', rowPinned, true) }, extraProps);
31
34
  const tpl = rowRenderer === null || rowRenderer === void 0 ? void 0 : rowRenderer.template;
35
+ /**
36
+ * Applies appropriate classes to td / th VNodes;
37
+ * which can be supplied by user defined templates
38
+ * @param children virtual / jsx node array
39
+ * @returns virtual / jsx node array
40
+ */
41
+ const applyCellClasses = (children) => {
42
+ return utils.map(children, (cNode, i) => {
43
+ if (['td', 'th'].includes(cNode.vtag.toString())) {
44
+ cNode.vattrs = mergeProperties({
45
+ class: baseCellClasses(i, true),
46
+ }, cNode.vattrs);
47
+ }
48
+ return cNode;
49
+ });
50
+ };
32
51
  if (tpl) {
33
52
  let toRender = tpl(h, {
34
53
  renderedRow: (h("tr", Object.assign({}, props, { key: rowModel.__uuid }), children)),
@@ -40,24 +59,9 @@ export const TableRow = ({ rowRenderer, rowIndex, rowModel, onColumnPinned }, ch
40
59
  if (node.vtag === 'tr') {
41
60
  if (!node.vkey)
42
61
  node.vkey = `${rowModel.__uuid}_${i}`;
43
- node.vattrs = mergeProperties({ class: headerPinClasses('tr', pinned, true) }, node.vattrs);
62
+ node.vattrs = mergeProperties({ class: headerPinClasses('tr', rowPinned, true) }, node.vattrs);
44
63
  if (!!node.vchildren) {
45
- node.vchildren = utils.map(node.vchildren, (cNode, i) => {
46
- if (['td', 'th'].includes(cNode.vtag.toString())) {
47
- cNode.vattrs = mergeProperties({
48
- class: headerPinClasses(cNode.vtag.toString(), pinned, true) + baseCellClasses(i, true),
49
- ref: (th) => {
50
- if ((!!th && pinned === 'top') || pinned === 'bottom')
51
- addVObserver(th, pinned, onColumnPinned);
52
- if (!!th && th.classList.contains('nano-tbl__pin--end'))
53
- addHObserver(th, 'end', onColumnPinned);
54
- if (!!th && th.classList.contains('nano-tbl__pin--start'))
55
- addHObserver(th, 'start', onColumnPinned);
56
- },
57
- }, cNode.vattrs);
58
- }
59
- return cNode;
60
- });
64
+ node.vchildren = applyCellClasses(node.vchildren);
61
65
  }
62
66
  }
63
67
  return node;
@@ -65,28 +69,25 @@ export const TableRow = ({ rowRenderer, rowIndex, rowModel, onColumnPinned }, ch
65
69
  }
66
70
  return toRender;
67
71
  }
68
- return (h("tr", Object.assign({}, props, { key: rowModel.__uuid }), children));
72
+ return (h("tr", Object.assign({}, props, { key: rowModel.__uuid }), applyCellClasses(children)));
69
73
  };
70
- export const TableHeadFootRow = ({ rowRenderer, onColumnPinned }, children, utils) => {
74
+ export const TableHeadFootRow = ({ rowRenderer }, // onRowPinned, onColPinned
75
+ children, utils) => {
71
76
  let extraProps = {};
72
77
  if (rowRenderer.rowProperties) {
73
78
  extraProps = rowRenderer.rowProperties() || {};
74
79
  }
75
- const TableCell = ({ header, wrap }, children) => {
76
- const cell = (h("div", { class: {
77
- [`${CSSNAMESPACE}__cell-content`]: true,
78
- [`${CSSNAMESPACE}__cell-content--wrap`]: wrap,
79
- } }, children));
80
- return header !== false ? h("th", { scope: "col" }, cell) : h("td", null, cell);
80
+ const TableHeadFootCell = ({ header, wrap, cellProps, wrapperProps }, children) => {
81
+ return tableCellContent({ header, wrap, cellProps, wrapperProps }, children, 'col');
81
82
  };
82
83
  const pinned = rowRenderer.pinned || null;
83
- const baseProps = { class: headerPinClasses('tr', null) };
84
+ const baseProps = { class: headerPinClasses('tr', pinned) };
84
85
  const props = extraProps ? mergeProperties(baseProps, extraProps) : baseProps;
85
86
  const tpl = rowRenderer === null || rowRenderer === void 0 ? void 0 : rowRenderer.template;
86
87
  if (tpl) {
87
88
  let toRender = tpl(h, {
88
89
  renderedRow: h("tr", Object.assign({}, props), children),
89
- }, TableCell);
90
+ }, TableHeadFootCell);
90
91
  if (Array.isArray(toRender)) {
91
92
  toRender = utils.map(toRender, (node) => {
92
93
  if (node.vtag === 'tr') {
@@ -96,14 +97,6 @@ export const TableHeadFootRow = ({ rowRenderer, onColumnPinned }, children, util
96
97
  if (['td', 'th'].includes(cNode.vtag.toString())) {
97
98
  cNode.vattrs = mergeProperties({
98
99
  class: headerPinClasses(cNode.vtag.toString(), pinned, true),
99
- ref: (th) => {
100
- if ((!!th && pinned === 'top') || pinned === 'bottom')
101
- addVObserver(th, pinned, onColumnPinned);
102
- if (!!th && th.classList.contains('nano-tbl__pin--end'))
103
- addHObserver(th, 'end', onColumnPinned);
104
- if (!!th && th.classList.contains('nano-tbl__pin--start'))
105
- addHObserver(th, 'start', onColumnPinned);
106
- },
107
100
  }, cNode.vattrs);
108
101
  }
109
102
  return cNode;
@@ -1 +1 @@
1
- {"version":3,"file":"table.row.js","sourceRoot":"","sources":["../../../src/components/table/table.row.tsx"],"names":[],"mappings":"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","sourcesContent":["import { FunctionalComponent, h, VNode } from '@stencil/core';\nimport {\n addHObserver,\n addVObserver,\n headerPinClasses,\n mergeProperties,\n rowDataModel,\n} from './table.utils';\nimport { baseCellClasses } from './table.cell';\nimport { CSSNAMESPACE } from './table.constants';\nimport type { TableTypes } from '../../interface';\n\n// TABLE ROWS\n// (thead > tr, tfoot > tr, tr)\n\ntype TableRowCellHelperProps = { header: boolean; wrap: boolean };\n\ntype TableRowProps = {\n rowRenderer: TableTypes.RowRenderer;\n rowIndex: number;\n rowModel: TableTypes.RowData;\n onColumnPinned?: TableTypes.PinnedCb;\n};\n\nconst TableCell: FunctionalComponent<TableRowCellHelperProps> = (\n { header, wrap },\n children\n): VNode => {\n const cell = (\n <div\n class={{\n [`${CSSNAMESPACE}__cell-content`]: true,\n [`${CSSNAMESPACE}__cell-content--wrap`]: wrap,\n }}\n >\n {children}\n </div>\n );\n return header ? <th scope=\"row\">{cell}</th> : <td>{cell}</td>;\n};\n\nexport const TableRow: FunctionalComponent<TableRowProps> = (\n { rowRenderer, rowIndex, rowModel, onColumnPinned },\n children,\n utils\n) => {\n let extraProps = {};\n\n if (!rowModel) {\n const model = rowDataModel(rowIndex);\n rowModel = model.rowModel;\n }\n\n if (rowRenderer?.rowProperties) {\n extraProps =\n rowRenderer.rowProperties({ rowModel, rowIndex }) || extraProps;\n }\n\n let pinned: TableTypes.Position;\n if (rowRenderer?.pinned && typeof rowRenderer.pinned === 'function') {\n pinned = rowRenderer.pinned();\n }\n\n const baseProps = { class: headerPinClasses('tr', pinned) };\n const props = extraProps ? mergeProperties(baseProps, extraProps) : baseProps;\n const tpl = rowRenderer?.template;\n\n if (tpl) {\n let toRender = tpl(\n h as TableTypes.HFunc<VNode>,\n {\n renderedRow: (\n <tr {...props} key={rowModel.__uuid}>\n {children}\n </tr>\n ),\n rowModel,\n rowIndex,\n },\n TableCell\n );\n\n if (Array.isArray(toRender)) {\n toRender = utils.map(toRender, (node, i) => {\n if (node.vtag === 'tr') {\n if (!node.vkey) node.vkey = `${rowModel.__uuid}_${i}`;\n\n node.vattrs = mergeProperties(\n { class: headerPinClasses('tr', pinned, true) },\n node.vattrs\n );\n\n if (!!node.vchildren) {\n node.vchildren = utils.map(node.vchildren, (cNode, i) => {\n if (['td', 'th'].includes(cNode.vtag.toString())) {\n cNode.vattrs = mergeProperties(\n {\n class:\n headerPinClasses(\n cNode.vtag.toString() as 'th' | 'td',\n pinned,\n true\n ) + baseCellClasses(i, true),\n ref: (th: HTMLTableCellElement) => {\n if ((!!th && pinned === 'top') || pinned === 'bottom')\n addVObserver(th, pinned, onColumnPinned);\n if (!!th && th.classList.contains('nano-tbl__pin--end'))\n addHObserver(th, 'end', onColumnPinned);\n if (!!th && th.classList.contains('nano-tbl__pin--start'))\n addHObserver(th, 'start', onColumnPinned);\n },\n },\n cNode.vattrs\n );\n }\n return cNode;\n });\n }\n }\n return node;\n });\n }\n return toRender;\n }\n\n return (\n <tr {...props} key={rowModel.__uuid}>\n {children}\n </tr>\n );\n};\n\ntype TableHeadFootProps = {\n rowRenderer: TableTypes.HeadFootRenderer;\n onColumnPinned?: TableTypes.PinnedCb;\n};\n\nexport const TableHeadFootRow: FunctionalComponent<TableHeadFootProps> = (\n { rowRenderer, onColumnPinned },\n children,\n utils\n) => {\n let extraProps = {};\n if (rowRenderer.rowProperties) {\n extraProps = rowRenderer.rowProperties() || {};\n }\n\n const TableCell: FunctionalComponent<TableRowCellHelperProps> = (\n { header, wrap },\n children\n ): VNode => {\n const cell = (\n <div\n class={{\n [`${CSSNAMESPACE}__cell-content`]: true,\n [`${CSSNAMESPACE}__cell-content--wrap`]: wrap,\n }}\n >\n {children}\n </div>\n );\n return header !== false ? <th scope=\"col\">{cell}</th> : <td>{cell}</td>;\n };\n\n const pinned = rowRenderer.pinned || null;\n const baseProps = { class: headerPinClasses('tr', null) };\n const props = extraProps ? mergeProperties(baseProps, extraProps) : baseProps;\n const tpl = rowRenderer?.template;\n\n if (tpl) {\n let toRender = tpl(\n h as TableTypes.HFunc<VNode>,\n {\n renderedRow: <tr {...props}>{children}</tr>,\n },\n TableCell\n );\n\n if (Array.isArray(toRender)) {\n toRender = utils.map(toRender, (node) => {\n if (node.vtag === 'tr') {\n node.vattrs = mergeProperties(\n { class: headerPinClasses('tr', pinned, true) },\n node.vattrs\n );\n\n if (!!node.vchildren) {\n node.vchildren = utils.map(node.vchildren, (cNode) => {\n if (['td', 'th'].includes(cNode.vtag.toString())) {\n cNode.vattrs = mergeProperties(\n {\n class: headerPinClasses(\n cNode.vtag.toString() as 'th' | 'td',\n pinned,\n true\n ),\n ref: (th) => {\n if ((!!th && pinned === 'top') || pinned === 'bottom')\n addVObserver(th, pinned, onColumnPinned);\n if (!!th && th.classList.contains('nano-tbl__pin--end'))\n addHObserver(th, 'end', onColumnPinned);\n if (!!th && th.classList.contains('nano-tbl__pin--start'))\n addHObserver(th, 'start', onColumnPinned);\n },\n },\n cNode.vattrs\n );\n }\n return cNode;\n });\n }\n }\n return node;\n });\n }\n return toRender;\n }\n\n return <tr {...props}>{children}</tr>;\n};\n"]}
1
+ {"version":3,"file":"table.row.js","sourceRoot":"","sources":["../../../src/components/table/table.row.tsx"],"names":[],"mappings":"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","sourcesContent":["import { FunctionalComponent, h, VNode } from '@stencil/core';\nimport { headerPinClasses, mergeProperties, rowDataModel } from './table.utils';\nimport { baseCellClasses } from './table.cell';\nimport { CSSNAMESPACE } from './table.constants';\nimport type { TableTypes } from '../../interface';\n\n// TABLE ROWS\n// (thead > tr, tfoot > tr, tr)\n\ntype TableRowProps = {\n rowRenderer: TableTypes.RowRenderer;\n rowIndex: number;\n rowModel: TableTypes.RowData;\n onRowPinned?: TableTypes.PinnedCb;\n};\n\nconst tableCellContent = (\n props: TableTypes.TableRowCellHelperProps,\n children: VNode[],\n ctx: 'col' | 'row'\n): VNode => {\n const cell = (\n <div\n {...props.wrapperProps}\n class={{\n [`${CSSNAMESPACE}__cell-content`]: true,\n [`${CSSNAMESPACE}__cell-content--wrap`]: props.wrap,\n }}\n >\n {children}\n </div>\n );\n return props.header ? (\n <th scope={ctx} {...props.cellProps}>\n {cell}\n </th>\n ) : (\n <td {...props.cellProps}>{cell}</td>\n );\n};\n\nexport const TableRow: FunctionalComponent<TableRowProps> = (\n { rowRenderer, rowIndex, rowModel },\n children,\n utils\n) => {\n // helper, generates <td> or <th>\n const TableCell: FunctionalComponent<TableTypes.TableRowCellHelperProps> = (\n { header, wrap, cellProps, wrapperProps },\n children\n ): VNode => {\n return tableCellContent(\n { header, wrap, cellProps, wrapperProps },\n children,\n 'row'\n );\n };\n\n let extraProps = {};\n\n if (!rowModel) {\n const model = rowDataModel(rowIndex);\n rowModel = model.rowModel;\n }\n\n if (rowRenderer?.rowProperties) {\n extraProps =\n rowRenderer.rowProperties({ rowModel, rowIndex }) || extraProps;\n }\n\n let rowPinned: TableTypes.Position;\n if (rowRenderer?.pinned && typeof rowRenderer.pinned === 'function') {\n rowPinned = rowRenderer.pinned({ rowModel, rowIndex });\n }\n\n const props = mergeProperties(\n { class: headerPinClasses('tr', rowPinned, true) },\n extraProps\n );\n const tpl = rowRenderer?.template;\n\n /**\n * Applies appropriate classes to td / th VNodes;\n * which can be supplied by user defined templates\n * @param children virtual / jsx node array\n * @returns virtual / jsx node array\n */\n const applyCellClasses = (children: VNode[]) => {\n return utils.map(children, (cNode, i) => {\n if (['td', 'th'].includes(cNode.vtag.toString())) {\n cNode.vattrs = mergeProperties(\n {\n class: baseCellClasses(i, true),\n },\n cNode.vattrs\n );\n }\n return cNode;\n });\n };\n\n if (tpl) {\n let toRender = tpl(\n h as TableTypes.HFunc<VNode>,\n {\n renderedRow: (\n <tr {...props} key={rowModel.__uuid}>\n {children}\n </tr>\n ),\n rowModel,\n rowIndex,\n },\n TableCell\n );\n\n if (Array.isArray(toRender)) {\n toRender = utils.map(toRender, (node, i) => {\n if (node.vtag === 'tr') {\n if (!node.vkey) node.vkey = `${rowModel.__uuid}_${i}`;\n\n node.vattrs = mergeProperties(\n { class: headerPinClasses('tr', rowPinned, true) },\n node.vattrs\n );\n\n if (!!node.vchildren) {\n node.vchildren = applyCellClasses(node.vchildren);\n }\n }\n return node;\n });\n }\n return toRender;\n }\n\n return (\n <tr {...props} key={rowModel.__uuid}>\n {applyCellClasses(children)}\n </tr>\n );\n};\n\ntype TableHeadFootProps = {\n rowRenderer: TableTypes.HeadFootRenderer;\n onRowPinned?: TableTypes.PinnedCb;\n onColPinned?: TableTypes.PinnedCb;\n};\n\nexport const TableHeadFootRow: FunctionalComponent<TableHeadFootProps> = (\n { rowRenderer }, // onRowPinned, onColPinned\n children,\n utils\n) => {\n let extraProps = {};\n if (rowRenderer.rowProperties) {\n extraProps = rowRenderer.rowProperties() || {};\n }\n\n const TableHeadFootCell: FunctionalComponent<\n TableTypes.TableRowCellHelperProps\n > = ({ header, wrap, cellProps, wrapperProps }, children): VNode => {\n return tableCellContent(\n { header, wrap, cellProps, wrapperProps },\n children,\n 'col'\n );\n };\n\n const pinned = rowRenderer.pinned || null;\n const baseProps = { class: headerPinClasses('tr', pinned) };\n const props = extraProps ? mergeProperties(baseProps, extraProps) : baseProps;\n const tpl = rowRenderer?.template;\n\n if (tpl) {\n let toRender = tpl(\n h as TableTypes.HFunc<VNode>,\n {\n renderedRow: <tr {...props}>{children}</tr>,\n },\n TableHeadFootCell\n );\n\n if (Array.isArray(toRender)) {\n toRender = utils.map(toRender, (node) => {\n if (node.vtag === 'tr') {\n node.vattrs = mergeProperties(\n { class: headerPinClasses('tr', pinned, true) },\n node.vattrs\n );\n\n if (!!node.vchildren) {\n node.vchildren = utils.map(node.vchildren, (cNode) => {\n if (['td', 'th'].includes(cNode.vtag.toString())) {\n cNode.vattrs = mergeProperties(\n {\n class: headerPinClasses(\n cNode.vtag.toString() as 'th' | 'td',\n pinned,\n true\n ),\n },\n cNode.vattrs\n );\n }\n return cNode;\n });\n }\n }\n return node;\n });\n }\n return toRender;\n }\n\n return <tr {...props}>{children}</tr>;\n};\n"]}