@geotab/zenith 3.16.0 → 3.17.0-beta.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 (282) hide show
  1. package/README.md +67 -1
  2. package/README.md.baseline +1 -0
  3. package/dist/absolute/absolute.js +5 -1
  4. package/dist/button/button.d.ts +2 -1
  5. package/dist/button/button.js +22 -5
  6. package/dist/checkboxListWithAction/checkboxListWithAction.d.ts +2 -0
  7. package/dist/checkboxListWithAction/checkboxListWithAction.js +1 -1
  8. package/dist/commonHelpers/ShowMoreCell.d.ts +5 -0
  9. package/dist/commonHelpers/ShowMoreCell.js +66 -0
  10. package/dist/commonHelpers/getAriaAttributes.js +6 -9
  11. package/dist/commonHelpers/getNonAriaProps.d.ts +11 -0
  12. package/dist/commonHelpers/getNonAriaProps.js +19 -0
  13. package/dist/commonHelpers/hooks/useScroll.d.ts +1 -1
  14. package/dist/commonHelpers/hooks/useScroll.js +6 -6
  15. package/dist/commonHelpers/isAriaProp.d.ts +9 -0
  16. package/dist/commonHelpers/isAriaProp.js +13 -0
  17. package/dist/commonHelpers/showMoreRow.d.ts +28 -0
  18. package/dist/commonHelpers/showMoreRow.js +29 -0
  19. package/dist/commonHelpers/tabsKeyboard.d.ts +1 -1
  20. package/dist/commonHelpers/tabsKeyboard.js +15 -1
  21. package/dist/commonStyles/colors/colors.less +18 -0
  22. package/dist/dataFeed/dataFeedColumnsItems.js +3 -1
  23. package/dist/dataGrid/columns/checkboxColumn/checkboxCell.d.ts +2 -1
  24. package/dist/dataGrid/columns/checkboxColumn/checkboxCell.js +1 -1
  25. package/dist/dataGrid/columns/checkboxColumn/checkboxColumnWrapper.d.ts +4 -2
  26. package/dist/dataGrid/columns/checkboxColumn/checkboxColumnWrapper.js +10 -1
  27. package/dist/dataGrid/dataGrid.d.ts +5 -1
  28. package/dist/dataGrid/dataGrid.js +39 -2
  29. package/dist/dataGrid/lazyLoadingEnd/lazyLoadingEnd.d.ts +3 -0
  30. package/dist/dataGrid/lazyLoadingEnd/lazyLoadingEnd.js +54 -0
  31. package/dist/dataGrid/row/row.js +20 -2
  32. package/dist/dataGrid/withSelectableRows/components/bulkActions/bulkActions.d.ts +3 -1
  33. package/dist/dataGrid/withSelectableRows/components/bulkActions/bulkActions.js +39 -4
  34. package/dist/dataGrid/withSelectableRows/withSelectableRows.js +73 -12
  35. package/dist/dropdown/dropdownTrigger.d.ts +1 -1
  36. package/dist/dropdownRaw/dropdownHelper.d.ts +12 -0
  37. package/dist/dropdownRaw/dropdownHelper.js +32 -11
  38. package/dist/dropdownRaw/dropdownRaw.js +36 -8
  39. package/dist/dropdownRaw/dropdownSearchableTrigger.d.ts +2 -1
  40. package/dist/dropdownRaw/dropdownSearchableTrigger.js +13 -6
  41. package/dist/dropdownRaw/dropdownTrigger.d.ts +2 -1
  42. package/dist/dropdownRaw/dropdownTrigger.js +2 -2
  43. package/dist/dropdownRaw/stateReducer/stateReducer.d.ts +8 -0
  44. package/dist/dropdownRaw/stateReducer/stateReducer.js +5 -2
  45. package/dist/dropdownRaw/types.d.ts +36 -0
  46. package/dist/filterButton/filterButton.d.ts +1 -1
  47. package/dist/formGroup/hooks/rowHooks/useLabelClasses.js +8 -2
  48. package/dist/formLayout/utils/applyLayoutPosition/applyLayoutPosition.d.ts +2 -1
  49. package/dist/formLayout/utils/applyLayoutPosition/applyLayoutPosition.js +37 -90
  50. package/dist/header/components/collapsedItemsControl/collapsedItemsControl.d.ts +1 -1
  51. package/dist/header/components/collapsedItemsControl/collapsedItemsControl.js +6 -2
  52. package/dist/header/headerButton.d.ts +3 -1
  53. package/dist/header/headerButton.js +4 -2
  54. package/dist/header/headerMenu.d.ts +2 -0
  55. package/dist/header/headerMenu.js +1 -1
  56. package/dist/index.css +319 -68
  57. package/dist/index.d.ts +3 -1
  58. package/dist/index.js +9 -3
  59. package/dist/menu/components/menuButton.d.ts +3 -1
  60. package/dist/menu/components/menuButton.js +66 -47
  61. package/dist/menu/components/menuItem.js +4 -4
  62. package/dist/miniTabs/miniTabs.js +4 -2
  63. package/dist/pageHeader/pageHeaderButton.d.ts +1 -1
  64. package/dist/pageHeader/pageHeaderButton.js +4 -2
  65. package/dist/pagination/pagination.d.ts +19 -4
  66. package/dist/pagination/pagination.js +21 -1
  67. package/dist/pagination/paginationText/paginationText.d.ts +7 -1
  68. package/dist/pagination/paginationText/paginationText.js +6 -3
  69. package/dist/pillExpandable/pillContent.d.ts +3 -2
  70. package/dist/pillExpandable/pillContent.js +2 -2
  71. package/dist/pillExpandable/pillExpandable.js +20 -5
  72. package/dist/pillExpandable/pillExpandablePopoverContent.d.ts +3 -2
  73. package/dist/pillExpandable/pillExpandablePopoverContent.js +1 -1
  74. package/dist/pillExpandable/pillExpandableSimple.d.ts +3 -1
  75. package/dist/pillExpandable/pillExpandableSimple.js +19 -9
  76. package/dist/selectList/selectList.js +1 -0
  77. package/dist/selectList/selectListItem.d.ts +10 -1
  78. package/dist/selectList/selectListItem.js +12 -9
  79. package/dist/table/children/tablePagination.d.ts +1 -1
  80. package/dist/table/children/useTableChildren.d.ts +4 -2
  81. package/dist/table/children/useTableChildren.js +64 -16
  82. package/dist/table/nested/nestedData.d.ts +29 -1
  83. package/dist/table/nested/nestedData.js +45 -4
  84. package/dist/table/nested/useNestedRows.js +18 -22
  85. package/dist/table/nested/useShowMore.d.ts +41 -0
  86. package/dist/table/nested/useShowMore.js +56 -0
  87. package/dist/table/selectable/interfaces.d.ts +17 -0
  88. package/dist/table/selectable/useDragSelection.d.ts +10 -0
  89. package/dist/table/selectable/useDragSelection.js +145 -0
  90. package/dist/table/selectable/useSelectableRows.d.ts +5 -2
  91. package/dist/table/selectable/useSelectableRows.js +131 -36
  92. package/dist/table/selectable/utils/calculateSelectionState.d.ts +1 -1
  93. package/dist/table/selectable/utils/calculateSelectionState.js +43 -7
  94. package/dist/table/selectable/utils/checkRow.js +4 -2
  95. package/dist/table/selectable/utils/getCurrentPageSelection.js +9 -5
  96. package/dist/table/selectable/utils/getDragSelectionRows.d.ts +15 -0
  97. package/dist/table/selectable/utils/getDragSelectionRows.js +28 -0
  98. package/dist/table/selectable/utils/getRangeIds.d.ts +2 -0
  99. package/dist/table/selectable/utils/getRangeIds.js +21 -0
  100. package/dist/table/selectable/utils/isRowChecked.d.ts +1 -1
  101. package/dist/table/selectable/utils/isRowChecked.js +40 -7
  102. package/dist/table/table.d.ts +1 -2
  103. package/dist/table/table.js +58 -31
  104. package/dist/tabs/tabs.d.ts +1 -0
  105. package/dist/tabs/tabs.js +50 -17
  106. package/dist/textInputRaw/textInputRaw.js +3 -2
  107. package/dist/tooltip/tooltip.d.ts +2 -0
  108. package/dist/tooltip/tooltip.js +19 -7
  109. package/dist/utils/localization/translations/ar-001.json +1 -0
  110. package/dist/utils/localization/translations/bg-BG.json +1 -0
  111. package/dist/utils/localization/translations/cs.json +1 -0
  112. package/dist/utils/localization/translations/da-DK.json +1 -0
  113. package/dist/utils/localization/translations/de.json +1 -0
  114. package/dist/utils/localization/translations/el-GR.json +1 -0
  115. package/dist/utils/localization/translations/en.json +4 -0
  116. package/dist/utils/localization/translations/es.json +1 -0
  117. package/dist/utils/localization/translations/et-EE.json +1 -0
  118. package/dist/utils/localization/translations/fi-FI.json +1 -0
  119. package/dist/utils/localization/translations/fr-FR.json +1 -0
  120. package/dist/utils/localization/translations/fr.json +1 -0
  121. package/dist/utils/localization/translations/hu-HU.json +1 -0
  122. package/dist/utils/localization/translations/id.json +1 -0
  123. package/dist/utils/localization/translations/it.json +1 -0
  124. package/dist/utils/localization/translations/ja.json +1 -0
  125. package/dist/utils/localization/translations/ka-GE.json +1 -0
  126. package/dist/utils/localization/translations/ko-KR.json +1 -0
  127. package/dist/utils/localization/translations/lt-LT.json +1 -0
  128. package/dist/utils/localization/translations/lv-LV.json +1 -0
  129. package/dist/utils/localization/translations/ms.json +1 -0
  130. package/dist/utils/localization/translations/nb-NO.json +1 -0
  131. package/dist/utils/localization/translations/nl.json +1 -0
  132. package/dist/utils/localization/translations/pl.json +1 -0
  133. package/dist/utils/localization/translations/pt-BR.json +1 -0
  134. package/dist/utils/localization/translations/pt-PT.json +1 -0
  135. package/dist/utils/localization/translations/ro-RO.json +1 -0
  136. package/dist/utils/localization/translations/sk-SK.json +1 -0
  137. package/dist/utils/localization/translations/sv.json +1 -0
  138. package/dist/utils/localization/translations/th.json +1 -0
  139. package/dist/utils/localization/translations/tr.json +1 -0
  140. package/dist/utils/localization/translations/zh-Hans.json +1 -0
  141. package/dist/utils/localization/translations/zh-TW.json +1 -0
  142. package/dist/waiting/waiting.js +95 -1
  143. package/esm/absolute/absolute.js +5 -1
  144. package/esm/button/button.d.ts +2 -1
  145. package/esm/button/button.js +22 -5
  146. package/esm/checkboxListWithAction/checkboxListWithAction.d.ts +2 -0
  147. package/esm/checkboxListWithAction/checkboxListWithAction.js +1 -1
  148. package/esm/commonHelpers/ShowMoreCell.d.ts +5 -0
  149. package/esm/commonHelpers/ShowMoreCell.js +57 -0
  150. package/esm/commonHelpers/getAriaAttributes.js +6 -9
  151. package/esm/commonHelpers/getNonAriaProps.d.ts +11 -0
  152. package/esm/commonHelpers/getNonAriaProps.js +15 -0
  153. package/esm/commonHelpers/hooks/useScroll.d.ts +1 -1
  154. package/esm/commonHelpers/hooks/useScroll.js +6 -6
  155. package/esm/commonHelpers/isAriaProp.d.ts +9 -0
  156. package/esm/commonHelpers/isAriaProp.js +9 -0
  157. package/esm/commonHelpers/showMoreRow.d.ts +28 -0
  158. package/esm/commonHelpers/showMoreRow.js +22 -0
  159. package/esm/commonHelpers/tabsKeyboard.d.ts +1 -1
  160. package/esm/commonHelpers/tabsKeyboard.js +15 -1
  161. package/esm/commonStyles/colors/colorsConstant.js +11 -11
  162. package/esm/dataFeed/dataFeedColumnsItems.js +3 -1
  163. package/esm/dataGrid/columns/checkboxColumn/checkboxCell.d.ts +2 -1
  164. package/esm/dataGrid/columns/checkboxColumn/checkboxCell.js +1 -1
  165. package/esm/dataGrid/columns/checkboxColumn/checkboxColumnWrapper.d.ts +4 -2
  166. package/esm/dataGrid/columns/checkboxColumn/checkboxColumnWrapper.js +10 -1
  167. package/esm/dataGrid/dataGrid.d.ts +5 -1
  168. package/esm/dataGrid/dataGrid.js +38 -2
  169. package/esm/dataGrid/lazyLoadingEnd/lazyLoadingEnd.d.ts +3 -0
  170. package/esm/dataGrid/lazyLoadingEnd/lazyLoadingEnd.js +45 -0
  171. package/esm/dataGrid/row/row.js +20 -2
  172. package/esm/dataGrid/withSelectableRows/components/bulkActions/bulkActions.d.ts +3 -1
  173. package/esm/dataGrid/withSelectableRows/components/bulkActions/bulkActions.js +39 -4
  174. package/esm/dataGrid/withSelectableRows/withSelectableRows.js +73 -12
  175. package/esm/dropdown/dropdownTrigger.d.ts +1 -1
  176. package/esm/dropdownRaw/dropdownHelper.d.ts +12 -0
  177. package/esm/dropdownRaw/dropdownHelper.js +30 -10
  178. package/esm/dropdownRaw/dropdownRaw.js +37 -9
  179. package/esm/dropdownRaw/dropdownSearchableTrigger.d.ts +2 -1
  180. package/esm/dropdownRaw/dropdownSearchableTrigger.js +13 -6
  181. package/esm/dropdownRaw/dropdownTrigger.d.ts +2 -1
  182. package/esm/dropdownRaw/dropdownTrigger.js +2 -2
  183. package/esm/dropdownRaw/stateReducer/stateReducer.d.ts +8 -0
  184. package/esm/dropdownRaw/stateReducer/stateReducer.js +5 -2
  185. package/esm/dropdownRaw/types.d.ts +36 -0
  186. package/esm/filterButton/filterButton.d.ts +1 -1
  187. package/esm/formGroup/hooks/rowHooks/useLabelClasses.js +8 -2
  188. package/esm/formLayout/utils/applyLayoutPosition/applyLayoutPosition.d.ts +2 -1
  189. package/esm/formLayout/utils/applyLayoutPosition/applyLayoutPosition.js +37 -90
  190. package/esm/header/components/collapsedItemsControl/collapsedItemsControl.d.ts +1 -1
  191. package/esm/header/components/collapsedItemsControl/collapsedItemsControl.js +6 -2
  192. package/esm/header/headerButton.d.ts +3 -1
  193. package/esm/header/headerButton.js +4 -2
  194. package/esm/header/headerMenu.d.ts +2 -0
  195. package/esm/header/headerMenu.js +1 -1
  196. package/esm/index.d.ts +3 -1
  197. package/esm/index.js +3 -1
  198. package/esm/menu/components/menuButton.d.ts +3 -1
  199. package/esm/menu/components/menuButton.js +66 -47
  200. package/esm/menu/components/menuItem.js +4 -4
  201. package/esm/miniTabs/miniTabs.js +4 -2
  202. package/esm/pageHeader/pageHeaderButton.d.ts +1 -1
  203. package/esm/pageHeader/pageHeaderButton.js +4 -2
  204. package/esm/pagination/pagination.d.ts +19 -4
  205. package/esm/pagination/pagination.js +21 -1
  206. package/esm/pagination/paginationText/paginationText.d.ts +7 -1
  207. package/esm/pagination/paginationText/paginationText.js +6 -3
  208. package/esm/pillExpandable/pillContent.d.ts +3 -2
  209. package/esm/pillExpandable/pillContent.js +2 -2
  210. package/esm/pillExpandable/pillExpandable.js +20 -5
  211. package/esm/pillExpandable/pillExpandablePopoverContent.d.ts +3 -2
  212. package/esm/pillExpandable/pillExpandablePopoverContent.js +1 -1
  213. package/esm/pillExpandable/pillExpandableSimple.d.ts +3 -1
  214. package/esm/pillExpandable/pillExpandableSimple.js +20 -10
  215. package/esm/selectList/selectList.js +1 -0
  216. package/esm/selectList/selectListItem.d.ts +10 -1
  217. package/esm/selectList/selectListItem.js +12 -9
  218. package/esm/table/children/tablePagination.d.ts +1 -1
  219. package/esm/table/children/useTableChildren.d.ts +4 -2
  220. package/esm/table/children/useTableChildren.js +64 -16
  221. package/esm/table/nested/nestedData.d.ts +29 -1
  222. package/esm/table/nested/nestedData.js +44 -3
  223. package/esm/table/nested/useNestedRows.js +18 -22
  224. package/esm/table/nested/useShowMore.d.ts +41 -0
  225. package/esm/table/nested/useShowMore.js +52 -0
  226. package/esm/table/selectable/interfaces.d.ts +17 -0
  227. package/esm/table/selectable/useDragSelection.d.ts +10 -0
  228. package/esm/table/selectable/useDragSelection.js +141 -0
  229. package/esm/table/selectable/useSelectableRows.d.ts +5 -2
  230. package/esm/table/selectable/useSelectableRows.js +129 -35
  231. package/esm/table/selectable/utils/calculateSelectionState.d.ts +1 -1
  232. package/esm/table/selectable/utils/calculateSelectionState.js +43 -7
  233. package/esm/table/selectable/utils/checkRow.js +4 -2
  234. package/esm/table/selectable/utils/getCurrentPageSelection.js +9 -5
  235. package/esm/table/selectable/utils/getDragSelectionRows.d.ts +15 -0
  236. package/esm/table/selectable/utils/getDragSelectionRows.js +24 -0
  237. package/esm/table/selectable/utils/getRangeIds.d.ts +2 -0
  238. package/esm/table/selectable/utils/getRangeIds.js +17 -0
  239. package/esm/table/selectable/utils/isRowChecked.d.ts +1 -1
  240. package/esm/table/selectable/utils/isRowChecked.js +40 -7
  241. package/esm/table/table.d.ts +1 -2
  242. package/esm/table/table.js +43 -16
  243. package/esm/tabs/tabs.d.ts +1 -0
  244. package/esm/tabs/tabs.js +50 -17
  245. package/esm/textInputRaw/textInputRaw.js +3 -2
  246. package/esm/tooltip/tooltip.d.ts +2 -0
  247. package/esm/tooltip/tooltip.js +19 -7
  248. package/esm/utils/localization/translations/ar-001.json +1 -0
  249. package/esm/utils/localization/translations/bg-BG.json +1 -0
  250. package/esm/utils/localization/translations/cs.json +1 -0
  251. package/esm/utils/localization/translations/da-DK.json +1 -0
  252. package/esm/utils/localization/translations/de.json +1 -0
  253. package/esm/utils/localization/translations/el-GR.json +1 -0
  254. package/esm/utils/localization/translations/en.json +4 -0
  255. package/esm/utils/localization/translations/es.json +1 -0
  256. package/esm/utils/localization/translations/et-EE.json +1 -0
  257. package/esm/utils/localization/translations/fi-FI.json +1 -0
  258. package/esm/utils/localization/translations/fr-FR.json +1 -0
  259. package/esm/utils/localization/translations/fr.json +1 -0
  260. package/esm/utils/localization/translations/hu-HU.json +1 -0
  261. package/esm/utils/localization/translations/id.json +1 -0
  262. package/esm/utils/localization/translations/it.json +1 -0
  263. package/esm/utils/localization/translations/ja.json +1 -0
  264. package/esm/utils/localization/translations/ka-GE.json +1 -0
  265. package/esm/utils/localization/translations/ko-KR.json +1 -0
  266. package/esm/utils/localization/translations/lt-LT.json +1 -0
  267. package/esm/utils/localization/translations/lv-LV.json +1 -0
  268. package/esm/utils/localization/translations/ms.json +1 -0
  269. package/esm/utils/localization/translations/nb-NO.json +1 -0
  270. package/esm/utils/localization/translations/nl.json +1 -0
  271. package/esm/utils/localization/translations/pl.json +1 -0
  272. package/esm/utils/localization/translations/pt-BR.json +1 -0
  273. package/esm/utils/localization/translations/pt-PT.json +1 -0
  274. package/esm/utils/localization/translations/ro-RO.json +1 -0
  275. package/esm/utils/localization/translations/sk-SK.json +1 -0
  276. package/esm/utils/localization/translations/sv.json +1 -0
  277. package/esm/utils/localization/translations/th.json +1 -0
  278. package/esm/utils/localization/translations/tr.json +1 -0
  279. package/esm/utils/localization/translations/zh-Hans.json +1 -0
  280. package/esm/utils/localization/translations/zh-TW.json +1 -0
  281. package/esm/waiting/waiting.js +96 -2
  282. package/package.json +18 -6
