@nanoporetech-digital/components 3.0.0 → 3.1.1

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 (212) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/dist/cjs/index-41582c2a.js +8 -4
  3. package/dist/cjs/loader.cjs.js +1 -1
  4. package/dist/cjs/nano-checkbox-group.cjs.entry.js +12 -3
  5. package/dist/cjs/nano-checkbox-group.cjs.entry.js.map +1 -1
  6. package/dist/cjs/nano-components.cjs.js +1 -1
  7. package/dist/cjs/nano-details.cjs.entry.js +2 -2
  8. package/dist/cjs/nano-details.cjs.entry.js.map +1 -1
  9. package/dist/cjs/nano-field-validator.cjs.entry.js +2 -0
  10. package/dist/cjs/nano-field-validator.cjs.entry.js.map +1 -1
  11. package/dist/cjs/nano-global-nav-user-profile_3.cjs.entry.js +3 -3
  12. package/dist/cjs/nano-global-nav-user-profile_3.cjs.entry.js.map +1 -1
  13. package/dist/cjs/nano-global-nav.cjs.entry.js +18 -20
  14. package/dist/cjs/nano-global-nav.cjs.entry.js.map +1 -1
  15. package/dist/cjs/nano-input.cjs.entry.js +1 -1
  16. package/dist/cjs/nano-input.cjs.entry.js.map +1 -1
  17. package/dist/cjs/nano-menu-drawer.cjs.entry.js +1 -1
  18. package/dist/cjs/nano-menu-drawer.cjs.entry.js.map +1 -1
  19. package/dist/cjs/nano-progress-bar.cjs.entry.js +33 -0
  20. package/dist/cjs/nano-progress-bar.cjs.entry.js.map +1 -0
  21. package/dist/cjs/nano-resize-observe_2.cjs.entry.js +2 -2
  22. package/dist/cjs/nano-resize-observe_2.cjs.entry.js.map +1 -1
  23. package/dist/cjs/nano-spinner.cjs.entry.js +1 -1
  24. package/dist/cjs/nano-spinner.cjs.entry.js.map +1 -1
  25. package/dist/cjs/nano-tab-group.cjs.entry.js +1 -1
  26. package/dist/cjs/nano-tab.cjs.entry.js +1 -1
  27. package/dist/cjs/nano-tab.cjs.entry.js.map +1 -1
  28. package/dist/cjs/{nano-table-8a898621.js → nano-table-844394ad.js} +146 -58
  29. package/dist/cjs/nano-table-844394ad.js.map +1 -0
  30. package/dist/cjs/nano-table.cjs.entry.js +2 -1
  31. package/dist/cjs/nano-table.cjs.entry.js.map +1 -1
  32. package/dist/cjs/{table.worker-b0b0044a.js → table.worker-1bc19978.js} +3 -2
  33. package/dist/cjs/table.worker-1bc19978.js.map +1 -0
  34. package/dist/cjs/{transitions-d295a09e.js → transitions-5cd8f697.js} +10 -8
  35. package/dist/cjs/transitions-5cd8f697.js.map +1 -0
  36. package/dist/collection/collection-manifest.json +1 -0
  37. package/dist/collection/components/checkbox/checkbox-group.js +12 -3
  38. package/dist/collection/components/checkbox/checkbox-group.js.map +1 -1
  39. package/dist/collection/components/details/details.css +1 -0
  40. package/dist/collection/components/field-validator/field-validator.js +2 -0
  41. package/dist/collection/components/field-validator/field-validator.js.map +1 -1
  42. package/dist/collection/components/global-nav/assets/ont-logo.svg +89 -47
  43. package/dist/collection/components/global-nav/global-nav-interface.js.map +1 -1
  44. package/dist/collection/components/global-nav/global-nav.js +19 -21
  45. package/dist/collection/components/global-nav/global-nav.js.map +1 -1
  46. package/dist/collection/components/global-nav/{global-nav.css → style/global-nav.css} +465 -405
  47. package/dist/collection/components/input/input.css +2 -0
  48. package/dist/collection/components/menu-drawer/menu-drawer.css +1 -0
  49. package/dist/collection/components/nav-item/nav-item.css +6 -6
  50. package/dist/collection/components/progress-bar/progress-bar.css +84 -0
  51. package/dist/collection/components/progress-bar/progress-bar.js +106 -0
  52. package/dist/collection/components/progress-bar/progress-bar.js.map +1 -0
  53. package/dist/collection/components/select/select.css +4 -0
  54. package/dist/collection/components/skeleton/skeleton.css +8 -5
  55. package/dist/collection/components/skeleton/skeleton.js +1 -1
  56. package/dist/collection/components/skeleton/skeleton.js.map +1 -1
  57. package/dist/collection/components/spinner/spinner.css +5 -9
  58. package/dist/collection/components/table/table.children.js +43 -17
  59. package/dist/collection/components/table/table.children.js.map +1 -1
  60. package/dist/collection/components/table/table.css +97 -27
  61. package/dist/collection/components/table/table.js +143 -33
  62. package/dist/collection/components/table/table.js.map +1 -1
  63. package/dist/collection/components/table/table.service.js +1 -10
  64. package/dist/collection/components/table/table.service.js.map +1 -1
  65. package/dist/collection/components/table/table.store.js +11 -11
  66. package/dist/collection/components/table/table.store.js.map +1 -1
  67. package/dist/collection/components/tabs/tab.css +1 -0
  68. package/dist/collection/utils/transitions.js +9 -7
  69. package/dist/collection/utils/transitions.js.map +1 -1
  70. package/dist/components/index.d.ts +1 -0
  71. package/dist/components/index.js +1 -0
  72. package/dist/components/index.js.map +1 -1
  73. package/dist/components/input.js +1 -1
  74. package/dist/components/input.js.map +1 -1
  75. package/dist/components/nano-checkbox-group.js +12 -3
  76. package/dist/components/nano-checkbox-group.js.map +1 -1
  77. package/dist/components/nano-details.js +1 -1
  78. package/dist/components/nano-details.js.map +1 -1
  79. package/dist/components/nano-field-validator.js +2 -0
  80. package/dist/components/nano-field-validator.js.map +1 -1
  81. package/dist/components/nano-global-nav.js +17 -19
  82. package/dist/components/nano-global-nav.js.map +1 -1
  83. package/dist/components/nano-menu-drawer.js +1 -1
  84. package/dist/components/nano-menu-drawer.js.map +1 -1
  85. package/dist/components/nano-progress-bar.d.ts +11 -0
  86. package/dist/components/nano-progress-bar.js +11 -0
  87. package/dist/components/nano-progress-bar.js.map +1 -0
  88. package/dist/components/nano-tab.js +1 -1
  89. package/dist/components/nano-tab.js.map +1 -1
  90. package/dist/components/nano-table.js +167 -58
  91. package/dist/components/nano-table.js.map +1 -1
  92. package/dist/components/nav-item.js +1 -1
  93. package/dist/components/nav-item.js.map +1 -1
  94. package/dist/components/progress-bar.js +48 -0
  95. package/dist/components/progress-bar.js.map +1 -0
  96. package/dist/components/select.js +1 -1
  97. package/dist/components/select.js.map +1 -1
  98. package/dist/components/skeleton.js +2 -2
  99. package/dist/components/skeleton.js.map +1 -1
  100. package/dist/components/spinner.js +1 -1
  101. package/dist/components/spinner.js.map +1 -1
  102. package/dist/components/transitions.js +9 -7
  103. package/dist/components/transitions.js.map +1 -1
  104. package/dist/custom-elements/index.d.ts +6 -0
  105. package/dist/custom-elements/index.js +219 -96
  106. package/dist/custom-elements/index.js.map +1 -1
  107. package/dist/esm/index-3c280603.js +8 -4
  108. package/dist/esm/loader.js +1 -1
  109. package/dist/esm/nano-checkbox-group.entry.js +12 -3
  110. package/dist/esm/nano-checkbox-group.entry.js.map +1 -1
  111. package/dist/esm/nano-components.js +1 -1
  112. package/dist/esm/nano-details.entry.js +2 -2
  113. package/dist/esm/nano-details.entry.js.map +1 -1
  114. package/dist/esm/nano-field-validator.entry.js +2 -0
  115. package/dist/esm/nano-field-validator.entry.js.map +1 -1
  116. package/dist/esm/nano-global-nav-user-profile_3.entry.js +3 -3
  117. package/dist/esm/nano-global-nav-user-profile_3.entry.js.map +1 -1
  118. package/dist/esm/nano-global-nav.entry.js +18 -20
  119. package/dist/esm/nano-global-nav.entry.js.map +1 -1
  120. package/dist/esm/nano-input.entry.js +1 -1
  121. package/dist/esm/nano-input.entry.js.map +1 -1
  122. package/dist/esm/nano-menu-drawer.entry.js +1 -1
  123. package/dist/esm/nano-menu-drawer.entry.js.map +1 -1
  124. package/dist/esm/nano-progress-bar.entry.js +29 -0
  125. package/dist/esm/nano-progress-bar.entry.js.map +1 -0
  126. package/dist/esm/nano-resize-observe_2.entry.js +2 -2
  127. package/dist/esm/nano-resize-observe_2.entry.js.map +1 -1
  128. package/dist/esm/nano-spinner.entry.js +1 -1
  129. package/dist/esm/nano-spinner.entry.js.map +1 -1
  130. package/dist/esm/nano-tab-group.entry.js +1 -1
  131. package/dist/esm/nano-tab.entry.js +1 -1
  132. package/dist/esm/nano-tab.entry.js.map +1 -1
  133. package/dist/esm/{nano-table-efdf3dba.js → nano-table-19d19d72.js} +146 -58
  134. package/dist/esm/nano-table-19d19d72.js.map +1 -0
  135. package/dist/esm/nano-table.entry.js +2 -1
  136. package/dist/esm/nano-table.entry.js.map +1 -1
  137. package/dist/esm/{table.worker-10ba1126.js → table.worker-c82cecdf.js} +3 -2
  138. package/dist/esm/table.worker-c82cecdf.js.map +1 -0
  139. package/dist/esm/{transitions-d75d242e.js → transitions-71cca3ed.js} +10 -8
  140. package/dist/esm/transitions-71cca3ed.js.map +1 -0
  141. package/dist/nano-components/assets/ont-logo.svg +89 -47
  142. package/dist/nano-components/nano-components.esm.js +1 -1
  143. package/dist/nano-components/nano-components.esm.js.map +1 -1
  144. package/dist/nano-components/p-02df1f62.entry.js +5 -0
  145. package/dist/nano-components/{p-9f8b091a.entry.js.map → p-02df1f62.entry.js.map} +1 -1
  146. package/dist/nano-components/p-167b9165.js +5 -0
  147. package/dist/nano-components/p-167b9165.js.map +1 -0
  148. package/dist/nano-components/p-1ae8c03e.entry.js +5 -0
  149. package/dist/nano-components/p-1ae8c03e.entry.js.map +1 -0
  150. package/dist/nano-components/p-28b43ee9.entry.js +5 -0
  151. package/dist/nano-components/{p-49a831a3.entry.js.map → p-28b43ee9.entry.js.map} +1 -1
  152. package/dist/nano-components/{p-8ef2363b.entry.js → p-6cd59e58.entry.js} +2 -2
  153. package/dist/nano-components/{p-8ef2363b.entry.js.map → p-6cd59e58.entry.js.map} +0 -0
  154. package/dist/nano-components/{p-687350a5.entry.js → p-701e8ebf.entry.js} +2 -2
  155. package/dist/nano-components/p-701e8ebf.entry.js.map +1 -0
  156. package/dist/nano-components/p-7ade1695.js +5 -0
  157. package/dist/nano-components/{p-8a6834ff.entry.js.map → p-7ade1695.js.map} +0 -0
  158. package/dist/nano-components/p-8a52a411.entry.js +5 -0
  159. package/dist/nano-components/{p-68b18b99.entry.js.map → p-8a52a411.entry.js.map} +1 -1
  160. package/dist/nano-components/p-a2d0d7b9.entry.js.map +1 -1
  161. package/dist/nano-components/p-b4a045a2.entry.js +5 -0
  162. package/dist/nano-components/{p-b7b06e04.js.map → p-b4a045a2.entry.js.map} +0 -0
  163. package/dist/nano-components/p-b7901427.entry.js +5 -0
  164. package/dist/nano-components/p-b7901427.entry.js.map +1 -0
  165. package/dist/nano-components/p-b83a8320.js +5 -0
  166. package/dist/nano-components/p-b83a8320.js.map +1 -0
  167. package/dist/nano-components/p-d8e8d7e3.entry.js +5 -0
  168. package/dist/nano-components/p-d8e8d7e3.entry.js.map +1 -0
  169. package/dist/nano-components/p-efa8c520.entry.js +5 -0
  170. package/dist/nano-components/{p-47bd0f5d.entry.js.map → p-efa8c520.entry.js.map} +1 -1
  171. package/dist/nano-components/p-f95a263c.entry.js +5 -0
  172. package/dist/nano-components/p-f95a263c.entry.js.map +1 -0
  173. package/dist/nano-components/p-fa2a6733.entry.js +5 -0
  174. package/dist/nano-components/p-fa2a6733.entry.js.map +1 -0
  175. package/dist/themes/london-calling.css.map +1 -1
  176. package/dist/themes/nanopore.css.map +1 -1
  177. package/dist/types/components/global-nav/global-nav-interface.d.ts +43 -0
  178. package/dist/types/components/global-nav/global-nav.d.ts +1 -1
  179. package/dist/types/components/progress-bar/progress-bar.d.ts +19 -0
  180. package/dist/types/components/table/table.children.d.ts +2 -1
  181. package/dist/types/components/table/table.d.ts +25 -7
  182. package/dist/types/components/table/table.service.d.ts +1 -7
  183. package/dist/types/components/table/table.store.d.ts +4 -2
  184. package/dist/types/components.d.ts +60 -5
  185. package/docs-json.json +274 -49
  186. package/docs-vscode.json +31 -2
  187. package/package.json +3 -3
  188. package/dist/cjs/nano-table-8a898621.js.map +0 -1
  189. package/dist/cjs/table.worker-b0b0044a.js.map +0 -1
  190. package/dist/cjs/transitions-d295a09e.js.map +0 -1
  191. package/dist/esm/nano-table-efdf3dba.js.map +0 -1
  192. package/dist/esm/table.worker-10ba1126.js.map +0 -1
  193. package/dist/esm/transitions-d75d242e.js.map +0 -1
  194. package/dist/nano-components/p-03402e69.entry.js +0 -5
  195. package/dist/nano-components/p-03402e69.entry.js.map +0 -1
  196. package/dist/nano-components/p-2382d5e9.entry.js +0 -5
  197. package/dist/nano-components/p-2382d5e9.entry.js.map +0 -1
  198. package/dist/nano-components/p-47bd0f5d.entry.js +0 -5
  199. package/dist/nano-components/p-49a831a3.entry.js +0 -5
  200. package/dist/nano-components/p-4c6ef60b.js +0 -5
  201. package/dist/nano-components/p-4c6ef60b.js.map +0 -1
  202. package/dist/nano-components/p-61bfb8b9.entry.js +0 -5
  203. package/dist/nano-components/p-61bfb8b9.entry.js.map +0 -1
  204. package/dist/nano-components/p-687350a5.entry.js.map +0 -1
  205. package/dist/nano-components/p-68b18b99.entry.js +0 -5
  206. package/dist/nano-components/p-82295d91.js +0 -5
  207. package/dist/nano-components/p-82295d91.js.map +0 -1
  208. package/dist/nano-components/p-8a6834ff.entry.js +0 -5
  209. package/dist/nano-components/p-9f2524d4.entry.js +0 -5
  210. package/dist/nano-components/p-9f2524d4.entry.js.map +0 -1
  211. package/dist/nano-components/p-9f8b091a.entry.js +0 -5
  212. package/dist/nano-components/p-b7b06e04.js +0 -5
