@internetarchive/collection-browser 4.7.1-alpha-webdev9189.0 → 4.8.1-webdev-9227.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 (396) hide show
  1. package/README.md +33 -0
  2. package/dist/src/app-root.js +0 -2
  3. package/dist/src/app-root.js.map +1 -1
  4. package/dist/src/assets/img/icons/check.d.ts +2 -0
  5. package/dist/src/assets/img/icons/check.js +5 -0
  6. package/dist/src/assets/img/icons/check.js.map +1 -0
  7. package/dist/src/collection-browser.d.ts +2 -1
  8. package/dist/src/collection-browser.js +5 -27
  9. package/dist/src/collection-browser.js.map +1 -1
  10. package/dist/src/collection-facets/facet-row-template.d.ts +38 -0
  11. package/dist/src/collection-facets/facet-row-template.js +200 -0
  12. package/dist/src/collection-facets/facet-row-template.js.map +1 -0
  13. package/dist/src/collection-facets/facet-row.js +11 -186
  14. package/dist/src/collection-facets/facet-row.js.map +1 -1
  15. package/dist/src/collection-facets/models.d.ts +7 -2
  16. package/dist/src/collection-facets/models.js +7 -2
  17. package/dist/src/collection-facets/models.js.map +1 -1
  18. package/dist/src/collection-facets/more-facets-content.d.ts +87 -21
  19. package/dist/src/collection-facets/more-facets-content.js +479 -201
  20. package/dist/src/collection-facets/more-facets-content.js.map +1 -1
  21. package/dist/src/collection-facets/more-facets-scroller.d.ts +85 -0
  22. package/dist/src/collection-facets/more-facets-scroller.js +429 -0
  23. package/dist/src/collection-facets/more-facets-scroller.js.map +1 -0
  24. package/dist/src/collection-facets/page-window.d.ts +73 -0
  25. package/dist/src/collection-facets/page-window.js +202 -0
  26. package/dist/src/collection-facets/page-window.js.map +1 -0
  27. package/dist/src/collection-facets/toggle-switch.js +1 -0
  28. package/dist/src/collection-facets/toggle-switch.js.map +1 -1
  29. package/dist/src/collection-facets.js +3 -2
  30. package/dist/src/collection-facets.js.map +1 -1
  31. package/dist/src/empty-placeholder.d.ts +7 -7
  32. package/dist/src/empty-placeholder.js +29 -15
  33. package/dist/src/empty-placeholder.js.map +1 -1
  34. package/dist/src/expanded-date-picker.js +3 -2
  35. package/dist/src/expanded-date-picker.js.map +1 -1
  36. package/dist/src/locales/es.d.ts +94 -0
  37. package/dist/src/locales/es.js +109 -0
  38. package/dist/src/locales/es.js.map +1 -0
  39. package/dist/src/manage/manage-bar.d.ts +3 -2
  40. package/dist/src/manage/manage-bar.js +6 -7
  41. package/dist/src/manage/manage-bar.js.map +1 -1
  42. package/dist/src/manage/remove-items-modal-content.js +3 -2
  43. package/dist/src/manage/remove-items-modal-content.js.map +1 -1
  44. package/dist/src/models.d.ts +4 -0
  45. package/dist/src/models.js +22 -2
  46. package/dist/src/models.js.map +1 -1
  47. package/dist/src/sort-filter-bar/sort-filter-bar.js +3 -3
  48. package/dist/src/sort-filter-bar/sort-filter-bar.js.map +1 -1
  49. package/dist/src/tiles/grid/account-tile.js +3 -2
  50. package/dist/src/tiles/grid/account-tile.js.map +1 -1
  51. package/dist/src/tiles/grid/collection-tile.js +3 -2
  52. package/dist/src/tiles/grid/collection-tile.js.map +1 -1
  53. package/dist/src/tiles/grid/item-tile.js +3 -2
  54. package/dist/src/tiles/grid/item-tile.js.map +1 -1
  55. package/dist/src/tiles/grid/tile-stats.js +3 -2
  56. package/dist/src/tiles/grid/tile-stats.js.map +1 -1
  57. package/dist/src/tiles/list/tile-list-compact-header.js +3 -2
  58. package/dist/src/tiles/list/tile-list-compact-header.js.map +1 -1
  59. package/dist/src/tiles/list/tile-list-compact.js +3 -1
  60. package/dist/src/tiles/list/tile-list-compact.js.map +1 -1
  61. package/dist/src/tiles/list/tile-list.js +3 -2
  62. package/dist/src/tiles/list/tile-list.js.map +1 -1
  63. package/dist/src/tiles/overlay/text-overlay.js +3 -1
  64. package/dist/src/tiles/overlay/text-overlay.js.map +1 -1
  65. package/dist/src/tiles/review-block.js +3 -2
  66. package/dist/src/tiles/review-block.js.map +1 -1
  67. package/dist/src/tiles/tile-dispatcher.d.ts +2 -1
  68. package/dist/src/tiles/tile-dispatcher.js +5 -4
  69. package/dist/src/tiles/tile-dispatcher.js.map +1 -1
  70. package/dist/src/utils/log.d.ts +1 -4
  71. package/dist/src/utils/normalize-filter-text.d.ts +28 -0
  72. package/dist/src/utils/normalize-filter-text.js +35 -0
  73. package/dist/src/utils/normalize-filter-text.js.map +1 -0
  74. package/locales/es.d.ts +1 -0
  75. package/locales/es.js +1 -0
  76. package/package.json +15 -1
  77. package/.editorconfig +0 -29
  78. package/.github/workflows/ci.yml +0 -29
  79. package/.github/workflows/gh-pages-main.yml +0 -41
  80. package/.github/workflows/npm-publish.yml +0 -42
  81. package/.github/workflows/pr-preview.yml +0 -40
  82. package/.husky/pre-commit +0 -1
  83. package/.prettierignore +0 -1
  84. package/dist/src/collection-facets/more-facets-pagination.d.ts +0 -36
  85. package/dist/src/collection-facets/more-facets-pagination.js +0 -260
  86. package/dist/src/collection-facets/more-facets-pagination.js.map +0 -1
  87. package/dist/test/collection-browser.test.d.ts +0 -1
  88. package/dist/test/collection-browser.test.js +0 -1849
  89. package/dist/test/collection-browser.test.js.map +0 -1
  90. package/dist/test/collection-facets/facet-row.test.d.ts +0 -1
  91. package/dist/test/collection-facets/facet-row.test.js +0 -291
  92. package/dist/test/collection-facets/facet-row.test.js.map +0 -1
  93. package/dist/test/collection-facets/facets-template.test.d.ts +0 -1
  94. package/dist/test/collection-facets/facets-template.test.js +0 -95
  95. package/dist/test/collection-facets/facets-template.test.js.map +0 -1
  96. package/dist/test/collection-facets/more-facets-content.test.d.ts +0 -1
  97. package/dist/test/collection-facets/more-facets-content.test.js +0 -159
  98. package/dist/test/collection-facets/more-facets-content.test.js.map +0 -1
  99. package/dist/test/collection-facets/more-facets-pagination.test.d.ts +0 -1
  100. package/dist/test/collection-facets/more-facets-pagination.test.js +0 -126
  101. package/dist/test/collection-facets/more-facets-pagination.test.js.map +0 -1
  102. package/dist/test/collection-facets/toggle-switch.test.d.ts +0 -1
  103. package/dist/test/collection-facets/toggle-switch.test.js +0 -99
  104. package/dist/test/collection-facets/toggle-switch.test.js.map +0 -1
  105. package/dist/test/collection-facets.test.d.ts +0 -2
  106. package/dist/test/collection-facets.test.js +0 -728
  107. package/dist/test/collection-facets.test.js.map +0 -1
  108. package/dist/test/data-source/collection-browser-data-source.test.d.ts +0 -1
  109. package/dist/test/data-source/collection-browser-data-source.test.js +0 -154
  110. package/dist/test/data-source/collection-browser-data-source.test.js.map +0 -1
  111. package/dist/test/empty-placeholder.test.d.ts +0 -1
  112. package/dist/test/empty-placeholder.test.js +0 -57
  113. package/dist/test/empty-placeholder.test.js.map +0 -1
  114. package/dist/test/expanded-date-picker.test.d.ts +0 -1
  115. package/dist/test/expanded-date-picker.test.js +0 -124
  116. package/dist/test/expanded-date-picker.test.js.map +0 -1
  117. package/dist/test/icon-overlay.test.d.ts +0 -1
  118. package/dist/test/icon-overlay.test.js +0 -31
  119. package/dist/test/icon-overlay.test.js.map +0 -1
  120. package/dist/test/image-block.test.d.ts +0 -1
  121. package/dist/test/image-block.test.js +0 -208
  122. package/dist/test/image-block.test.js.map +0 -1
  123. package/dist/test/item-image.test.d.ts +0 -1
  124. package/dist/test/item-image.test.js +0 -187
  125. package/dist/test/item-image.test.js.map +0 -1
  126. package/dist/test/manage/manage-bar.test.d.ts +0 -3
  127. package/dist/test/manage/manage-bar.test.js +0 -216
  128. package/dist/test/manage/manage-bar.test.js.map +0 -1
  129. package/dist/test/manage/remove-items-modal-content.test.d.ts +0 -1
  130. package/dist/test/manage/remove-items-modal-content.test.js +0 -60
  131. package/dist/test/manage/remove-items-modal-content.test.js.map +0 -1
  132. package/dist/test/mediatype-config.test.d.ts +0 -1
  133. package/dist/test/mediatype-config.test.js +0 -11
  134. package/dist/test/mediatype-config.test.js.map +0 -1
  135. package/dist/test/mocks/mock-analytics-handler.d.ts +0 -10
  136. package/dist/test/mocks/mock-analytics-handler.js +0 -16
  137. package/dist/test/mocks/mock-analytics-handler.js.map +0 -1
  138. package/dist/test/mocks/mock-search-responses.d.ts +0 -31
  139. package/dist/test/mocks/mock-search-responses.js +0 -1241
  140. package/dist/test/mocks/mock-search-responses.js.map +0 -1
  141. package/dist/test/mocks/mock-search-service.d.ts +0 -16
  142. package/dist/test/mocks/mock-search-service.js +0 -64
  143. package/dist/test/mocks/mock-search-service.js.map +0 -1
  144. package/dist/test/restoration-state-handler.test.d.ts +0 -1
  145. package/dist/test/restoration-state-handler.test.js +0 -335
  146. package/dist/test/restoration-state-handler.test.js.map +0 -1
  147. package/dist/test/review-block.test.d.ts +0 -1
  148. package/dist/test/review-block.test.js +0 -46
  149. package/dist/test/review-block.test.js.map +0 -1
  150. package/dist/test/sort-filter-bar/alpha-bar-tooltip.test.d.ts +0 -1
  151. package/dist/test/sort-filter-bar/alpha-bar-tooltip.test.js +0 -12
  152. package/dist/test/sort-filter-bar/alpha-bar-tooltip.test.js.map +0 -1
  153. package/dist/test/sort-filter-bar/alpha-bar.test.d.ts +0 -1
  154. package/dist/test/sort-filter-bar/alpha-bar.test.js +0 -68
  155. package/dist/test/sort-filter-bar/alpha-bar.test.js.map +0 -1
  156. package/dist/test/sort-filter-bar/sort-filter-bar.test.d.ts +0 -1
  157. package/dist/test/sort-filter-bar/sort-filter-bar.test.js +0 -326
  158. package/dist/test/sort-filter-bar/sort-filter-bar.test.js.map +0 -1
  159. package/dist/test/text-overlay.test.d.ts +0 -1
  160. package/dist/test/text-overlay.test.js +0 -43
  161. package/dist/test/text-overlay.test.js.map +0 -1
  162. package/dist/test/text-snippet-block.test.d.ts +0 -1
  163. package/dist/test/text-snippet-block.test.js +0 -58
  164. package/dist/test/text-snippet-block.test.js.map +0 -1
  165. package/dist/test/tile-stats.test.d.ts +0 -1
  166. package/dist/test/tile-stats.test.js +0 -167
  167. package/dist/test/tile-stats.test.js.map +0 -1
  168. package/dist/test/tiles/grid/account-tile.test.d.ts +0 -1
  169. package/dist/test/tiles/grid/account-tile.test.js +0 -96
  170. package/dist/test/tiles/grid/account-tile.test.js.map +0 -1
  171. package/dist/test/tiles/grid/collection-tile.test.d.ts +0 -1
  172. package/dist/test/tiles/grid/collection-tile.test.js +0 -90
  173. package/dist/test/tiles/grid/collection-tile.test.js.map +0 -1
  174. package/dist/test/tiles/grid/item-tile.test.d.ts +0 -1
  175. package/dist/test/tiles/grid/item-tile.test.js +0 -400
  176. package/dist/test/tiles/grid/item-tile.test.js.map +0 -1
  177. package/dist/test/tiles/grid/search-tile.test.d.ts +0 -1
  178. package/dist/test/tiles/grid/search-tile.test.js +0 -62
  179. package/dist/test/tiles/grid/search-tile.test.js.map +0 -1
  180. package/dist/test/tiles/hover/hover-pane-controller.test.d.ts +0 -1
  181. package/dist/test/tiles/hover/hover-pane-controller.test.js +0 -351
  182. package/dist/test/tiles/hover/hover-pane-controller.test.js.map +0 -1
  183. package/dist/test/tiles/hover/tile-hover-pane.test.d.ts +0 -1
  184. package/dist/test/tiles/hover/tile-hover-pane.test.js +0 -53
  185. package/dist/test/tiles/hover/tile-hover-pane.test.js.map +0 -1
  186. package/dist/test/tiles/list/tile-list-compact-header.test.d.ts +0 -1
  187. package/dist/test/tiles/list/tile-list-compact-header.test.js +0 -36
  188. package/dist/test/tiles/list/tile-list-compact-header.test.js.map +0 -1
  189. package/dist/test/tiles/list/tile-list-compact.test.d.ts +0 -1
  190. package/dist/test/tiles/list/tile-list-compact.test.js +0 -237
  191. package/dist/test/tiles/list/tile-list-compact.test.js.map +0 -1
  192. package/dist/test/tiles/list/tile-list.test.d.ts +0 -1
  193. package/dist/test/tiles/list/tile-list.test.js +0 -460
  194. package/dist/test/tiles/list/tile-list.test.js.map +0 -1
  195. package/dist/test/tiles/tile-dispatcher.test.d.ts +0 -1
  196. package/dist/test/tiles/tile-dispatcher.test.js +0 -246
  197. package/dist/test/tiles/tile-dispatcher.test.js.map +0 -1
  198. package/dist/test/tiles/tile-display-value-provider.test.d.ts +0 -1
  199. package/dist/test/tiles/tile-display-value-provider.test.js +0 -142
  200. package/dist/test/tiles/tile-display-value-provider.test.js.map +0 -1
  201. package/dist/test/tiles/tile-mediatype-icon.test.d.ts +0 -1
  202. package/dist/test/tiles/tile-mediatype-icon.test.js +0 -133
  203. package/dist/test/tiles/tile-mediatype-icon.test.js.map +0 -1
  204. package/dist/test/utils/array-equals.test.d.ts +0 -1
  205. package/dist/test/utils/array-equals.test.js +0 -27
  206. package/dist/test/utils/array-equals.test.js.map +0 -1
  207. package/dist/test/utils/format-count.test.d.ts +0 -1
  208. package/dist/test/utils/format-count.test.js +0 -24
  209. package/dist/test/utils/format-count.test.js.map +0 -1
  210. package/dist/test/utils/format-date.test.d.ts +0 -1
  211. package/dist/test/utils/format-date.test.js +0 -61
  212. package/dist/test/utils/format-date.test.js.map +0 -1
  213. package/dist/test/utils/format-unit-size.test.d.ts +0 -1
  214. package/dist/test/utils/format-unit-size.test.js +0 -18
  215. package/dist/test/utils/format-unit-size.test.js.map +0 -1
  216. package/dist/test/utils/local-date-from-utc.test.d.ts +0 -1
  217. package/dist/test/utils/local-date-from-utc.test.js +0 -27
  218. package/dist/test/utils/local-date-from-utc.test.js.map +0 -1
  219. package/eslint.config.mjs +0 -53
  220. package/index.html +0 -24
  221. package/index.ts +0 -29
  222. package/local.archive.org.cert +0 -86
  223. package/local.archive.org.key +0 -27
  224. package/pnpm-workspace.yaml +0 -30
  225. package/renovate.json +0 -6
  226. package/src/app-root.ts +0 -1284
  227. package/src/assets/img/icons/arrow-left.ts +0 -10
  228. package/src/assets/img/icons/arrow-right.ts +0 -10
  229. package/src/assets/img/icons/chevron.ts +0 -4
  230. package/src/assets/img/icons/close-circle-dark.ts +0 -5
  231. package/src/assets/img/icons/contract.ts +0 -9
  232. package/src/assets/img/icons/empty-query.ts +0 -5
  233. package/src/assets/img/icons/expand.ts +0 -9
  234. package/src/assets/img/icons/eye-closed.ts +0 -5
  235. package/src/assets/img/icons/eye.ts +0 -5
  236. package/src/assets/img/icons/favorite-filled.ts +0 -10
  237. package/src/assets/img/icons/favorite-unfilled.ts +0 -9
  238. package/src/assets/img/icons/filter.ts +0 -10
  239. package/src/assets/img/icons/login-required.ts +0 -18
  240. package/src/assets/img/icons/mediatype/account.ts +0 -14
  241. package/src/assets/img/icons/mediatype/audio.ts +0 -14
  242. package/src/assets/img/icons/mediatype/collection.ts +0 -12
  243. package/src/assets/img/icons/mediatype/data.ts +0 -15
  244. package/src/assets/img/icons/mediatype/etree.ts +0 -14
  245. package/src/assets/img/icons/mediatype/film.ts +0 -14
  246. package/src/assets/img/icons/mediatype/images.ts +0 -13
  247. package/src/assets/img/icons/mediatype/radio.ts +0 -15
  248. package/src/assets/img/icons/mediatype/search.ts +0 -14
  249. package/src/assets/img/icons/mediatype/software.ts +0 -13
  250. package/src/assets/img/icons/mediatype/texts.ts +0 -13
  251. package/src/assets/img/icons/mediatype/tv-commercial.ts +0 -12
  252. package/src/assets/img/icons/mediatype/tv-fact-check.ts +0 -12
  253. package/src/assets/img/icons/mediatype/tv-quote.ts +0 -12
  254. package/src/assets/img/icons/mediatype/tv.ts +0 -14
  255. package/src/assets/img/icons/mediatype/video.ts +0 -14
  256. package/src/assets/img/icons/mediatype/web.ts +0 -13
  257. package/src/assets/img/icons/null-result.ts +0 -5
  258. package/src/assets/img/icons/quote.ts +0 -7
  259. package/src/assets/img/icons/restricted.ts +0 -13
  260. package/src/assets/img/icons/reviews.ts +0 -11
  261. package/src/assets/img/icons/upload.ts +0 -12
  262. package/src/assets/img/icons/views.ts +0 -11
  263. package/src/circular-activity-indicator.ts +0 -64
  264. package/src/collection-browser.ts +0 -3187
  265. package/src/collection-facets/facet-row.ts +0 -309
  266. package/src/collection-facets/facet-tombstone-row.ts +0 -40
  267. package/src/collection-facets/facets-template.ts +0 -85
  268. package/src/collection-facets/models.ts +0 -10
  269. package/src/collection-facets/more-facets-content.ts +0 -644
  270. package/src/collection-facets/more-facets-pagination.ts +0 -294
  271. package/src/collection-facets/smart-facets/dedupe.ts +0 -44
  272. package/src/collection-facets/smart-facets/heuristics/browser-language/browser-language-heuristic.ts +0 -27
  273. package/src/collection-facets/smart-facets/heuristics/index.ts +0 -3
  274. package/src/collection-facets/smart-facets/heuristics/query-keywords/query-keywords-heuristic.ts +0 -17
  275. package/src/collection-facets/smart-facets/heuristics/query-keywords/query-keywords-map.ts +0 -70
  276. package/src/collection-facets/smart-facets/heuristics/wikidata/wikidata-entity-map.ts +0 -79
  277. package/src/collection-facets/smart-facets/heuristics/wikidata/wikidata-heuristic.ts +0 -93
  278. package/src/collection-facets/smart-facets/models.ts +0 -36
  279. package/src/collection-facets/smart-facets/smart-facet-bar.ts +0 -437
  280. package/src/collection-facets/smart-facets/smart-facet-button.ts +0 -145
  281. package/src/collection-facets/smart-facets/smart-facet-dropdown.ts +0 -185
  282. package/src/collection-facets/smart-facets/smart-facet-equals.ts +0 -16
  283. package/src/collection-facets/smart-facets/smart-facet-heuristics.ts +0 -26
  284. package/src/collection-facets/toggle-switch.ts +0 -174
  285. package/src/collection-facets.ts +0 -1013
  286. package/src/data-source/collection-browser-data-source-interface.ts +0 -351
  287. package/src/data-source/collection-browser-data-source.ts +0 -1474
  288. package/src/data-source/collection-browser-query-state.ts +0 -60
  289. package/src/data-source/models.ts +0 -56
  290. package/src/empty-placeholder.ts +0 -192
  291. package/src/expanded-date-picker.ts +0 -191
  292. package/src/language-code-handler/language-code-handler.ts +0 -64
  293. package/src/language-code-handler/language-code-mapping.ts +0 -564
  294. package/src/manage/manage-bar.ts +0 -276
  295. package/src/manage/remove-items-modal-content.ts +0 -102
  296. package/src/mediatype/mediatype-config.ts +0 -146
  297. package/src/models.ts +0 -895
  298. package/src/restoration-state-handler.ts +0 -550
  299. package/src/sort-filter-bar/alpha-bar-tooltip.ts +0 -53
  300. package/src/sort-filter-bar/alpha-bar.ts +0 -252
  301. package/src/sort-filter-bar/img/compact.ts +0 -5
  302. package/src/sort-filter-bar/img/list.ts +0 -5
  303. package/src/sort-filter-bar/img/sort-toggle-disabled.ts +0 -15
  304. package/src/sort-filter-bar/img/sort-toggle-down.ts +0 -17
  305. package/src/sort-filter-bar/img/sort-toggle-up.ts +0 -17
  306. package/src/sort-filter-bar/img/sort-triangle.ts +0 -5
  307. package/src/sort-filter-bar/img/tile.ts +0 -5
  308. package/src/sort-filter-bar/sort-filter-bar.ts +0 -734
  309. package/src/styles/ia-button.ts +0 -139
  310. package/src/styles/item-image-styles.ts +0 -124
  311. package/src/styles/sr-only.ts +0 -18
  312. package/src/styles/tile-action-styles.ts +0 -59
  313. package/src/tiles/base-tile-component.ts +0 -124
  314. package/src/tiles/collection-browser-loading-tile.ts +0 -26
  315. package/src/tiles/grid/account-tile.ts +0 -113
  316. package/src/tiles/grid/collection-tile.ts +0 -184
  317. package/src/tiles/grid/item-tile.ts +0 -347
  318. package/src/tiles/grid/search-tile.ts +0 -90
  319. package/src/tiles/grid/styles/tile-grid-shared-styles.ts +0 -130
  320. package/src/tiles/grid/tile-stats.ts +0 -211
  321. package/src/tiles/hover/hover-pane-controller.ts +0 -638
  322. package/src/tiles/hover/tile-hover-pane.ts +0 -184
  323. package/src/tiles/image-block.ts +0 -162
  324. package/src/tiles/item-image.ts +0 -214
  325. package/src/tiles/list/tile-list-compact-header.ts +0 -112
  326. package/src/tiles/list/tile-list-compact.ts +0 -278
  327. package/src/tiles/list/tile-list.ts +0 -718
  328. package/src/tiles/models.ts +0 -21
  329. package/src/tiles/overlay/icon-overlay.ts +0 -57
  330. package/src/tiles/overlay/text-overlay.ts +0 -79
  331. package/src/tiles/review-block.ts +0 -130
  332. package/src/tiles/text-snippet-block.ts +0 -132
  333. package/src/tiles/tile-dispatcher.ts +0 -637
  334. package/src/tiles/tile-display-value-provider.ts +0 -133
  335. package/src/tiles/tile-mediatype-icon.ts +0 -133
  336. package/src/utils/analytics-events.ts +0 -29
  337. package/src/utils/array-equals.ts +0 -8
  338. package/src/utils/collapse-repeated-quotes.ts +0 -13
  339. package/src/utils/date-filter-field.ts +0 -11
  340. package/src/utils/facet-utils.ts +0 -183
  341. package/src/utils/format-count.ts +0 -95
  342. package/src/utils/format-date.ts +0 -62
  343. package/src/utils/format-unit-size.ts +0 -43
  344. package/src/utils/local-date-from-utc.ts +0 -15
  345. package/src/utils/log.ts +0 -14
  346. package/src/utils/resolve-mediatype.ts +0 -26
  347. package/src/utils/sha1.ts +0 -9
  348. package/test/collection-browser.test.ts +0 -2694
  349. package/test/collection-facets/facet-row.test.ts +0 -421
  350. package/test/collection-facets/facets-template.test.ts +0 -139
  351. package/test/collection-facets/more-facets-content.test.ts +0 -231
  352. package/test/collection-facets/more-facets-pagination.test.ts +0 -201
  353. package/test/collection-facets/toggle-switch.test.ts +0 -164
  354. package/test/collection-facets.test.ts +0 -928
  355. package/test/data-source/collection-browser-data-source.test.ts +0 -193
  356. package/test/empty-placeholder.test.ts +0 -88
  357. package/test/expanded-date-picker.test.ts +0 -201
  358. package/test/icon-overlay.test.ts +0 -38
  359. package/test/image-block.test.ts +0 -247
  360. package/test/item-image.test.ts +0 -220
  361. package/test/manage/manage-bar.test.ts +0 -347
  362. package/test/manage/remove-items-modal-content.test.ts +0 -81
  363. package/test/mediatype-config.test.ts +0 -11
  364. package/test/mocks/mock-analytics-handler.ts +0 -30
  365. package/test/mocks/mock-search-responses.ts +0 -1364
  366. package/test/mocks/mock-search-service.ts +0 -134
  367. package/test/restoration-state-handler.test.ts +0 -480
  368. package/test/review-block.test.ts +0 -62
  369. package/test/sort-filter-bar/alpha-bar-tooltip.test.ts +0 -17
  370. package/test/sort-filter-bar/alpha-bar.test.ts +0 -101
  371. package/test/sort-filter-bar/sort-filter-bar.test.ts +0 -472
  372. package/test/text-overlay.test.ts +0 -55
  373. package/test/text-snippet-block.test.ts +0 -85
  374. package/test/tile-stats.test.ts +0 -191
  375. package/test/tiles/grid/account-tile.test.ts +0 -121
  376. package/test/tiles/grid/collection-tile.test.ts +0 -114
  377. package/test/tiles/grid/item-tile.test.ts +0 -520
  378. package/test/tiles/grid/search-tile.test.ts +0 -75
  379. package/test/tiles/hover/hover-pane-controller.test.ts +0 -482
  380. package/test/tiles/hover/tile-hover-pane.test.ts +0 -80
  381. package/test/tiles/list/tile-list-compact-header.test.ts +0 -43
  382. package/test/tiles/list/tile-list-compact.test.ts +0 -282
  383. package/test/tiles/list/tile-list.test.ts +0 -576
  384. package/test/tiles/tile-dispatcher.test.ts +0 -320
  385. package/test/tiles/tile-display-value-provider.test.ts +0 -172
  386. package/test/tiles/tile-mediatype-icon.test.ts +0 -160
  387. package/test/utils/array-equals.test.ts +0 -31
  388. package/test/utils/format-count.test.ts +0 -32
  389. package/test/utils/format-date.test.ts +0 -89
  390. package/test/utils/format-unit-size.test.ts +0 -21
  391. package/test/utils/local-date-from-utc.test.ts +0 -37
  392. package/tsconfig.json +0 -25
  393. package/types/dompurify.d.ts +0 -1
  394. package/vite.config.ts +0 -29
  395. package/web-dev-server.config.mjs +0 -30
  396. package/web-test-runner.config.mjs +0 -52