@@ -2,8 +2,9 @@ import { injectString } from "../utils/localization/translationsDictionary";
2
2
  import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
3
3
  import { memo, useCallback, useEffect, useMemo, useRef, useState } from "react";
4
4
  import { DataFeed } from "../dataFeed/dataFeed";
5
- import { DataGrid as DataGridInternal } from "../dataGrid/dataGrid";
6
- import { useSelectableRows } from "./selectable/useSelectableRows";
5
+ import { DataGrid as DataGridInternal, EndOfList as DataGridEndOfList } from "../dataGrid/dataGrid";
6
+ import { LazyLoadingEnd } from "../dataGrid/lazyLoadingEnd/lazyLoadingEnd";
7
+ import { getEmptySelection, isAllSelection, useSelectableRows } from "./selectable/useSelectableRows";
7
8
  import { useSortableColumns } from "./sortable/useSortableColumns";
8
9
  import { useFlexibleColumns } from "./flexible/useFlexibleColumns";
9
10
  import { useActions } from "./actions/useActions";
@@ -15,12 +16,12 @@ import { ColumnsListButton } from "../dataGrid/entitiesListActions/actions/colum
15
16
  import { useTableChildren } from "./children/useTableChildren";
16
17
  import { DeviceType } from "../commonHelpers/hooks/deviceType";