@@ -10,8 +10,10 @@
10
10
  [hidden] {
11
11
  display: none !important;
12
12
  }
13
+ @charset "UTF-8";
13
14
  nano-table {
14
- display: block;
15
+ display: table;
16
+ width: 100%;
15
17
  --max-col-width: 200px;
16
18
  --color: var(--nano-color-mediumgrey, #68767e);
17
19
  --font-size: 0.87rem;
@@ -20,11 +22,11 @@ nano-table {
20
22
  --border-style: 1px solid var(--border-color);
21
23
  --border-tint-color: var(--nano-color-blue, #90c6e7);
22
24
  --border-tint-style: 2px solid var(--border-tint-color);
23
- --cell-bg-rgb: var(--nano-color-white-rgb);
25
+ --cell-bg-rgb: var(--nano-color-white-rgb, 255 255 255);
24
26
  --head-bg-rgb: var(--cell-bg-rgb);
25
27
  --foot-bg-rgb: var(--cell-bg-rgb);
26
28
  --th-row-bg-rgb: var(--cell-bg-rgb);
27
- --ordered-bg-rgb: var(--nano-color-lightgrey-rgb);
29
+ --ordered-bg-rgb: var(--nano-color-offwhite-rgb, 249 249 251);
28
30
  --td-padding: 0.5rem 0.625rem 0.4125rem;
29
31
  --th-padding: 0.875rem 0.625rem 0.6875rem;
30
32
  --head-th-padding: var(--th-padding);
@@ -38,10 +40,21 @@ nano-table {
38
40
  width: 100%;
39
41
  font-size: var(--font-size);
40
42
  border-spacing: 0 0;
41
- -webkit-margin-after: 32px;
42
- margin-block-end: 32px;
43
43
  border-collapse: separate;
44
44
  background: rgb(var(--cell-bg-rgb));
45
+ -webkit-border-end: 1px solid transparent;
46
+ border-inline-end: 1px solid transparent;
47
+ }
48
+ .nano-tbl__top-anchor {
49
+ clip: rect(1px, 1px, 1px, 1px);
50
+ -webkit-clip-path: inset(50%);
51
+ clip-path: inset(50%);
52
+ block-size: 1px;
53
+ inline-size: 1px;
54
+ margin: -1px;
55
+ overflow: hidden;
56
+ padding: 0;
57
+ position: absolute;
45
58
  }
46
59
  .nano-tbl__ordered {
47
60
  background-color: var(--ordered-bg);
@@ -76,12 +89,23 @@ nano-table {
76
89
  display: flex;
77
90
  gap: 10px;
78
91
  }
79
- .nano-tbl__loader {
80
- font-size: 2rem;
92
+ .nano-tbl__progress-bar {
93
+ font-size: 0.2rem;
94
+ position: sticky;
95
+ inset-block-start: 0;
96
+ inset-inline: 0;
97
+ z-index: 10;
98
+ -webkit-transition: scale 0.25s;
99
+ transition: scale 0.25s;
100
+ scale: 0;
81
101
  width: 100%;
82
- display: block;
102
+ height: 0;
103
+ }
104
+ .nano-tbl__progress-bar--show {
105
+ scale: 1;
106
+ height: auto;
83
107
  }
84
- .nano-tbl__caption {
108
+ .nano-tbl__caption--hide {
85
109
  clip: rect(1px, 1px, 1px, 1px);
86
110
  -webkit-clip-path: inset(50%);
87
111
  clip-path: inset(50%);
@@ -94,41 +118,47 @@ nano-table {
94
118
  }
95
119
  .nano-tbl__td, .nano-tbl__th {
96
120
  line-height: var(--cell-line-height);
97
- overflow: hidden;
98
- text-overflow: ellipsis;
99
- white-space: nowrap;
100
121
  text-align: start;
101
122
  -webkit-border-after: var(--border-style);
102
123
  border-block-end: var(--border-style);
103
- padding: var(--td-padding);
104
124
  max-width: var(--max-col-width);
105
125
  background-color: rgb(var(--cell-bg-rgb));
106
126
  }
107
127
  @media (min-width: 768px) {
108
- .nano-tbl__td:first-child, .nano-tbl__th:first-child {
128
+ .nano-tbl__td:first-child .nano-tbl__cell-content, .nano-tbl__th:first-child .nano-tbl__cell-content {
109
129
  -webkit-padding-start: var(--bookend-col-padding) !important;
110
130
  padding-inline-start: var(--bookend-col-padding) !important;
111
131
  }
112
- .nano-tbl__td:last-child, .nano-tbl__th:last-child {
132
+ .nano-tbl__td:last-child .nano-tbl__cell-content, .nano-tbl__th:last-child .nano-tbl__cell-content {
113
133
  -webkit-padding-end: var(--bookend-col-padding) !important;
114
134
  padding-inline-end: var(--bookend-col-padding) !important;
115
135
  }
116
136
  }
117
137
  thead .nano-tbl__td, thead .nano-tbl__th {
118
- padding: var(--head-th-padding);
119
138
  font-weight: 800;
120
139
  background: rgba(var(--head-bg-rgb), 90%);
121
140
  }
141
+ thead .nano-tbl__td .nano-tbl__cell-content, thead .nano-tbl__th .nano-tbl__cell-content {
142
+ padding: var(--head-th-padding);
143
+ }
122
144
  tfoot .nano-tbl__td, tfoot .nano-tbl__th {
123
- padding: var(--foot-th-padding);
124
145
  font-weight: 800;
125
146
  -webkit-border-after: none;
126
147
  border-block-end: none;
127
148
  background: rgba(var(--foot-bg-rgb), 90%);
128
149
  }
150
+ tfoot .nano-tbl__td .nano-tbl__cell-content, tfoot .nano-tbl__th .nano-tbl__cell-content {
151
+ padding: var(--foot-th-padding);
152
+ }
129
153
  .nano-tbl__td.nano-tbl__ordered, .nano-tbl__th.nano-tbl__ordered {
130
154
  background-color: rgba(var(--ordered-bg-rgb), 0.8) !important;
131
155
  }
156
+ .nano-tbl__cell-content {
157
+ overflow: hidden;
158
+ text-overflow: ellipsis;
159
+ white-space: nowrap;
160
+ padding: var(--td-padding);
161
+ }
132
162
  .nano-tbl tbody {
133
163
  will-change: scroll-position;
134
164
  visibility: visible;
@@ -143,11 +173,12 @@ tfoot .nano-tbl__td, tfoot .nano-tbl__th {
143
173
  }
144
174
  .nano-tbl__pin {
145
175
  position: sticky;
176
+ z-index: 1;
146
177
  }
147
178
  .nano-tbl__pin--start {
148
179
  inset-inline: -1px auto;
149
- will-change: scroll-position;
150
- overflow: visible;
180
+ -webkit-transition: max-width 0.25s;
181
+ transition: max-width 0.25s;
151
182
  }
152
183
  .nano-tbl__pin--start::after {
153
184
  content: "";
@@ -156,15 +187,27 @@ tfoot .nano-tbl__td, tfoot .nano-tbl__th {
156
187
  -webkit-box-shadow: 5px 0 4px 0 rgba(0, 0, 0, 0.2);
157
188
  box-shadow: 5px 0 4px 0 rgba(0, 0, 0, 0.2);
158
189
  opacity: 0;
190
+ z-index: -1;
159
191
  }
160
192
  .nano-tbl__pinned--start .nano-tbl__pin--start {
161
- z-index: 1;
193
+ z-index: 2;
194
+ }
195
+ @media (max-width: 576px) {
196
+ .nano-tbl__pinned--start .nano-tbl__pin--start {
197
+ max-width: 25vw !important;
198
+ }
162
199
  }
163
200
  .nano-tbl__pinned--start .nano-tbl__pin--start::after {
164
201
  opacity: 1;
165
202
  }
166
203
  .nano-tbl__pin--end {
167
204
  inset-inline: auto -1px;
205
+ max-width: min(50vw, 200px);
206
+ /*
207
+ I cannot think of a nice way to make stuck-end columns play nice on small screens :(
208
+ Changing the width when stuck (as we do for stuck-start columns) causes the whole positioning to change.
209
+ This fires the IO, thus un-sticks the column, thus causes the IO to fire which sticks the column ∞
210
+ */
168
211
  }
169
212
  .nano-tbl__pin--end::after {
170
213
  content: "";
@@ -173,38 +216,47 @@ tfoot .nano-tbl__td, tfoot .nano-tbl__th {
173
216
  -webkit-box-shadow: -5px 0 4px 0 rgba(0, 0, 0, 0.2);
174
217
  box-shadow: -5px 0 4px 0 rgba(0, 0, 0, 0.2);
175
218
  opacity: 0;
219
+ z-index: -1;
176
220
  }
177
221
  .nano-tbl__pinned--end .nano-tbl__pin--end {
178
- z-index: 2;
222
+ z-index: 3;
179
223
  }
180
224
  .nano-tbl__pinned--end .nano-tbl__pin--end::after {
181
225
  opacity: 1;
182
226
  }
227
+ @media (max-width: 576px) {
228
+ .nano-tbl__pin--start ~ .nano-tbl__pin--end {
229
+ inset-inline: auto auto;
230
+ }
231
+ .nano-tbl__pin--start ~ .nano-tbl__pin--end::after {
232
+ display: none;
233
+ }
234
+ }
183
235
  .nano-tbl__pin--top {
184
236
  inset-block: -1px auto;
185
237
  }
186
238
  .nano-tbl__pinned--top .nano-tbl__pin--top {
187
- z-index: 3;
239
+ z-index: 4;
188
240
  }
189
241
  .nano-tbl__pin--bottom {
190
242
  inset-block: auto -1px;
191
243
  }
192
244
  .nano-tbl__pinned--bottom .nano-tbl__pin--bottom {
193
- z-index: 4;
245
+ z-index: 5;
194
246
  -webkit-border-before: var(--border-tint-style);
195
247
  border-block-start: var(--border-tint-style);
196
248
  }
197
249
  .nano-tbl__pinned--top.nano-tbl__pinned--start .nano-tbl__pin--top.nano-tbl__pin--start {
198
- z-index: 5;
250
+ z-index: 6;
199
251
  }
200
252
  .nano-tbl__pinned--top.nano-tbl__pinned--end .nano-tbl__pin--top.nano-tbl__pin--end {
201
- z-index: 5;
253
+ z-index: 6;
202
254
  }
203
255
  .nano-tbl__pinned--bottom.nano-tbl__pinned--start .nano-tbl__pin--bottom.nano-tbl__pin--start {
204
- z-index: 5;
256
+ z-index: 6;
205
257
  }
206
258
  .nano-tbl__pinned--bottom.nano-tbl__pinned--end .nano-tbl__pin--bottom.nano-tbl__pin--end {
207
- z-index: 5;
259
+ z-index: 6;
208
260
  }
209
261
  .nano-tbl thead tr:last-of-type td,
210
262
  .nano-tbl thead tr:last-of-type th,
@@ -215,4 +267,22 @@ tfoot .nano-tbl__td, tfoot .nano-tbl__th {
215
267
  }
216
268
  .nano-tbl .unlimited-width {
217
269
  max-width: none;
270
+ }
271
+ .nano-tbl__spinner {
272
+ font-size: 1.5rem;
273
+ -webkit-transition: scale 0.25s;
274
+ transition: scale 0.25s;
275
+ scale: 0;
276
+ padding: 0.5rem;
277
+ position: absolute;
278
+ inset-block-end: 0;
279
+ inset-inline-start: calc(50% - 0.75rem);
280
+ z-index: -1;
281
+ }
282
+ .nano-tbl__spinner--show {
283
+ scale: 1;
284
+ position: sticky;
285
+ }
286
+ .nano-tbl nano-skeleton {
287
+ line-height: var(--cell-line-height);
218
288
  }
@@ -3,6 +3,7 @@
3
3
  */
4
4
  import { h, Host, readTask, Build, } from '@stencil/core';
5
5
  import { cyrb53 } from '../../utils/math';
6
+ import { debounce } from '../../utils/throttle';
6
7
  import { TableColHead, TableRow, TableCell, TableHeadFootRow, } from './table.children';
7
8
  import { CSSNAMESPACE } from './table.constants';
8
9
  import { generateStore, storeSearch, storeSetConfig, storeSetData, storeSort, storeFilter, } from './table.store';
@@ -22,12 +23,22 @@ function perMark(name, end = false) {
22
23
  }
23
24
  let id = 0;
24
25
  /**
25
- * Table
26
- * @slot - The tooltip's target element. Only the first element will be used as the target.
27
- * @slot content - The tooltip's content. Alternatively, you can use the content prop.
26
+ * A performant, accessible and semantic (uses real html `<table />`, `<tr />` etc) table and data-grid solution.
27
+ * - Built-in search
28
+ * - Built-in column filter
29
+ * - Built-in column sort
30
+ * - Easily swap in API / async based search / filter & sort
31
+ * - Pin headers, footers, rows, columns
32
+ * - Add custom rendering at every level
33
+ * - Add custom properties at every level
34
+ *
35
+ * @slot caption - The table's caption. You must either use this or the `caption` attribute.
28
36
  */
29
37
  export class Table {
30
38
  constructor() {
39
+ this.debounceSetLoading = (l) => {
40
+ this._loading = l;
41
+ };
31
42
  this.renderId = 'tbl-' + id++;
32
43
  this.filters = [];
33
44
  this.currentFilters = '';
@@ -45,8 +56,10 @@ export class Table {
45
56
  * @returns A promise
46
57
  */
47
58
  this.sortStart = async (order, column, element) => {
59
+ // did order change?
48
60
  if (this.currentSort === order + ':' + column)
49
61
  return;
62
+ this.loading = true;
50
63
  const sortEvent = this.nanoTblBeforeSort.emit({ column: column, order });
51
64
  if (sortEvent.defaultPrevented)
52
65
  return;
@@ -72,10 +85,13 @@ export class Table {
72
85
  console.warn('sort failed', e);
73
86
  this.currentSort = '';
74
87
  }
88
+ finally {
89
+ this.loading = false;
90
+ }
75
91
  };
76
92
  /**
77
- * Attaches an intersection observer to each rendered tbody elements
78
- * shows / hides intersecting blocks' and sets heights for when their hidden
93
+ * Attaches an intersection observer to each rendered tbody element
94
+ * shows / hides intersecting blocks' and sets heights for when they're hidden
79
95
  * @param el - the tbody element to observe
80
96
  * @param blockIndex - the rendering tbody we're attaching the IO to
81
97
  */
@@ -90,8 +106,8 @@ export class Table {
90
106
  // The Intersection Observer (IO) fires in an incorrect order when the scrolling is very fast
91
107
  // i.e. we go past blocks 3, 2, 1 and land on 0, but 3 can fire as 'intersecting' after 0.
92
108
  // To fix that, we check - for realsies - if the block IS visible.
93
- // BUT that test is not as sensitive to a block being visible as the IO,
94
- // so doesn't always fire if scrolling slowing
109
+ // BUT that test is not as sensitive to a block being visible via the IO,
110
+ // so doesn't always fire if scrolling slowly
95
111
  // *sigh*
96
112
  readTask(() => {
97
113
  if (this.scrollSpeed < 100 || isInViewport(el, 0.01)) {
@@ -108,7 +124,12 @@ export class Table {
108
124
  }
109
125
  });
110
126
  }
111
- }, { threshold: [0] });
127
+ }, {
128
+ threshold: [0],
129
+ root: this.scrollParent === document.scrollingElement
130
+ ? null
131
+ : this.scrollParent,
132
+ });
112
133
  blockIo.observe(el);
113
134
  this.blockIos.set(el, blockIo);
114
135
  };
@@ -120,7 +141,9 @@ export class Table {
120
141
  this.type = 'table';
121
142
  this.caption = undefined;
122
143
  this.showCaption = false;
123
- this.rows = [];
144
+ this._loading = true;
145
+ this.placeholderSize = 5;
146
+ this.rows = undefined;
124
147
  this.columns = [];
125
148
  this.headRender = { pinned: 'top' };
126
149
  this.rowRender = undefined;
@@ -133,9 +156,29 @@ export class Table {
133
156
  this.blocks = [];
134
157
  this.activeBlocks = [0, 1, 2];
135
158
  this.measureHeight = 0;
159
+ this.debounceSetLoading = debounce(this.debounceSetLoading.bind(this), 50);
160
+ }
161
+ /** Will show a loading state when true.
162
+ * Will be shown automatically if `rows` is a promise waiting to resolve
163
+ * or when performing custom filtering or sorting */
164
+ get loading() {
165
+ return this._loading;
166
+ }
167
+ set loading(l) {
168
+ this.debounceSetLoading(l);
136
169
  }
137
170
  handleRowsChange() {
138
- storeSetData(this.host, this.rows);
171
+ if (!this.rows)
172
+ return;
173
+ this.loading = true;
174
+ Promise.resolve(this.rows).then(async (rows) => {
175
+ await storeSetData(this.host, rows);
176
+ if (!this.isReady) {
177
+ await this.columnInit();
178
+ this.setInitialBlockDimension();
179
+ }
180
+ this.loading = false;
181
+ });
139
182
  }
140
183
  handleColsChange() {
141
184
  storeSetConfig(this.host, this.columns);
@@ -183,6 +226,8 @@ export class Table {
183
226
  }
184
227
  // uses the first 'tr' of an active block as our yard stick
185
228
  set measureEle(el) {
229
+ if (!el)
230
+ return;
186
231
  this.measureHeight = el.getBoundingClientRect().height;
187
232
  this.unitHeight =
188
233
  el.querySelector('tr')?.getBoundingClientRect().height || this.unitHeight;
@@ -230,6 +275,7 @@ export class Table {
230
275
  perMark('sort', true);
231
276
  }
232
277
  async searchStart() {
278
+ this.loading = true;
233
279
  const sortEvent = this.nanoTblBeforeSearch.emit({ term: this.searchTerm });
234
280
  if (sortEvent.defaultPrevented)
235
281
  return;
@@ -241,7 +287,12 @@ export class Table {
241
287
  this.nanoTblAfterSearch.emit({ term: this.searchTerm });
242
288
  perMark('search', true);
243
289
  }
244
- catch (e) { }
290
+ catch (e) {
291
+ console.warn('search failed', e);
292
+ }
293
+ finally {
294
+ this.loading = false;
295
+ }
245
296
  }
246
297
  async filterStart(filters, additive = true) {
247
298
  if (filters) {
@@ -257,6 +308,7 @@ export class Table {
257
308
  }
258
309
  if (this.currentFilters === JSON.stringify(this.filters))
259
310
  return;
311
+ this.loading = true;
260
312
  const sortEvent = this.nanoTblBeforeFilter.emit({ filters: this.filters });
261
313
  if (sortEvent.defaultPrevented)
262
314
  return;
@@ -280,7 +332,12 @@ export class Table {
280
332
  this.filterComplete();
281
333
  perMark('search', true);
282
334
  }
283
- catch (e) { }
335
+ catch (e) {
336
+ console.warn('filter failed', e);
337
+ }
338
+ finally {
339
+ this.loading = false;
340
+ }
284
341
  }
285
342
  filterComplete() {
286
343
  this.columns = this.columns.map((c) => {
@@ -295,16 +352,20 @@ export class Table {
295
352
  /** Scrolls to the top immediately - used whilst sorting / filtering */
296
353
  scrollToTop(element) {
297
354
  const scrollBehaviour = this.scrollParent.style?.scrollBehavior;
355
+ const scrollX = this.scrollParent.scrollLeft;
298
356
  this.scrollParent.style.scrollBehavior = 'auto';
299
- this.host.scrollIntoView();
357
+ if (this.topAnchorEle && !isInViewport(this.topAnchorEle, 0.1))
358
+ this.topAnchorEle.scrollIntoView();
300
359
  if (element)
301
- element.scrollIntoView();
360
+ element.scrollIntoView({ block: 'start' });
361
+ if (scrollX)
362
+ this.scrollParent.scrollLeft = scrollX;
302
363
  if (scrollBehaviour)
303
364
  this.scrollParent.style.scrollBehavior = scrollBehaviour;
304
365
  }
305
366
  setMeasureElement() {
306
367
  readTask(() => {
307
- this.measureEle = this.blockElements.find((b) => !b.classList?.contains(`${CSSNAMESPACE}__inactive`));
368
+ this.measureEle = this.blockElements.find((b) => !b?.classList?.contains(`${CSSNAMESPACE}__inactive`));
308
369
  });
309
370
  }
310
371
  /**
@@ -330,11 +391,6 @@ export class Table {
330
391
  }
331
392
  if (i === this.blockElements.length - 1)
332
393
  resolve();
333
- // const heightGuess = this.getBlockHeight(this.blockElements.indexOf(el));
334
- // writeTask(() => {
335
- // el.style.height = heightGuess;
336
- // if (i === this.blockElements.length - 1) resolve();
337
- // });
338
394
  });
339
395
  });
340
396
  });
@@ -422,8 +478,8 @@ export class Table {
422
478
  if (!el)
423
479
  return;
424
480
  const height = el.getBoundingClientRect().height;
425
- // cache height to our block heights
426
- // array for subsequent renders
481
+ // cache height to our block heights array
482
+ // for subsequent renders
427
483
  const fBhI = this.blockHeights.findIndex((bh) => bh.blockIndex === blockIndex);
428
484
  if (fBhI > 0) {
429
485
  this.blockHeights[fBhI] = { height, blockIndex };
@@ -443,8 +499,8 @@ export class Table {
443
499
  // Component lifecycle
444
500
  async componentWillLoad() {
445
501
  perMark('init');
446
- this.store = await generateStore(this.host, this.rows, this.columns);
447
- await this.columnInit();
502
+ this.store = await generateStore(this.host, this.columns, this.scrollParent);
503
+ await this.handleRowsChange();
448
504
  this.processSlots();
449
505
  this.setBlocks();
450
506
  this.store.data.onChange('rows', () => this.setBlocks());
@@ -472,9 +528,17 @@ export class Table {
472
528
  }
473
529
  render() {
474
530
  this.blockElements = [];
475
- return (h(Host, null, h("div", { "aria-labelledby": 'table-caption-' + this.renderId, tabindex: this.type === 'grid' ? '0' : undefined }, h("table", { role: this.type === 'grid' ? 'grid' : undefined, "aria-readonly": this.type === 'table' ? 'true' : undefined, "aria-rowcount": this.store.data.state.rows.length, "aria-colcount": this.store.config.state.columns.length, class: `${CSSNAMESPACE}`, ref: (tbl) => (this.tableEle = tbl) }, h("caption", { class: `${CSSNAMESPACE}__caption`, id: 'table-caption-' + this.renderId }, h("slot", { name: "caption" }, this.caption)), h("thead", null, h(TableHeadFootRow, { rowRenderer: this.headRender, onColumnPinned: this.handleColumnPinned }, this.store.config.state.columns.map((colModel) => [
531
+ return (h(Host, null, h("div", { class: `${CSSNAMESPACE}__top-anchor`, ref: (a) => (this.topAnchorEle = a) }, "\u00A0"), h("div", { "aria-labelledby": 'table-caption-' + this.renderId, tabindex: this.type === 'grid' ? '0' : undefined }, h("nano-progress-bar", { indeterminate: true, class: {
532
+ [`${CSSNAMESPACE}__progress-bar`]: true,
533
+ [`${CSSNAMESPACE}__progress-bar--show`]: this.loading,
534
+ } }), h("table", { role: this.type === 'grid' ? 'grid' : undefined, "aria-readonly": this.type === 'table' ? 'true' : undefined, "aria-rowcount": this.store.data.state.rows.length, "aria-colcount": this.store.config.state.columns.length, class: `${CSSNAMESPACE}`, ref: (tbl) => (this.tableEle = tbl) }, h("caption", { class: {
535
+ [`${CSSNAMESPACE}__caption`]: true,
536
+ [`${CSSNAMESPACE}__caption--hide`]: !this.showCaption,
537
+ }, id: 'table-caption-' + this.renderId }, h("slot", { name: "caption" }, this.caption)), h("thead", null, h(TableHeadFootRow, { rowRenderer: this.headRender, onColumnPinned: this.handleColumnPinned }, this.store.config.state.columns.map((colModel) => [
476
538
  h(TableColHead, { column: colModel, headRenderer: this.headRender, onColumnOrderClick: this.sortStart, onColumnPinned: this.handleColumnPinned }),
477
- ]))), this.blocks.map((block, blockIndex) => (h("tbody", { key: block.__uuid, id: `tbody-${this.renderId}-${blockIndex}`, ref: (tb) => {
539
+ ]))), this.loading &&
540
+ !this.blocks.length &&
541
+ [...Array(10).keys()].map((rowIndex) => (h("tr", null, this.store.config.state.columns.map((_colModel, colIndex) => (h(TableCell, { rowIndex: rowIndex, colIndex: colIndex, nestedContent: h("nano-skeleton", null) })))))), this.blocks.map((block, blockIndex) => (h("tbody", { key: block.__uuid, id: `tbody-${this.renderId}-${blockIndex}`, ref: (tb) => {
478
542
  this.blockElements.push(tb);
479
543
  this.setupBlockIO(tb, blockIndex);
480
544
  }, class: {
@@ -485,9 +549,12 @@ export class Table {
485
549
  return (h(TableRow, { rowRenderer: this.rowRender, row: row }, this.store.config.state.columns.map((_colModel, colIndex) => (h(TableCell, { rowIndex: rowIndex, colIndex: colIndex })))));
486
550
  })) : (h("td", { colSpan: this.store.config.state.columns.length, style: {
487
551
  height: this.getBlockHeight(blockIndex),
488
- } }))))), (this.showFooter || !!this.footRender) && (h("tfoot", null, h(TableHeadFootRow, { rowRenderer: this.footRender, onColumnPinned: this.handleColumnPinned }, this.store.config.state.columns.map((colModel) => [
552
+ } }))))), this.showFooter && (h("tfoot", null, h(TableHeadFootRow, { rowRenderer: this.footRender, onColumnPinned: this.handleColumnPinned }, this.store.config.state.columns.map((colModel) => [
489
553
  h(TableColHead, { column: colModel, headRenderer: this.footRender, onColumnPinned: this.handleColumnPinned }),
490
- ]))))))));
554
+ ]))))), !!this.blocks.length && (h("nano-spinner", { type: "circle", class: {
555
+ [`${CSSNAMESPACE}__spinner`]: true,
556
+ [`${CSSNAMESPACE}__spinner--show`]: this.loading,
557
+ } })))));
491
558
  }
492
559
  static get is() { return "nano-table"; }
493
560
  static get originalStyleUrls() {
@@ -561,16 +628,59 @@ export class Table {
561
628
  "reflect": false,
562
629
  "defaultValue": "false"
563
630
  },
631
+ "loading": {
632
+ "type": "boolean",
633
+ "mutable": false,
634
+ "complexType": {
635
+ "original": "boolean",
636
+ "resolved": "boolean",
637
+ "references": {}
638
+ },
639
+ "required": false,
640
+ "optional": false,
641
+ "docs": {
642
+ "tags": [],
643
+ "text": "Will show a loading state when true.\nWill be shown automatically if `rows` is a promise waiting to resolve\nor when performing custom filtering or sorting"
644
+ },
645
+ "getter": true,
646
+ "setter": true,
647
+ "attribute": "loading",
648
+ "reflect": false,
649
+ "defaultValue": "true"
650
+ },
651
+ "placeholderSize": {
652
+ "type": "number",
653
+ "mutable": false,
654
+ "complexType": {
655
+ "original": "number",
656
+ "resolved": "number",
657
+ "references": {}
658
+ },
659
+ "required": false,
660
+ "optional": false,
661
+ "docs": {
662
+ "tags": [],
663
+ "text": "When loading rows asynchronously, this will render this number of placeholder rows"
664
+ },
665
+ "getter": false,
666
+ "setter": false,
667
+ "attribute": "placeholder-size",
668
+ "reflect": false,
669
+ "defaultValue": "5"
670
+ },
564
671
  "rows": {
565
672
  "type": "unknown",
566
673
  "mutable": false,
567
674
  "complexType": {
568
- "original": "TableTypes.NanoTable['rows']",
569
- "resolved": "RowData[]",
675
+ "original": "| TableTypes.NanoTable['rows']\n | Promise<TableTypes.NanoTable['rows']>",
676
+ "resolved": "Promise<RowData[]> | RowData[]",
570
677
  "references": {
571
678
  "TableTypes": {
572
679
  "location": "import",
573
680
  "path": "../../interface"
681
+ },
682
+ "Promise": {
683
+ "location": "global"
574
684
  }
575
685
  }
576
686
  },
@@ -581,8 +691,7 @@ export class Table {
581
691
  "text": "The data to place in the table"
582
692
  },
583
693
  "getter": false,
584
- "setter": false,
585
- "defaultValue": "[]"
694
+ "setter": false
586
695
  },
587
696
  "columns": {
588
697
  "type": "unknown",
@@ -807,6 +916,7 @@ export class Table {
807
916
  }
808
917
  static get states() {
809
918
  return {
919
+ "_loading": {},
810
920
  "blocks": {},
811
921
  "activeBlocks": {},
812
922
  "measureHeight": {}
@@ -946,7 +1056,7 @@ export class Table {
946
1056
  "composed": true,
947
1057
  "docs": {
948
1058
  "tags": [],
949
- "text": "Fired after a general search"
1059
+ "text": "Fired after a general / cross column search"
950
1060
  },
951
1061
  "complexType": {
952
1062
  "original": "{ term: string }",