@@ -1,133 +0,0 @@
1
- import { TemplateResult, html, nothing } from 'lit';
2
- import { msg, str } from '@lit/localize';
3
- import type { SortParam } from '@internetarchive/search-service';
4
- import type { TileModel } from '../models';
5
- import { formatDate } from '../utils/format-date';
6
-
7
- /**
8
- * A class encapsulating shared logic for converting model values into display values
9
- * across different types of tiles.
10
- */
11
- export class TileDisplayValueProvider {
12
- private model?: TileModel;
13
-
14
- private baseNavigationUrl?: string;
15
-
16
- private collectionPagePath?: string;
17
-
18
- private sortParam?: SortParam;
19
-
20
- private creatorFilter?: string;
21
-
22
- constructor(
23
- options: {
24
- model?: TileModel;
25
- baseNavigationUrl?: string;
26
- collectionPagePath?: string;
27
- sortParam?: SortParam;
28
- creatorFilter?: string;
29
- } = {},
30
- ) {
31
- this.model = options.model;
32
- this.baseNavigationUrl = options.baseNavigationUrl;
33
- this.collectionPagePath = options.collectionPagePath ?? '/details/';
34
- this.sortParam = options.sortParam;
35
- this.creatorFilter = options.creatorFilter;
36
- }
37
-
38
- /**
39
- * Examines the creator(s) for the given tile model, returning
40
- * the first creator whose name matches the provided filter
41
- * (or simply the first creator overall if no filter is provided).
42
- */
43
- get firstCreatorMatchingFilter(): string | undefined {
44
- let matchingCreator;
45
-
46
- // If we're filtering by creator initial and have multiple creators, we want
47
- // to surface the first creator who matches the filter.
48
- if (this.creatorFilter && this.model?.creators.length) {
49
- const firstLetter = this.creatorFilter; // This is just to satisfy tsc
50
- matchingCreator = this.model.creators.find(creator =>
51
- // Decompose combining characters first, so that e.g., filtering on E matches É too.
52
- // Then remove anything that isn't strictly alphabetic, since our filters currently
53
- // only handle A-Z. The first such letter (if one exists) is what needs to match.
54
- creator
55
- .normalize('NFD')
56
- .replace(/[^A-Z]+/gi, '')
57
- .toUpperCase()
58
- .startsWith(firstLetter),
59
- );
60
- }
61
-
62
- return matchingCreator ?? this.model?.creator;
63
- }
64
-
65
- /**
66
- * The label indicating what year an account item was created.
67
- * E.g., "Archivist since 2015"
68
- */
69
- get accountLabel(): string {
70
- return this.model?.dateAdded
71
- ? msg(str`Archivist since ${this.model.dateAdded.getFullYear()}`)
72
- : '';
73
- }
74
-
75
- /**
76
- * The readable label for the current sort if it is a type of date sort,
77
- * or the empty string otherwise.
78
- */
79
- get dateLabel(): string {
80
- switch (this.sortParam?.field) {
81
- case 'publicdate':
82
- return msg('Archived');
83
- case 'reviewdate':
84
- return msg('Reviewed');
85
- case 'addeddate':
86
- return msg('Added');
87
- case 'date':
88
- return msg('Published');
89
- default:
90
- return '';
91
- }
92
- }
93
-
94
- /**
95
- * The readable label for the current views column, based on whether
96
- * weekly or all-time views are being shown.
97
- */
98
- get viewsLabel(): string {
99
- return this.sortParam?.field === 'week'
100
- ? msg('Weekly views')
101
- : msg('All-time views');
102
- }
103
-
104
- /**
105
- * Produces a URL pointing at the item page for the given identifier,
106
- * using the current base URL and the correct path based on whether the
107
- * item is specified to be a collection (default false).
108
- */
109
- itemPageUrl(
110
- identifier?: string,
111
- isCollection = false,
112
- ): string | typeof nothing {
113
- if (!identifier || this.baseNavigationUrl == null) return nothing;
114
- const basePath = isCollection ? this.collectionPagePath : '/details/';
115
- return `${this.baseNavigationUrl}${basePath}${identifier}`;
116
- }
117
-
118
- /**
119
- * Produces a template for a link to a single web capture of the given URL and date
120
- */
121
- webArchivesCaptureLink(url: string, date: Date): TemplateResult {
122
- // Convert the date into the format used to identify wayback captures (e.g., '20150102124550')
123
- const captureDateStr = date
124
- .toISOString()
125
- .replace(/[TZ:-]/g, '')
126
- .replace(/\..*/, '');
127
- // url must not be percent-encoded — Wayback Machine matches on the raw URL
128
- const captureHref = `https://web.archive.org/web/${captureDateStr}/${url}`;
129
- const captureText = formatDate(date, 'long');
130
-
131
- return html` <a href=${captureHref}> ${captureText} </a> `;
132
- }
133
- }
@@ -1,133 +0,0 @@
1
- import { css, CSSResultGroup, html, LitElement } from 'lit';
2
- import { customElement, property } from 'lit/decorators.js';
3
-
4
- import {
5
- mediatypeConfig,
6
- MediatypeConfigKey,
7
- } from '../mediatype/mediatype-config';
8
- import type { TileModel } from '../models';
9
-
10
- const TV_COMMERCIAL_COLLECTION = 'tv_ads';
11
- const TV_FACT_CHECK_COLLECTION = 'factchecked';
12
- const TV_COLLECTIONS = new Set(['tvnews', 'tvarchive', 'television']);
13
- const RADIO_COLLECTIONS = new Set(['radio', 'radioprogram']);
14
-
15
- @customElement('tile-mediatype-icon')
16
- export class TileMediatypeIcon extends LitElement {
17
- @property({ type: Object }) model?: TileModel;
18
-
19
- @property({ type: Boolean }) showText = false;
20
-
21
- /**
22
- * Returns the appropriate mediatype config key for the current mediatype/collections.
23
- */
24
- private get displayMediatype(): MediatypeConfigKey {
25
- if (this.isTvItem) return this.tvDisplayMediatype;
26
- if (this.isRadioItem) return 'radio';
27
- return this.model?.mediatype ?? 'none';
28
- }
29
-
30
- /**
31
- * Returns the appropriate TV mediatype, depending on the current collections.
32
- */
33
- private get tvDisplayMediatype(): MediatypeConfigKey {
34
- if (this.isTvCommercial) {
35
- return 'tvCommercial';
36
- } else if (this.model?.isTvSearchResult && this.isTvFactCheck) {
37
- return 'tvFactCheck';
38
- } else if (this.model?.isTvSearchResult && this.isTvQuote) {
39
- return 'tvQuote';
40
- }
41
-
42
- return 'tv';
43
- }
44
-
45
- /**
46
- * Whether this represents a TV item
47
- */
48
- private get isTvItem(): boolean {
49
- return !!(
50
- this.model?.mediatype === 'movies' &&
51
- this.model?.collections.some(id => TV_COLLECTIONS.has(id))
52
- );
53
- }
54
-
55
- private get isTvCommercial(): boolean {
56
- // Contains one or more TV ad identifiers or is in the tv_ads collection
57
- return !!(
58
- this.model?.adIds?.length ||
59
- this.model?.collections.includes(TV_COMMERCIAL_COLLECTION)
60
- );
61
- }
62
-
63
- private get isTvFactCheck(): boolean {
64
- // Contains one or more fact-check URLs or is in the factchecked collection
65
- return !!(
66
- this.model?.factChecks?.length ||
67
- this.model?.collections.includes(TV_FACT_CHECK_COLLECTION)
68
- );
69
- }
70
-
71
- private get isTvQuote(): boolean {
72
- return !!this.model?.isClip;
73
- }
74
-
75
- /**
76
- * Whether this represents a radio item
77
- */
78
- private get isRadioItem(): boolean {
79
- return !!(
80
- this.model?.mediatype === 'audio' &&
81
- this.model?.collections.some(id => RADIO_COLLECTIONS.has(id))
82
- );
83
- }
84
-
85
- render() {
86
- const config = mediatypeConfig[this.displayMediatype];
87
- if (!config) {
88
- return html``;
89
- }
90
-
91
- return html`
92
- <div
93
- id="icon"
94
- class="${this.showText ? 'show-text' : 'hide-text'}"
95
- title="${config.text}"
96
- style="--iconFillColor: ${config.color}"
97
- >
98
- ${config.icon}
99
- <p class="status-text">${config.text}</p>
100
- </div>
101
- `;
102
- }
103
-
104
- static get styles(): CSSResultGroup {
105
- return css`
106
- #icon {
107
- height: var(--iconHeight, 25px);
108
- }
109
-
110
- .status-text {
111
- font-size: 14px;
112
- color: #2c2c2c;
113
- margin: auto;
114
- display: block;
115
- text-align: var(--iconTextAlign, center);
116
- }
117
-
118
- #icon.hide-text p {
119
- display: none;
120
- }
121
-
122
- svg {
123
- height: var(--iconHeight, 10px);
124
- width: var(--iconWidth, 10px);
125
- pointer-events: none;
126
- }
127
-
128
- .fill-color {
129
- fill: var(--iconFillColor, '#000000');
130
- }
131
- `;
132
- }
133
- }
@@ -1,29 +0,0 @@
1
- /**
2
- * Analytics categories and events. Used when building actions in
3
- */
4
- export enum analyticsCategories {
5
- default = 'collection-browser',
6
- }
7
-
8
- export enum analyticsActions {
9
- sortBy = 'sortBy',
10
- filterByCreator = 'filterByCreator',
11
- filterByTitle = 'filterByTitle',
12
- displayMode = 'displayMode',
13
- loadDesktopView = 'loadDesktopView',
14
- loadMobileView = 'loadMobileView',
15
- facetSelected = 'facetSelected',
16
- facetDeselected = 'facetDeselected',
17
- facetNegativeSelected = 'facetNegativeSelected',
18
- facetNegativeDeselected = 'facetNegativeDeselected',
19
- mobileFacetsToggled = 'mobileFacetsToggled',
20
- partOfCollectionClicked = 'partOfCollectionClicked',
21
- histogramChanged = 'histogramChanged',
22
- histogramChangedFromModal = 'histogramChangedFromModal',
23
- histogramExpanded = 'histogramExpanded',
24
- resultSelected = 'resultSelected',
25
- moreFacetsPageChange = 'moreFacetsPageChange',
26
- showMoreFacetsModal = 'showMoreFacetsModal',
27
- closeMoreFacetsModal = 'closeMoreFacetsModal',
28
- applyMoreFacetsModal = 'applyMoreFacetsModal',
29
- }
@@ -1,8 +0,0 @@
1
- /**
2
- * Determines whether two arrays have the same (shallow) contents in the same order
3
- */
4
- export function arrayEquals(arr1: unknown[], arr2: unknown[]): boolean {
5
- if (arr1 === arr2) return true;
6
- if (arr1.length !== arr2.length) return false;
7
- return arr1.every((val, i) => val === arr2[i]);
8
- }
@@ -1,13 +0,0 @@
1
- /**
2
- * Returns the input string, but removing one set of quotes from all instances of
3
- * ""clauses wrapped in two sets of quotes"". This assumes the quotes are already
4
- * URL-encoded.
5
- *
6
- * This should be a temporary measure to address the fact that the __href__ field
7
- * sometimes acquires extra quotation marks during query rewriting. Once there is a
8
- * full Lucene parser in place that handles quoted queries correctly, this can likely
9
- * be removed.
10
- */
11
- export function collapseRepeatedQuotes(str?: string): string | undefined {
12
- return str?.replace(/%22%22(?!%22%22)(.+?)%22%22/g, '%22$1%22');
13
- }
@@ -1,11 +0,0 @@
1
- /**
2
- * Determines the appropriate search filter field name based on date format.
3
- * Dates in YYYY-MM format (containing a hyphen) use the `date` field;
4
- * dates in YYYY format use the `year` field.
5
- */
6
- export function dateFilterField(
7
- minDate?: string,
8
- maxDate?: string,
9
- ): 'date' | 'year' {
10
- return minDate?.includes('-') || maxDate?.includes('-') ? 'date' : 'year';
11
- }
@@ -1,183 +0,0 @@
1
- import { AggregationSortType } from '@internetarchive/search-service';
2
- import {
3
- FacetOption,
4
- getDefaultSelectedFacets,
5
- type FacetBucket,
6
- type SelectedFacets,
7
- } from '../models';
8
-
9
- // This file contains several helper functions designed to make working immutably
10
- // with SelectedFacet objects and FacetGroups cleaner & easier.
11
-
12
- /**
13
- * Calls the given function for each FacetBucket specified in the given SelectedFacets
14
- * object. The function is always called with the facet type, bucket key, bucket object,
15
- * and the given SelectedFacets object.
16
- *
17
- * @param selectedFacets The SelectedFacets object whose buckets should be iterated over
18
- * @param fn The function to apply to each facet bucket.
19
- *
20
- * @example
21
- * forEachFacetBucket(
22
- * myFacets,
23
- * (facetType, bucketKey, bucket) => {
24
- * if (facetType === 'collection' && bucket.state === 'hidden') {
25
- * console.log(`Excluding any results in the ${bucketKey} collection`);
26
- * }
27
- * }
28
- * );
29
- */
30
- export function forEachFacetBucket(
31
- selectedFacets: SelectedFacets | undefined,
32
- fn: (
33
- facetType: FacetOption,
34
- bucketKey: string,
35
- bucket: FacetBucket,
36
- selectedFacets: SelectedFacets,
37
- ) => unknown,
38
- ): void {
39
- if (!selectedFacets) return;
40
- for (const [facetType, facetBuckets] of Object.entries(selectedFacets)) {
41
- for (const [bucketKey, bucket] of Object.entries(facetBuckets)) {
42
- fn(facetType as FacetOption, bucketKey, bucket, selectedFacets);
43
- }
44
- }
45
- }
46
-
47
- /**
48
- * Returns a new SelectedFacets object having only the specified bucket changed to
49
- * reflect its new provided value. The bucket key is determined from the provided
50
- * `bucket` itself.
51
- * @param selectedFacets The SelectedFacets object to produce an updated clone of
52
- * @param facetType The type of facet to be modified (e.g., 'mediatype', 'subject', ...)
53
- * @param bucket The new bucket that should be present on the result
54
- * @param omitNoneState If set to true, the returned object will omit the given
55
- * bucket entirely if it is updated to state `'none'`. Default is false, which leaves
56
- * the `'none'` state in place.
57
- */
58
- export function updateSelectedFacetBucket(
59
- selectedFacets: SelectedFacets | undefined,
60
- facetType: FacetOption,
61
- bucket: FacetBucket,
62
- omitNoneState = false,
63
- ): SelectedFacets {
64
- const defaultedSelectedFacets = selectedFacets ?? getDefaultSelectedFacets();
65
- const newFacets: SelectedFacets = {
66
- ...defaultedSelectedFacets,
67
- [facetType]: {
68
- ...defaultedSelectedFacets[facetType],
69
- [bucket.key]: bucket,
70
- },
71
- };
72
-
73
- if (omitNoneState && bucket.state === 'none') {
74
- delete newFacets[facetType]?.[bucket.key];
75
- }
76
-
77
- return newFacets;
78
- }
79
-
80
- /**
81
- * Creates a clone of the given SelectedFacets object.
82
- *
83
- * Note that the underlying FacetBucket objects are not deep-cloned -- they will
84
- * be references to the same objects as in the input. However, the objects
85
- * containing the FacetBuckets for each FacetOption are created anew.
86
- *
87
- * If the provided argument is undefined, returns an empty SelectedFacets object.
88
- *
89
- * @param selectedFacets The SelectedFacets object to be cloned
90
- */
91
- export function cloneSelectedFacets(
92
- selectedFacets: SelectedFacets | undefined,
93
- ): SelectedFacets {
94
- const cloneResult = getDefaultSelectedFacets();
95
- forEachFacetBucket(selectedFacets, (facetType, bucketKey, bucket) => {
96
- if (!cloneResult[facetType]) cloneResult[facetType] = {};
97
- cloneResult[facetType][bucketKey] = bucket;
98
- });
99
- return cloneResult;
100
- }
101
-
102
- /**
103
- * Creates a new SelectedFacets object representing a merge of the `source` facets object
104
- * into the `destination` facets object. Any facets existing in `source` take precedence
105
- * over those in `destination` in the event of conflicts.
106
- *
107
- * The resulting SelectedFacets object is normalized to omit any facet buckets whose
108
- * state is `'none'` in the merged result. Consequently, any facets buckets with state
109
- * `'none'` in `source` will always be absent from the end result. Likewise, any facet
110
- * buckets with state `'none'` in `destination` will be absent _unless_ they are also
111
- * present in `source` with a state of `'selected'` or `'hidden'` (in which case `source`
112
- * takes precedence as usual).
113
- *
114
- * @param source The source of the new facets to merge in. Any facet buckets existing in
115
- * this `source` object will take precedence over those in `destination` having the same
116
- * key, if they exist in both. Any facet buckets that are _not_ present in `source` will
117
- * remain unmodified from their state in `destination`, if they are present there at all.
118
- * @param destination The destination onto which facets should be merged. Note that this
119
- * object is _not_ re-used for the return value, but it is conceptually the "existing base"
120
- * onto which the source facets are merged.
121
- */
122
- export function mergeSelectedFacets(
123
- destination: SelectedFacets | undefined,
124
- source: SelectedFacets | undefined,
125
- ): SelectedFacets {
126
- const mergeResult = cloneSelectedFacets(destination);
127
- forEachFacetBucket(source, (facetType, bucketKey, bucket) => {
128
- if (!mergeResult[facetType]) mergeResult[facetType] = {};
129
- mergeResult[facetType][bucketKey] = bucket;
130
- });
131
-
132
- // Normalize any 'none' states on the result (from either source or destination)
133
- forEachFacetBucket(mergeResult, (facetType, bucketKey, bucket) => {
134
- if (bucket.state === 'none') {
135
- delete mergeResult[facetType]?.[bucketKey];
136
- }
137
- });
138
-
139
- return mergeResult;
140
- }
141
-
142
- /**
143
- * Defines the order of states in which to display SelectedFacets buckets
144
- */
145
- const BUCKET_STATE_ORDER = ['selected', 'hidden', 'none'];
146
-
147
- /**
148
- * Sorts the provided FacetBuckets so that:
149
- * - Any selected items come first
150
- * - Any hidden items come after all the selected items
151
- * - Any unselected / unhidden items come last
152
- *
153
- * Within each of the above groups, the buckets will be sorted according to
154
- * the provided sort type, or by their bucket count by default.
155
- *
156
- * The sort is performed in-place using `Array.sort`, so the return value is
157
- * a reference to the same array that was passed in, only sorted.
158
- *
159
- * @param buckets The array of facet buckets to sort
160
- * @param sort (Optional) How buckets within each state group should be sorted.
161
- * Defaults to `AggregationSortType.COUNT` (i.e., descending by bucket count).
162
- */
163
- export function sortBucketsBySelectionState(
164
- buckets: FacetBucket[],
165
- sort = AggregationSortType.COUNT,
166
- ) {
167
- return buckets.sort((a, b) => {
168
- const aStateIndex = BUCKET_STATE_ORDER.indexOf(a.state);
169
- const bStateIndex = BUCKET_STATE_ORDER.indexOf(b.state);
170
- const stateDiff = aStateIndex - bStateIndex; // Sort bucket states primarily in the order defined by BUCKET_STATE_ORDER
171
-
172
- let secondaryDiff;
173
- if (sort === AggregationSortType.ALPHABETICAL) {
174
- secondaryDiff = a.key.localeCompare(b.key); // Ascending alphabetically by bucket key
175
- } else if (sort === AggregationSortType.NUMERIC) {
176
- secondaryDiff = Number(b.key) - Number(a.key); // Descending numerically by bucket key
177
- } else {
178
- secondaryDiff = b.count - a.count; // Descending by bucket count
179
- }
180
-
181
- return stateDiff || secondaryDiff; // Primary sort on state, secondary sort on the given sort type (defaulting to descending count)
182
- });
183
- }
@@ -1,95 +0,0 @@
1
- /*
2
- * Replaces Petabox www/common/Util::number_format()
3
- * For positive numbers only.
4
- */
5
- import { msg, str } from '@lit/localize';
6
-
7
- export type NumberFormat =
8
- | 'short' // 1.2 [K | thousand]
9
- | 'long'; // 1,200 [No label for numbers < 1,000,000]
10
- export type LabelFormat =
11
- | 'short' // [1.2]K
12
- | 'long'; // [1.2] thousand
13
- type Divisor = 1_000_000_000 | 1_000_000 | 1_000 | 1;
14
-
15
- /**
16
- * Return the magnitude of a number.
17
- */
18
- function magnitude(number: number, numberFormat: NumberFormat): Divisor {
19
- let divisor: Divisor = 1;
20
- if (number >= 1_000_000_000) {
21
- divisor = 1_000_000_000;
22
- } else if (number >= 1_000_000) {
23
- divisor = 1_000_000;
24
- } else if (number >= 1_000 && numberFormat === 'short') {
25
- divisor = 1_000;
26
- }
27
- return divisor;
28
- }
29
-
30
- /**
31
- * Round a number given passed magnitude.
32
- * Significant digits of value less than 10 get a decimal.
33
- */
34
- function round(number: number = 0, divisor: Divisor): number {
35
- const result = number / divisor;
36
- const roundToOne = result < 10;
37
- let rounded: number = 0;
38
- if (roundToOne) {
39
- rounded = Math.round((result + Number.EPSILON) * 10) / 10;
40
- } else {
41
- rounded = Math.round(result);
42
- }
43
- return rounded;
44
- }
45
-
46
- /**
47
- * Return a label for a number and format.
48
- */
49
- function labelize(
50
- rounded: number,
51
- divisor: Divisor,
52
- format: LabelFormat,
53
- locale: string,
54
- ): string {
55
- switch (divisor) {
56
- case 1_000_000_000:
57
- if (format === 'short') {
58
- return msg(str`${rounded}B`);
59
- }
60
- return msg(str`${rounded} billion`);
61
- case 1_000_000:
62
- if (format === 'short') {
63
- return msg(str`${rounded}M`);
64
- }
65
- return msg(str`${rounded} million`);
66
- case 1_000:
67
- if (format === 'short') {
68
- return msg(str`${rounded}K`);
69
- }
70
- return msg(str`${rounded} thousand`);
71
-
72
- default:
73
- return new Intl.NumberFormat(locale).format(rounded);
74
- }
75
- }
76
-
77
- /**
78
- * Format a "count" number into short "icon" or longer text string.
79
- * For positive numbers only.
80
- */
81
- export function formatCount(
82
- count: number | undefined,
83
- numberFormat: NumberFormat = 'long',
84
- labelFormat: LabelFormat = 'short',
85
- locale: string = 'en-US',
86
- ): string {
87
- // Return blank if undefined
88
- const number = count ?? -1;
89
- if (number < 0) {
90
- return '';
91
- }
92
- const divisor = magnitude(number, numberFormat);
93
- const rounded = round(number, divisor);
94
- return labelize(rounded, divisor, labelFormat, locale);
95
- }
@@ -1,62 +0,0 @@
1
- /*
2
- * Display date
3
- * Override browser timezone to always display same date as in data
4
- */
5
- export type DateFormat =
6
- | 'year-only' // 2020
7
- | 'short' // Dec 2020
8
- | 'long'; // Dec 20, 2020
9
-
10
- /**
11
- * Extra options accepted by the `formatDate` function
12
- */
13
- export type FormatDateOptions = {
14
- /**
15
- * Which locale to format the date string for (default `'en-US'`)
16
- */
17
- locale?: string;
18
- /**
19
- * Whether to display the date in the browser's local time zone.
20
- * Default is `false`, displaying the dates in UTC.
21
- */
22
- useLocalTime?: boolean;
23
- };
24
-
25
- export function formatDate(
26
- date: Date | undefined,
27
- format: DateFormat = 'short',
28
- { locale = 'en-US', useLocalTime = false }: FormatDateOptions = {},
29
- ): string {
30
- // Return blank if undefined
31
- if (!date) return '';
32
-
33
- // The dates provided by the backend are assumed to already be with respect to UTC,
34
- // and by default we specify that they should be rendered as such. If the
35
- // `useLocalTime` option was set, we omit the UTC time zone from our format options
36
- // so that the browser's local time zone is used instead.
37
- const options: Intl.DateTimeFormatOptions = useLocalTime
38
- ? {}
39
- : { timeZone: 'UTC' };
40
-
41
- switch (format) {
42
- case 'year-only':
43
- // If we're only using the year, ensure we output the correct UTC year and not
44
- // the local year. If the local timezone is used, we can get strange off-by-one
45
- // errors due to quirks of timezone handling for older years.
46
- return `${date.getUTCFullYear()}`;
47
- case 'short':
48
- options.month = 'short';
49
- options.year = 'numeric';
50
- break;
51
- case 'long':
52
- options.year = 'numeric';
53
- options.month = 'short';
54
- options.day = '2-digit';
55
- break;
56
- default:
57
- break;
58
- }
59
-
60
- const dateFormatter = new Intl.DateTimeFormat(locale, options);
61
- return dateFormatter.format(date);
62
- }