17
18
  import { useMobile } from "../commonHelpers/hooks/useMobile";
19
+ import { getCurrentPageSelection } from "./selectable/utils/getCurrentPageSelection";
18
20
  import { TableFullscreen } from "./children/tableFullscreen";
19
21
  import { TableBulkActions } from "./children/tableBulkActions";
20
22
  import { TablePagination } from "./children/tablePagination";
21
23
  import { TableEmpty } from "./children/tableEmpty";
22
24
  import { TableFooter } from "./children/tableFooter";
23
- import { getEmptySelection } from "./selectable/useSelectableRows";
24
25
  import { ColumnSortDirection } from "./sortable/interfaces";
25
26
  import { getSortableValue } from "./sortable/useSortableColumns";
26
27
  import { ActionsColumn } from "../dataGrid/columns/actionsColumn/actionsColumn";
@@ -184,7 +185,7 @@ const TableInner = ({
184
185
  active,
185
186
  onClick
186
187
  }) => {
187
- var _a, _b, _c;
188
+ var _a, _b, _c, _d, _e;
188
189
  const isMobile = useMobile();
189
190
  const {
190
191
  translate
@@ -205,6 +206,8 @@ const TableInner = ({
205
206
  // Desktop infinite scroll is active when onScrollEnd is wired. In that mode there are no pages:
206
207
  // pagination is hidden and "Select current page" is suppressed (the checkbox selects all instead).
207
208
  const isInfinite = !!onScrollEnd;
209
+ const isAppendLoading = isLoading && (loading === null || loading === void 0 ? void 0 : loading.addToEnd) === true && entities.length > 0;
210
+ const selectableForRender = isLoading && !isAppendLoading ? undefined : selectable;
208
211
  // Announce loading/loaded state to screen readers (the skeleton rows are not perceivable to them).
209
212
  // Scoped to infinite scroll only: paged tables also pass `isLoading` for initial-fetch skeletons,
210
213
  // and "Loading more rows" / "N more rows loaded" are semantically wrong outside infinite scroll.
@@ -216,7 +219,13 @@ const TableInner = ({
216
219
  }
217
220
  if (isLoading) {
218
221
  setLiveMessage(translate("Loading more rows"));
219
- } else if (entities.length > prevEntitiesCountRef.current) {
222
+ // Don't advance the ref while loading: if `entities` and `isLoading` ever update across
223
+ // separate renders instead of together (e.g. without automatic batching), advancing here
224
+ // would make the next render see entities.length === prevEntitiesCountRef.current and
225
+ // silently skip the "N more rows loaded" announcement below.
226
+ return;
227
+ }
228
+ if (entities.length > prevEntitiesCountRef.current) {
220
229
  // Announce the delta (newly appended rows), not the running total — hearing
221
230
  // "500 rows loaded" on a later page is confusing when only a page just arrived.
222
231
  // Separate singular key because `translate()` has no plural support, so a raw
@@ -238,7 +247,7 @@ const TableInner = ({
238
247
  const {
239
248
  selectableColumns,
240
249
  selectableFeedWrapper
241
- } = useSelectableRows(nestedColumns, entities, isMobile, selectMode, setMobileSelectMode, isLoading ? undefined : selectable, isInfinite);
250
+ } = useSelectableRows(nestedColumns, entities, isMobile, selectMode, setMobileSelectMode, selectableForRender, isInfinite, gridRef, expanded);
242
251
  const {
243
252
  sortableColumns,
244
253
  feedSortControl
@@ -264,13 +273,21 @@ const TableInner = ({
264
273
  isFeedVisible,
265
274
  visibleColumns
266
275
  } = useFeedExpandable(isMobile, feedExpandable);
267
- const selectionQty = useMemo(() => {
276
+ // Keep bulk-action state available during initial/replacement loading for backward compatibility.
277
+ // The row controls themselves still use selectableForRender and remain hidden until real rows can render.
278
+ const allSelected = useMemo(() => {
268
279
  var _a, _b;
280
+ return isAllSelection((_a = selectable === null || selectable === void 0 ? void 0 : selectable.selection) === null || _a === void 0 ? void 0 : _a.all, (_b = selectable === null || selectable === void 0 ? void 0 : selectable.selection) === null || _b === void 0 ? void 0 : _b.selected.length, selectable === null || selectable === void 0 ? void 0 : selectable.allowExclusions);
281
+ }, [(_c = selectable === null || selectable === void 0 ? void 0 : selectable.selection) === null || _c === void 0 ? void 0 : _c.all, selectable === null || selectable === void 0 ? void 0 : selectable.allowExclusions, (_d = selectable === null || selectable === void 0 ? void 0 : selectable.selection) === null || _d === void 0 ? void 0 : _d.selected.length]);
282
+ const selectionQty = useMemo(() => {
283
+ var _a;
269
284
  if (!selectable) {
270
285
  return 0;
271
286
  }
272
- return ((_a = selectable.selection) === null || _a === void 0 ? void 0 : _a.all) ? loadingEntities.length : ((_b = selectable.selection) === null || _b === void 0 ? void 0 : _b.selected.length) || 0;
273
- }, [selectable, loadingEntities.length]);
287
+ const ids = new Set((_a = selectable.selection) === null || _a === void 0 ? void 0 : _a.selected);
288
+ const base = entities.length > 0 ? entities : loadingEntities;
289
+ return allSelected ? [...getCurrentPageSelection(base, selectable)].filter(id => !selectable.allowExclusions || !ids.has(id)).length : ids.size;
290
+ }, [selectable, entities, loadingEntities, allSelected]);
274
291
  const clearSelection = useCallback(() => {
275
292
  setSelectMode(false);
276
293
  selectable === null || selectable === void 0 ? void 0 : selectable.onSelect({
@@ -287,23 +304,31 @@ const TableInner = ({
287
304
  }, [onClickRow]);
288
305
  const {
289
306
  bulkActions,
307
+ hasSelection,
290
308
  pagination,
309
+ paginationTotal,
291
310
  activePage,
292
311
  fullscreenButton,
293
312
  emptyList,
294
313
  detailPanel,
295
314
  footer,
296
315
  other
297
- } = useTableChildren(children, isMobile, selectionQty, ((_c = selectable === null || selectable === void 0 ? void 0 : selectable.selection) === null || _c === void 0 ? void 0 : _c.all) || false, clearSelection, activeId, gridRef, onCloseDetailPanel);
316
+ } = useTableChildren(children, isMobile, selectionQty, allSelected, clearSelection, activeId, gridRef, onCloseDetailPanel, isInfinite, entities.length, (selectable === null || selectable === void 0 ? void 0 : selectable.allowExclusions) && ((_e = selectable.selection) === null || _e === void 0 ? void 0 : _e.all) ? new Set(selectable.selection.selected).size : 0, (selectable === null || selectable === void 0 ? void 0 : selectable.strategy) !== "nested" && !(selectable === null || selectable === void 0 ? void 0 : selectable.checkboxDisabled) && !(selectable === null || selectable === void 0 ? void 0 : selectable.checkboxVisible), !!feedEndCallback || !!isLoading);
298
317
  const hasDetailPanel = !!detailPanel;
299
318
  const shouldEnableRowClick = hasDetailPanel || !!onClick;
300
319
  const activeIdForRow = shouldEnableRowClick ? activeId : undefined;
301
320
  const onClickForRow = shouldEnableRowClick ? onClickRow : undefined;
302
321
  const handleOnHidePanel = useCallback(() => setSelectMode(false), []);
303
322
  const handleOnTriggerClick = useCallback(() => setSelectMode(prev => !prev), []);
304
- const hasPostActions = useMemo(() => columnsPopup || isMobile && selectable || !isMobile && fullscreenButton || isFeedVisible, [columnsPopup, fullscreenButton, isFeedVisible, isMobile, selectable]);
305
- // Pagination is desktop-only and is hidden in infinite-scroll mode (no pages).
306
- const showPagination = !!pagination && !isMobile && !isInfinite;
323
+ const hasPostActions = useMemo(() => columnsPopup || isMobile && selectableForRender || !isMobile && fullscreenButton || isFeedVisible, [columnsPopup, fullscreenButton, isFeedVisible, isMobile, selectableForRender]);
324
+ // Pagination is desktop-only. In infinite-scroll mode there are no pages, so when a
325
+ // Table.Pagination child is supplied, `pagination` is already the chevron-less "loaded X of Y"
326
+ // variant (see useTableChildren's `isInfinite` handling) rather than being hidden outright.
327
+ const showPagination = !!pagination && !isMobile;
328
+ // Shown as the last row once every row has been loaded (desktop infinite scroll only). Guarded
329
+ // on `paginationTotal` being a real, positive total from a Table.Pagination child — a consumer
330
+ // that hasn't opted in (no total) never sees this, and an empty list is handled by Table.Empty.
331
+ const isEndOfList = isInfinite && !isMobile && !isLoading && !!paginationTotal && entities.length >= paginationTotal;
307
332
  const hasToolbar = useMemo(() => bulkActions || feedSortControl || showPagination || other.length || columnsPopup || !isMobile && fullscreenButton || isFeedVisible, [bulkActions, columnsPopup, feedSortControl, fullscreenButton, isFeedVisible, isMobile, other.length, showPagination]);
308
333
  const gridAutoHeight = useMemo(() => contentHeight ? `${contentHeight}px` : undefined, [contentHeight]);
309
334
  const minHeight = "400px";
@@ -323,7 +348,7 @@ const TableInner = ({
323
348
  children: [hasToolbar ? _jsxs(EntitiesListActions, {
324
349
  gridType: isMobile ? DeviceType.Mobile : DeviceType.Desktop,
325
350
  children: [_jsxs(EntitiesListActions.Actions, {
326
- children: [!isMobile && bulkActions && selectionQty > 0 ? bulkActions : null, feedSortControl]
351
+ children: [!isMobile && hasSelection ? bulkActions : null, feedSortControl]
327
352
  }), showPagination || other.length > 0 ? _jsxs(EntitiesListActions.Pagination, {
328
353
  children: [_jsx(EntitiesListActions.CustomElements, {
329
354
  children: other
@@ -336,7 +361,7 @@ const TableInner = ({
336
361
  }) : null, isFeedVisible ? _jsx(FeedExpandControl, {
337
362
  isExpanded: isFeedExpanded,
338
363
  onClick: handleExpanded
339
- }) : null, isMobile && selectable ? _jsx(DataFeedSelectPanel, {
364
+ }) : null, isMobile && selectableForRender ? _jsx(DataFeedSelectPanel, {
340
365
  panelTitle: translate("Selection panel"),
341
366
  buttonTitle: translate("Bulk select"),
342
367
  onTriggerClick: handleOnTriggerClick,
@@ -389,7 +414,9 @@ const TableInner = ({
389
414
  onClick: onClickForRow,
390
415
  onScrollEnd: onScrollEnd,
391
416
  isLoading: isLoading,
392
- children: [emptyList || _jsx(_Fragment, {}), footer || _jsx(_Fragment, {})]
417
+ children: [emptyList || _jsx(_Fragment, {}), footer || _jsx(_Fragment, {}), isEndOfList ? _jsx(DataGridEndOfList, {
418
+ children: _jsx(LazyLoadingEnd, {})
419
+ }) : _jsx(_Fragment, {})]
393
420
  })
394
421
  }), detailPanel !== null && detailPanel !== void 0 ? detailPanel : null]
395
422
  })]
@@ -9,6 +9,7 @@ export interface ITabElement {
9
9
  id: string;
10
10
  quantity?: number;
11
11
  dataAnalyticsId?: string;
12
+ ariaControls?: string | null;
12
13
  }
13
14
  export interface ITabs extends IZenComponentProps {
14
15
  tabs: ITabElement[];
package/esm/tabs/tabs.js CHANGED
@@ -133,6 +133,27 @@ export const Tabs = ({
133
133
  const scrollRef = useRef(0);
134
134
  const focusableTabIdRef = useRef("");
135
135
  const userInitiatedTabChangeRef = useRef(false);
136
+ const scrollTabIntoView = useCallback(tabId => {
137
+ var _a, _b;
138
+ const scrollableElement = scrollableRef.current;
139
+ if (!scrollableElement) {
140
+ return;
141
+ }
142
+ if (tabId === ((_a = tabs[0]) === null || _a === void 0 ? void 0 : _a.id)) {
143
+ scrollableElement.scrollLeft = 0;
144
+ } else if (tabId === ((_b = tabs[tabs.length - 1]) === null || _b === void 0 ? void 0 : _b.id)) {
145
+ scrollableElement.scrollLeft = isRTL ? scrollableElement.clientWidth - scrollableElement.scrollWidth : scrollableElement.scrollWidth - scrollableElement.clientWidth;
146
+ } else {
147
+ const tab = scrollableElement.querySelector(`.zen-tab-item[id='${tabId}']`);
148
+ if (tab instanceof HTMLElement) {
149
+ tab.scrollIntoView({
150
+ block: "nearest",
151
+ inline: "nearest"
152
+ });
153
+ }
154
+ }
155
+ setScrollButtonType(getScrollButtonType(scrollableElement, isRTL));
156
+ }, [isRTL, tabs]);
136
157
  const handleButtonClick = e => {
137
158
  if (disabled) {
138
159
  return;
@@ -167,14 +188,23 @@ export const Tabs = ({
167
188
  const nextTabId = tabsKeyboardTabHandler(e, tabs, (_a = zen === null || zen === void 0 ? void 0 : zen.document) === null || _a === void 0 ? void 0 : _a.activeElement);
168
189
  if (nextTabId) {
169
190
  focusableTabIdRef.current = nextTabId;
191
+ scrollTabIntoView(nextTabId);
170
192
  }
171
193
  return;
172
194
  }
173
- const newActiveTabId = tabsKeyboardHandler(e, tabs, focusableTabIdRef.current) || activeTabId;
195
+ const newActiveTabId = tabsKeyboardHandler(e, tabs, focusableTabIdRef.current, isRTL);
196
+ if (!newActiveTabId) {
197
+ return;
198
+ }
174
199
  focusableTabIdRef.current = newActiveTabId;
175
200
  const focusableTab = (_b = scrollableRef.current) === null || _b === void 0 ? void 0 : _b.querySelector(`.zen-tab-item[id='${newActiveTabId}']`);
176
- focusableTab === null || focusableTab === void 0 ? void 0 : focusableTab.focus();
177
- }, [tabs, activeTabId, onTabChange, disabled]);
201
+ if (focusableTab instanceof HTMLElement) {
202
+ focusableTab.focus({
203
+ preventScroll: true
204
+ });
205
+ scrollTabIntoView(newActiveTabId);
206
+ }
207
+ }, [tabs, onTabChange, disabled, isRTL, scrollTabIntoView]);
178
208
  useEffect(() => {
179
209
  var _a;
180
210
  if (!scrollableRef.current) {
@@ -268,20 +298,23 @@ export const Tabs = ({
268
298
  children: _jsx("div", {
269
299
  className: "zen-tabs__tabs",
270
300
  role: "tablist",
271
- children: tabs.map(tab => _jsx(TabItem, {
272
- className: "zen-tabs__tab-item",
273
- tabId: tab.id,
274
- tabName: tab.name,
275
- icon: typeof tab.icon === "function" ? createElement(tab.icon, {
276
- size: "large"
277
- }) : tab.icon,
278
- quantity: tab.quantity,
279
- active: activeTabId === tab.id,
280
- ariaControl: `panel-${tab.id}`,
281
- handleButtonClick: handleButtonClick,
282
- dataAnalyticsId: tab.dataAnalyticsId,
283
- disabled: disabled
284
- }, tab.id))
301
+ children: tabs.map(tab => {
302
+ var _a;
303
+ return _jsx(TabItem, {
304
+ className: "zen-tabs__tab-item",
305
+ tabId: tab.id,
306
+ tabName: tab.name,
307
+ icon: typeof tab.icon === "function" ? createElement(tab.icon, {
308
+ size: "large"
309
+ }) : tab.icon,
310
+ quantity: tab.quantity,
311
+ active: activeTabId === tab.id,
312
+ ariaControl: tab.ariaControls === undefined ? `panel-${tab.id}` : (_a = tab.ariaControls) !== null && _a !== void 0 ? _a : undefined,
313
+ handleButtonClick: handleButtonClick,
314
+ dataAnalyticsId: tab.dataAnalyticsId,
315
+ disabled: disabled
316
+ }, tab.id);
317
+ })
285
318
  })
286
319
  }), scrollButtonType === "end" || scrollButtonType === "both" ? _jsxs(_Fragment, {
287
320
  children: [_jsx("div", {
@@ -4,6 +4,7 @@ import { useDriveClassName } from "../utils/theme/useDriveClassName";
4
4
  import { ReviewTextControl } from "../formGroup/components/reviewTextControl";
5
5
  import { useFormFieldValues } from "../commonHelpers/hooks/useFormFieldValues/useFormFieldValues";
6
6
  import { useMobileClassName } from "../utils/theme/useMobileClassName";
7
+ import { getAriaAttributes } from "../commonHelpers/getAriaAttributes";
7
8
  export const TextInputRaw = (props) => {
8
9
  const driveComponentClass = useDriveClassName("zen-text-input");
9
10
  const mobileComponentClass = useMobileClassName("zen-text-input");
@@ -11,13 +12,13 @@ export const TextInputRaw = (props) => {
11
12
  if (props.isReadOnly) {
12
13
  return _jsx(ReviewTextControl, { value: value, password: props.type === "password" });
13
14
  }
14
- return (_jsx("input", { id: props.id, ref: props.ref, type: props.type || "text", className: classNames([
15
+ return (_jsx("input", Object.assign({ id: props.id, ref: props.ref, type: props.type || "text", className: classNames([
15
16
  "zen-text-input",
16
17
  mobileComponentClass || driveComponentClass || "",
17
18
  props.className || "",
18
19
  props.isError ? "zen-text-input--error" : ""
19
20
  ]), value: maxLength ? value.substring(0, maxLength) : value, placeholder: props.placeholder, disabled: disabled, onChange: onChange, onKeyDown: props.onKeyDown, onBlur: onBlur, maxLength: maxLength, autoComplete: props.autocomplete,
20
21
  // TODO: add tests
21
- min: min, max: max, step: props.step, "aria-labelledby": props.ariaLabelledby, "aria-label": props.ariaLabel, autoFocus: props.autoFocus, required: !!required, onFocus: props.onFocus, minLength: minLength, name: name, pattern: pattern, role: props.role, "aria-expanded": props.ariaExpanded === undefined ? undefined : props.ariaExpanded === "true" || props.ariaExpanded === true, "aria-haspopup": props.ariaHaspopup, "aria-controls": props.ariaControls, "aria-autocomplete": props.ariaAutocomplete, "aria-describedby": props.ariaDescribedby }));
22
+ min: min, max: max, step: props.step, autoFocus: props.autoFocus, required: !!required, onFocus: props.onFocus, minLength: minLength, name: name, pattern: pattern, role: props.role }, getAriaAttributes(props), { "aria-expanded": props.ariaExpanded === undefined ? undefined : props.ariaExpanded === "true" || props.ariaExpanded === true })));
22
23
  };
23
24
  TextInputRaw.displayName = "TextInputRaw";
@@ -8,6 +8,8 @@ export type TMobileView = "default" | "mobileSheet";
8
8
  interface ITooltip extends IZenComponentProps {
9
9
  trigger?: ReactElement<PropsWithChildren & {
10
10
  onClick?: (e: React.MouseEvent) => void;
11
+ disabled?: boolean;
12
+ focusableWhenDisabled?: boolean;
11
13
  }>;
12
14
  alignment?: TAlignment;
13
15
  triggerClassName?: string;
@@ -115,13 +115,17 @@ const EventWrapper = ({
115
115
  deviceType,
116
116
  onKeyDownHandler,
117
117
  handleUniversalClick,
118
+ isTriggerDisabledFocusable,
118
119
  setTooltipVisible,
119
120
  timerRef,
120
121
  timerMouseLeaveRef,
121
122
  tooltipRef
122
123
  }) => {
123
124
  const isCurrentDeviceDesktop = deviceType === DeviceType.Desktop;
124
- const originalOnClick = children.props.onClick;
125
+ const triggerProps = children.props;
126
+ const originalOnClick = triggerProps.onClick;
127
+ // A disabled-focusable trigger's own `onClick` is a no-op guard, so `composedOnClick` never runs on
128
+ // mobile — see the `onClickCapture` handling in `mobileEvents` below.
125
129
  const composedOnClick = useCallback(e => {
126
130
  // Call original onClick first if it exists
127
131
  if (originalOnClick) {
@@ -158,10 +162,13 @@ const EventWrapper = ({
158
162
  handleUniversalClick(undefined);
159
163
  }
160
164
  }, [handleUniversalClick]);
161
- const mobileEvents = {
162
- onClick: composedOnClick,
165
+ const mobileEvents = Object.assign({
163
166
  onKeyDown: mobileOnKeyDown
164
- };
167
+ }, isTriggerDisabledFocusable ? {
168
+ onClickCapture: handleUniversalClick
169
+ } : {
170
+ onClick: composedOnClick
171
+ });
165
172
  const propsToApply = isCurrentDeviceDesktop ? desktopEvents : mobileEvents;
166
173
  return React.cloneElement(children, propsToApply);
167
174
  };
@@ -191,6 +198,8 @@ export const Tooltip = ({
191
198
  const [isTooltipVisible, setTooltipVisible] = useState(false);
192
199
  const [deviceType, setDeviceType] = useState(getInitialDeviceType);
193
200
  const isMobile = deviceType === DeviceType.Mobile;
201
+ const triggerProps = trigger === null || trigger === void 0 ? void 0 : trigger.props;
202
+ const isTriggerDisabledFocusable = Boolean(triggerProps === null || triggerProps === void 0 ? void 0 : triggerProps.disabled) && (triggerProps === null || triggerProps === void 0 ? void 0 : triggerProps.focusableWhenDisabled) !== false;
194
203
  const tooltipId = useId();
195
204
  const {
196
205
  translate
@@ -221,7 +230,7 @@ export const Tooltip = ({
221
230
  }
222
231
  };
223
232
  const handleUniversalClick = useCallback(e => {
224
- const hasExternalClickHandler = !!(trigger === null || trigger === void 0 ? void 0 : trigger.props.onClick);
233
+ const hasExternalClickHandler = !!(triggerProps === null || triggerProps === void 0 ? void 0 : triggerProps.onClick) && !isTriggerDisabledFocusable;
225
234
  if (deviceType === DeviceType.Desktop) {
226
235
  setTooltipVisible(currentVisible => {
227
236
  if (currentVisible) {
@@ -230,12 +239,14 @@ export const Tooltip = ({
230
239
  return currentVisible;
231
240
  });
232
241
  } else {
233
- e === null || e === void 0 ? void 0 : e.stopPropagation();
242
+ if (!isTriggerDisabledFocusable) {
243
+ e === null || e === void 0 ? void 0 : e.stopPropagation();
244
+ }
234
245
  if (!hasExternalClickHandler) {
235
246
  setTooltipVisible(isVisible => !isVisible);
236
247
  }
237
248
  }
238
- }, [trigger === null || trigger === void 0 ? void 0 : trigger.props, deviceType]);
249
+ }, [deviceType, isTriggerDisabledFocusable, triggerProps]);
239
250
  // Apply `triggerAriaLabel` to a `Tooltip.InlineTrigger` trigger (it has no `ariaLabel` prop
240
251
  // of its own); the default info-icon trigger below handles `triggerAriaLabel` separately.
241
252
  // An `aria-label` set directly on the `Tooltip.InlineTrigger` element takes priority over
@@ -262,6 +273,7 @@ export const Tooltip = ({
262
273
  isTooltipVisible: isTooltipVisible,
263
274
  onKeyDownHandler: onKeyDownHandler,
264
275
  handleUniversalClick: handleUniversalClick,
276
+ isTriggerDisabledFocusable: isTriggerDisabledFocusable,
265
277
  setTooltipVisible: setTooltipVisible,
266
278
  timerRef: timerRef,
267
279
  timerMouseLeaveRef: timerMouseLeaveRef,
@@ -129,6 +129,7 @@
129
129
  "GroupManuallyClassifiedPowertrainId": "محرك مصنف يدوياً",
130
130
  "GroupFuelCellElectricVehicleId": "مركبة كهربائية بخلايا الوقود",
131
131
  "and {0} more": "و {0} إضافي",
132
+ "+{0} more": "+{0} أخرى",
132
133
  "Clear selection": "مسح التحديد",
133
134
  "Select current page": "تحديد الصفحة الحالية",
134
135
  "OperatorOr": "معامل أو",
@@ -129,6 +129,7 @@
129
129
  "GroupManuallyClassifiedPowertrainId": "Ръчно класифицирана задвижваща система",
130
130
  "GroupFuelCellElectricVehicleId": "Електрическо превозно средство с горивни клетки",
131
131
  "and {0} more": "и {0} повече",
132
+ "+{0} more": "+ още {0}",
132
133
  "Clear selection": "Изчистване на избора",
133
134
  "Select current page": "Избиране на текущата страница",
134
135
  "OperatorOr": "ИЛИ",
@@ -115,6 +115,7 @@
115
115
  "GroupFuelCellElectricVehicleId": "Elektromobil s palivovým článkem",
116
116
  "{1} selected": "{1} vybraný/vybrané",
117
117
  "and {0} more": "a {0} dalších",
118
+ "+{0} more": "+{0} další",
118
119
  "Clear selection": "Vymazat výběr",
119
120
  "Select current page": "Vybrat aktuální stránku",
120
121
  "OperatorOr": "NEBO",
@@ -125,6 +125,7 @@
125
125
  "GroupManuallyClassifiedPowertrainId": "Manuelt klassificeret drivlinje",
126
126
  "GroupFuelCellElectricVehicleId": "Brændselscelle elektrisk køretøj",
127
127
  "and {0} more": "og {0} mere",
128
+ "+{0} more": "+{0} mere",
128
129
  "Clear selection": "Ryd markering",
129
130
  "Select current page": "Vælg aktuel side",
130
131
  "OperatorOr": "ELLER",
@@ -115,6 +115,7 @@
115
115
  "GroupFuelCellElectricVehicleId": "Brennstoffzellenfahrzeug",
116
116
  "{1} selected": "{1} ausgewählt",
117
117
  "and {0} more": "und {0} weitere",
118
+ "+{0} more": "+{0} weitere",
118
119
  "Select current page": "Aktuelle Seite auswählen",
119
120
  "OperatorOr": "ODER",
120
121
  "OperatorAnd": "UND",
@@ -129,6 +129,7 @@
129
129
  "GroupManuallyClassifiedPowertrainId": "Χειροκίνητα ταξινομημένο σύστημα κίνησης",
130
130
  "GroupFuelCellElectricVehicleId": "Ηλεκτρικό όχημα κυψελών καυσίμου",
131
131
  "and {0} more": "και {0} ακόμη",
132
+ "+{0} more": "+{0} ακόμα",
132
133
  "Clear selection": "Εκκαθάριση επιλογής",
133
134
  "Select current page": "Επιλογή τρέχουσας σελίδας",
134
135
  "OperatorOr": "Ή",
@@ -87,6 +87,7 @@
87
87
  "Previous page": "Previous page",
88
88
  "Next page": "Next page",
89
89
  "Showing {from} - {to} of {total}": "Showing {from} - {to} of {total}",
90
+ "{from}-{to} of {total}": "{from}-{to} of {total}",
90
91
  "Selected:": "Selected:",
91
92
  "All": "All",
92
93
  "Go to My Reports": "Go to My Reports",
@@ -129,6 +130,7 @@
129
130
  "GroupManuallyClassifiedPowertrainId": "Manually Classified Powertrain",
130
131
  "GroupFuelCellElectricVehicleId": "Fuel Cell Electric Vehicle",
131
132
  "and {0} more": "and {0} more",
133
+ "+{0} more": "+{0} more",
132
134
  "Clear selection": "Clear selection",
133
135
  "Select current page": "Select current page",
134
136
  "OperatorOr": "OR",
@@ -348,6 +350,8 @@
348
350
  "Loading more rows": "Loading more rows",
349
351
  "1 more row loaded": "1 more row loaded",
350
352
  "{count} more rows loaded": "{count} more rows loaded",
353
+ "No further results found": "No further results found",
354
+ "We couldn't find any more data matching your current selection. Try broadening your search.": "We couldn't find any more data matching your current selection. Try broadening your search.",
351
355
  "Line chart": "Line chart",
352
356
  "Bar chart": "Bar chart",
353
357
  "Pie chart": "Pie chart",
@@ -115,6 +115,7 @@
115
115
  "GroupFuelCellElectricVehicleId": "Vehículo eléctrico con celdas de combustible",
116
116
  "{1} selected": "Seleccionados: {1}",
117
117
  "and {0} more": "y {0} más",
118
+ "+{0} more": "+{0} más",
118
119
  "Clear selection": "Borrar selección",
119
120
  "Select current page": "Seleccionar página actual",
120
121
  "OperatorOr": "O",
@@ -129,6 +129,7 @@
129
129
  "GroupManuallyClassifiedPowertrainId": "Käsitsi klassifitseeritud jõuülekanne",
130
130
  "GroupFuelCellElectricVehicleId": "Kütuseelementidega elektrisõiduk",
131
131
  "and {0} more": "ja {0} veel",
132
+ "+{0} more": "+{0} veel",
132
133
  "Clear selection": "Tühjenda valik",
133
134
  "Select current page": "Vali praegune leht",
134
135
  "OperatorOr": "VÕI",
@@ -125,6 +125,7 @@
125
125
  "GroupManuallyClassifiedPowertrainId": "Manuaalisesti luokiteltu voimansiirto",
126
126
  "GroupFuelCellElectricVehicleId": "Polttokenno­sähköajoneuvo",
127
127
  "and {0} more": "ja {0} lisää",
128
+ "+{0} more": "+{0} lisää",
128
129
  "Clear selection": "Tyhjennä valinta",
129
130
  "Select current page": "Valitse nykyinen sivu",
130
131
  "OperatorOr": "TAI",
@@ -115,6 +115,7 @@
115
115
  "GroupFuelCellElectricVehicleId": "Véhicule électrique à pile combustible",
116
116
  "{1} selected": "{1} sélectionné(s)",
117
117
  "and {0} more": "et {0} de plus",
118
+ "+{0} more": "+{0} autres",
118
119
  "Clear selection": "Effacer la sélection",
119
120
  "Select current page": "Sélectionner toute la page",
120
121
  "OperatorOr": "OU",
@@ -115,6 +115,7 @@
115
115
  "GroupFuelCellElectricVehicleId": "Véhicule électrique à pile à combustible",
116
116
  "{1} selected": "{1} sélectionné(s)",
117
117
  "and {0} more": "et {0} de plus",
118
+ "+{0} more": "+{0} autres",
118
119
  "Clear selection": "Effacer la sélection",
119
120
  "Select current page": "Sélectionner la page actuelle",
120
121
  "OperatorOr": "OU",
@@ -125,6 +125,7 @@
125
125
  "GroupManuallyClassifiedPowertrainId": "Kézi besorolású hajtáslánc",
126
126
  "GroupFuelCellElectricVehicleId": "Üzemanyagcellás elektromos jármű",
127
127
  "and {0} more": "és még {0}",
128
+ "+{0} more": "+{0} több",
128
129
  "Clear selection": "Töröld a kijelölést.",
129
130
  "Select current page": "Válaszd ki az aktuális oldalt.",
130
131
  "OperatorOr": "VAGY",
@@ -115,6 +115,7 @@
115
115
  "GroupFuelCellElectricVehicleId": "Kendaraan Listrik Sel Bahan Bakar",
116
116
  "{1} selected": "{1} dipilih",
117
117
  "and {0} more": "dan {0} lainnya",
118
+ "+{0} more": "+{0} lebih",
118
119
  "Clear selection": "Hapus pilihan",
119
120
  "Select current page": "Pilih halaman saat ini",
120
121
  "OperatorOr": "ATAU",
@@ -115,6 +115,7 @@
115
115
  "GroupFuelCellElectricVehicleId": "Veicolo elettrico a celle a combustibile",
116
116
  "{1} selected": "Elementi selezionati: {1}",
117
117
  "and {0} more": "e altri {0}",
118
+ "+{0} more": "+{0} in più",
118
119
  "Clear selection": "Cancellare selezione",
119
120
  "Select current page": "Selezionare pagina corrente",
120
121
  "OperatorOr": "O",
@@ -115,6 +115,7 @@
115
115
  "GroupFuelCellElectricVehicleId": "燃料電池電気自動車",
116
116
  "{1} selected": "{1} つ選択",
117
117
  "and {0} more": "{0} 以上",
118
+ "+{0} more": "さらに {0} 個",
118
119
  "Clear selection": "選択をクリアします",
119
120
  "Select current page": "現在のページを選択",
120
121
  "OperatorOr": "または",
@@ -129,6 +129,7 @@
129
129
  "GroupManuallyClassifiedPowertrainId": "ხელით კლასიფიცირებული ძრავის სისტემა",
130
130
  "GroupFuelCellElectricVehicleId": "საწვავის ელემენტის ელექტრო მანქანა",
131
131
  "and {0} more": "და კიდევ {0}",
132
+ "+{0} more": "+{0} მეტი",
132
133
  "Clear selection": "მონიშვნის გასუფთავება",
133
134
  "Select current page": "მიმდინარე გვერდის არჩევა",
134
135
  "OperatorOr": "ან",
@@ -125,6 +125,7 @@
125
125
  "GroupManuallyClassifiedPowertrainId": "수동 분류 파워트레인",
126
126
  "GroupFuelCellElectricVehicleId": "연료 전지 전기 자동차",
127
127
  "and {0} more": "및 {0}개 더",
128
+ "+{0} more": "+{0} 더보기",
128
129
  "Clear selection": "선택 지우기",
129
130
  "Select current page": "현재 페이지 선택",
130
131
  "OperatorOr": "OperatorOr",
@@ -129,6 +129,7 @@
129
129
  "GroupManuallyClassifiedPowertrainId": "Rankiniu būdu klasifikuota pavara",
130
130
  "GroupFuelCellElectricVehicleId": "Kuro elementų elektrinis automobilis",
131
131
  "and {0} more": "ir dar {0}",
132
+ "+{0} more": "+{0} daugiau",
132
133
  "Clear selection": "Išvalyti pasirinkimą",
133
134
  "Select current page": "Pasirinkti dabartinį puslapį",
134
135
  "OperatorOr": "ARBA",
@@ -129,6 +129,7 @@
129
129
  "GroupManuallyClassifiedPowertrainId": "Manuāli klasificēta piedziņas sistēma",
130
130
  "GroupFuelCellElectricVehicleId": "Degvielas elementu elektriskais transportlīdzeklis",
131
131
  "and {0} more": "un vēl {0}",
132
+ "+{0} more": "+{0} vēl",
132
133
  "Clear selection": "Notīrīt atlasi",
133
134
  "Select current page": "Atlasīt pašreizējo lapu",
134
135
  "OperatorOr": "VAI",
@@ -115,6 +115,7 @@
115
115
  "{1} selected": "{1} dipilih",
116
116
  "GroupElectricHybridPluginId": "Pasang Masuk Elektrik atau Hibrid",
117
117
  "and {0} more": "dan {0} lagi",
118
+ "+{0} more": "+{0} lagi",
118
119
  "Clear selection": "Kosongkan pilihan",
119
120
  "Select current page": "Pilih halaman semasa",
120
121
  "OperatorOr": "ATAU",
@@ -125,6 +125,7 @@
125
125
  "GroupManuallyClassifiedPowertrainId": "Manuelt klassifisert drivlinje",
126
126
  "GroupFuelCellElectricVehicleId": "Brenselcelle-elektrisk kjøretøy",
127
127
  "and {0} more": "og {0} flere",
128
+ "+{0} more": "+{0} mer",
128
129
  "Clear selection": "Fjern utvalg",
129
130
  "Select current page": "Velg nåværende side",
130
131
  "OperatorOr": "ELLER",
@@ -115,6 +115,7 @@
115
115
  "GroupFuelCellElectricVehicleId": "Elektrisch voertuig met brandstofcel",
116
116
  "{1} selected": "{1} geselecteerd",
117
117
  "and {0} more": "en {0} meer",
118
+ "+{0} more": "+{0} meer",
118
119
  "Clear selection": "Selectie wissen",
119
120
  "Select current page": "Huidige pagina selecteren",
120
121
  "OperatorOr": "OF",
@@ -115,6 +115,7 @@
115
115
  "GroupFuelCellElectricVehicleId": "Elektryczny pojazd z ogniwem paliwowym",
116
116
  "{1} selected": "Wybrano {1}",
117
117
  "and {0} more": "i jeszcze {0}",
118
+ "+{0} more": "Jeszcze {0}",
118
119
  "Clear selection": "Wyczyść wybór",
119
120
  "Select current page": "Wybierz bieżącą stronę",
120
121
  "OperatorOr": "LUB",
@@ -115,6 +115,7 @@
115
115
  "GroupFuelCellElectricVehicleId": "Veículo elétrico com célula de combustível",
116
116
  "{1} selected": "{1} selecionado(s)",
117
117
  "and {0} more": "e {0} mais",
118
+ "+{0} more": "+{0} mais",
118
119
  "Clear selection": "Limpar seleção",
119
120
  "Select current page": "Selecionar página atual",
120
121
  "OperatorOr": "OU",