@internetarchive/collection-browser 4.8.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.
- package/README.md +33 -0
- package/dist/src/collection-browser.d.ts +2 -1
- package/dist/src/collection-browser.js +3 -3
- package/dist/src/collection-browser.js.map +1 -1
- package/dist/src/collection-facets/more-facets-content.js +3 -2
- package/dist/src/collection-facets/more-facets-content.js.map +1 -1
- package/dist/src/collection-facets/more-facets-scroller.js +3 -2
- package/dist/src/collection-facets/more-facets-scroller.js.map +1 -1
- package/dist/src/collection-facets.js +3 -2
- package/dist/src/collection-facets.js.map +1 -1
- package/dist/src/empty-placeholder.d.ts +7 -7
- package/dist/src/empty-placeholder.js +29 -15
- package/dist/src/empty-placeholder.js.map +1 -1
- package/dist/src/expanded-date-picker.js +3 -2
- package/dist/src/expanded-date-picker.js.map +1 -1
- package/dist/src/locales/es.d.ts +94 -0
- package/dist/src/locales/es.js +109 -0
- package/dist/src/locales/es.js.map +1 -0
- package/dist/src/manage/manage-bar.d.ts +3 -2
- package/dist/src/manage/manage-bar.js +6 -7
- package/dist/src/manage/manage-bar.js.map +1 -1
- package/dist/src/manage/remove-items-modal-content.js +3 -2
- package/dist/src/manage/remove-items-modal-content.js.map +1 -1
- package/dist/src/models.js +6 -2
- package/dist/src/models.js.map +1 -1
- package/dist/src/sort-filter-bar/sort-filter-bar.js +3 -2
- package/dist/src/sort-filter-bar/sort-filter-bar.js.map +1 -1
- package/dist/src/tiles/grid/account-tile.js +3 -2
- package/dist/src/tiles/grid/account-tile.js.map +1 -1
- package/dist/src/tiles/grid/collection-tile.js +3 -2
- package/dist/src/tiles/grid/collection-tile.js.map +1 -1
- package/dist/src/tiles/grid/item-tile.js +3 -2
- package/dist/src/tiles/grid/item-tile.js.map +1 -1
- package/dist/src/tiles/grid/tile-stats.js +3 -2
- package/dist/src/tiles/grid/tile-stats.js.map +1 -1
- package/dist/src/tiles/list/tile-list-compact-header.js +3 -2
- package/dist/src/tiles/list/tile-list-compact-header.js.map +1 -1
- package/dist/src/tiles/list/tile-list-compact.js +3 -1
- package/dist/src/tiles/list/tile-list-compact.js.map +1 -1
- package/dist/src/tiles/list/tile-list.js +3 -2
- package/dist/src/tiles/list/tile-list.js.map +1 -1
- package/dist/src/tiles/overlay/text-overlay.js +3 -1
- package/dist/src/tiles/overlay/text-overlay.js.map +1 -1
- package/dist/src/tiles/review-block.js +3 -2
- package/dist/src/tiles/review-block.js.map +1 -1
- package/dist/src/tiles/tile-dispatcher.d.ts +2 -1
- package/dist/src/tiles/tile-dispatcher.js +5 -4
- package/dist/src/tiles/tile-dispatcher.js.map +1 -1
- package/locales/es.d.ts +1 -0
- package/locales/es.js +1 -0
- package/package.json +13 -1
- package/.editorconfig +0 -29
- package/.github/workflows/ci.yml +0 -29
- package/.github/workflows/gh-pages-main.yml +0 -41
- package/.github/workflows/npm-publish.yml +0 -42
- package/.github/workflows/pr-preview.yml +0 -40
- package/.husky/pre-commit +0 -1
- package/.prettierignore +0 -1
- package/dist/test/collection-browser.test.d.ts +0 -1
- package/dist/test/collection-browser.test.js +0 -1815
- package/dist/test/collection-browser.test.js.map +0 -1
- package/dist/test/collection-facets/facet-row.test.d.ts +0 -1
- package/dist/test/collection-facets/facet-row.test.js +0 -291
- package/dist/test/collection-facets/facet-row.test.js.map +0 -1
- package/dist/test/collection-facets/facets-template.test.d.ts +0 -1
- package/dist/test/collection-facets/facets-template.test.js +0 -95
- package/dist/test/collection-facets/facets-template.test.js.map +0 -1
- package/dist/test/collection-facets/more-facets-content.test.d.ts +0 -1
- package/dist/test/collection-facets/more-facets-content.test.js +0 -509
- package/dist/test/collection-facets/more-facets-content.test.js.map +0 -1
- package/dist/test/collection-facets/more-facets-scroller.test.d.ts +0 -1
- package/dist/test/collection-facets/more-facets-scroller.test.js +0 -288
- package/dist/test/collection-facets/more-facets-scroller.test.js.map +0 -1
- package/dist/test/collection-facets/page-window.test.d.ts +0 -1
- package/dist/test/collection-facets/page-window.test.js +0 -175
- package/dist/test/collection-facets/page-window.test.js.map +0 -1
- package/dist/test/collection-facets/toggle-switch.test.d.ts +0 -1
- package/dist/test/collection-facets/toggle-switch.test.js +0 -99
- package/dist/test/collection-facets/toggle-switch.test.js.map +0 -1
- package/dist/test/collection-facets.test.d.ts +0 -2
- package/dist/test/collection-facets.test.js +0 -728
- package/dist/test/collection-facets.test.js.map +0 -1
- package/dist/test/data-source/collection-browser-data-source.test.d.ts +0 -1
- package/dist/test/data-source/collection-browser-data-source.test.js +0 -154
- package/dist/test/data-source/collection-browser-data-source.test.js.map +0 -1
- package/dist/test/empty-placeholder.test.d.ts +0 -1
- package/dist/test/empty-placeholder.test.js +0 -57
- package/dist/test/empty-placeholder.test.js.map +0 -1
- package/dist/test/expanded-date-picker.test.d.ts +0 -1
- package/dist/test/expanded-date-picker.test.js +0 -124
- package/dist/test/expanded-date-picker.test.js.map +0 -1
- package/dist/test/icon-overlay.test.d.ts +0 -1
- package/dist/test/icon-overlay.test.js +0 -31
- package/dist/test/icon-overlay.test.js.map +0 -1
- package/dist/test/image-block.test.d.ts +0 -1
- package/dist/test/image-block.test.js +0 -208
- package/dist/test/image-block.test.js.map +0 -1
- package/dist/test/item-image.test.d.ts +0 -1
- package/dist/test/item-image.test.js +0 -187
- package/dist/test/item-image.test.js.map +0 -1
- package/dist/test/manage/manage-bar.test.d.ts +0 -3
- package/dist/test/manage/manage-bar.test.js +0 -216
- package/dist/test/manage/manage-bar.test.js.map +0 -1
- package/dist/test/manage/remove-items-modal-content.test.d.ts +0 -1
- package/dist/test/manage/remove-items-modal-content.test.js +0 -60
- package/dist/test/manage/remove-items-modal-content.test.js.map +0 -1
- package/dist/test/mediatype-config.test.d.ts +0 -1
- package/dist/test/mediatype-config.test.js +0 -11
- package/dist/test/mediatype-config.test.js.map +0 -1
- package/dist/test/mocks/mock-analytics-handler.d.ts +0 -10
- package/dist/test/mocks/mock-analytics-handler.js +0 -16
- package/dist/test/mocks/mock-analytics-handler.js.map +0 -1
- package/dist/test/mocks/mock-search-responses.d.ts +0 -37
- package/dist/test/mocks/mock-search-responses.js +0 -1293
- package/dist/test/mocks/mock-search-responses.js.map +0 -1
- package/dist/test/mocks/mock-search-service.d.ts +0 -16
- package/dist/test/mocks/mock-search-service.js +0 -65
- package/dist/test/mocks/mock-search-service.js.map +0 -1
- package/dist/test/restoration-state-handler.test.d.ts +0 -1
- package/dist/test/restoration-state-handler.test.js +0 -335
- package/dist/test/restoration-state-handler.test.js.map +0 -1
- package/dist/test/review-block.test.d.ts +0 -1
- package/dist/test/review-block.test.js +0 -46
- package/dist/test/review-block.test.js.map +0 -1
- package/dist/test/sort-filter-bar/alpha-bar-tooltip.test.d.ts +0 -1
- package/dist/test/sort-filter-bar/alpha-bar-tooltip.test.js +0 -12
- package/dist/test/sort-filter-bar/alpha-bar-tooltip.test.js.map +0 -1
- package/dist/test/sort-filter-bar/alpha-bar.test.d.ts +0 -1
- package/dist/test/sort-filter-bar/alpha-bar.test.js +0 -68
- package/dist/test/sort-filter-bar/alpha-bar.test.js.map +0 -1
- package/dist/test/sort-filter-bar/sort-filter-bar.test.d.ts +0 -1
- package/dist/test/sort-filter-bar/sort-filter-bar.test.js +0 -304
- package/dist/test/sort-filter-bar/sort-filter-bar.test.js.map +0 -1
- package/dist/test/text-overlay.test.d.ts +0 -1
- package/dist/test/text-overlay.test.js +0 -43
- package/dist/test/text-overlay.test.js.map +0 -1
- package/dist/test/text-snippet-block.test.d.ts +0 -1
- package/dist/test/text-snippet-block.test.js +0 -58
- package/dist/test/text-snippet-block.test.js.map +0 -1
- package/dist/test/tile-stats.test.d.ts +0 -1
- package/dist/test/tile-stats.test.js +0 -167
- package/dist/test/tile-stats.test.js.map +0 -1
- package/dist/test/tiles/grid/account-tile.test.d.ts +0 -1
- package/dist/test/tiles/grid/account-tile.test.js +0 -96
- package/dist/test/tiles/grid/account-tile.test.js.map +0 -1
- package/dist/test/tiles/grid/collection-tile.test.d.ts +0 -1
- package/dist/test/tiles/grid/collection-tile.test.js +0 -90
- package/dist/test/tiles/grid/collection-tile.test.js.map +0 -1
- package/dist/test/tiles/grid/item-tile.test.d.ts +0 -1
- package/dist/test/tiles/grid/item-tile.test.js +0 -400
- package/dist/test/tiles/grid/item-tile.test.js.map +0 -1
- package/dist/test/tiles/grid/search-tile.test.d.ts +0 -1
- package/dist/test/tiles/grid/search-tile.test.js +0 -62
- package/dist/test/tiles/grid/search-tile.test.js.map +0 -1
- package/dist/test/tiles/hover/hover-pane-controller.test.d.ts +0 -1
- package/dist/test/tiles/hover/hover-pane-controller.test.js +0 -351
- package/dist/test/tiles/hover/hover-pane-controller.test.js.map +0 -1
- package/dist/test/tiles/hover/tile-hover-pane.test.d.ts +0 -1
- package/dist/test/tiles/hover/tile-hover-pane.test.js +0 -53
- package/dist/test/tiles/hover/tile-hover-pane.test.js.map +0 -1
- package/dist/test/tiles/list/tile-list-compact-header.test.d.ts +0 -1
- package/dist/test/tiles/list/tile-list-compact-header.test.js +0 -36
- package/dist/test/tiles/list/tile-list-compact-header.test.js.map +0 -1
- package/dist/test/tiles/list/tile-list-compact.test.d.ts +0 -1
- package/dist/test/tiles/list/tile-list-compact.test.js +0 -237
- package/dist/test/tiles/list/tile-list-compact.test.js.map +0 -1
- package/dist/test/tiles/list/tile-list.test.d.ts +0 -1
- package/dist/test/tiles/list/tile-list.test.js +0 -460
- package/dist/test/tiles/list/tile-list.test.js.map +0 -1
- package/dist/test/tiles/tile-dispatcher.test.d.ts +0 -1
- package/dist/test/tiles/tile-dispatcher.test.js +0 -246
- package/dist/test/tiles/tile-dispatcher.test.js.map +0 -1
- package/dist/test/tiles/tile-display-value-provider.test.d.ts +0 -1
- package/dist/test/tiles/tile-display-value-provider.test.js +0 -142
- package/dist/test/tiles/tile-display-value-provider.test.js.map +0 -1
- package/dist/test/tiles/tile-mediatype-icon.test.d.ts +0 -1
- package/dist/test/tiles/tile-mediatype-icon.test.js +0 -133
- package/dist/test/tiles/tile-mediatype-icon.test.js.map +0 -1
- package/dist/test/utils/array-equals.test.d.ts +0 -1
- package/dist/test/utils/array-equals.test.js +0 -27
- package/dist/test/utils/array-equals.test.js.map +0 -1
- package/dist/test/utils/format-count.test.d.ts +0 -1
- package/dist/test/utils/format-count.test.js +0 -24
- package/dist/test/utils/format-count.test.js.map +0 -1
- package/dist/test/utils/format-date.test.d.ts +0 -1
- package/dist/test/utils/format-date.test.js +0 -61
- package/dist/test/utils/format-date.test.js.map +0 -1
- package/dist/test/utils/format-unit-size.test.d.ts +0 -1
- package/dist/test/utils/format-unit-size.test.js +0 -18
- package/dist/test/utils/format-unit-size.test.js.map +0 -1
- package/dist/test/utils/local-date-from-utc.test.d.ts +0 -1
- package/dist/test/utils/local-date-from-utc.test.js +0 -27
- package/dist/test/utils/local-date-from-utc.test.js.map +0 -1
- package/dist/test/utils/normalize-filter-text.test.d.ts +0 -1
- package/dist/test/utils/normalize-filter-text.test.js +0 -69
- package/dist/test/utils/normalize-filter-text.test.js.map +0 -1
- package/docs/design/column-virtualization.md +0 -214
- package/eslint.config.mjs +0 -53
- package/index.html +0 -24
- package/index.ts +0 -29
- package/local.archive.org.cert +0 -86
- package/local.archive.org.key +0 -27
- package/pnpm-workspace.yaml +0 -30
- package/renovate.json +0 -6
- package/src/app-root.ts +0 -1282
- package/src/assets/img/icons/arrow-left.ts +0 -10
- package/src/assets/img/icons/arrow-right.ts +0 -10
- package/src/assets/img/icons/check.ts +0 -5
- package/src/assets/img/icons/chevron.ts +0 -4
- package/src/assets/img/icons/close-circle-dark.ts +0 -5
- package/src/assets/img/icons/contract.ts +0 -9
- package/src/assets/img/icons/empty-query.ts +0 -5
- package/src/assets/img/icons/expand.ts +0 -9
- package/src/assets/img/icons/eye-closed.ts +0 -5
- package/src/assets/img/icons/eye.ts +0 -5
- package/src/assets/img/icons/favorite-filled.ts +0 -10
- package/src/assets/img/icons/favorite-unfilled.ts +0 -9
- package/src/assets/img/icons/filter.ts +0 -10
- package/src/assets/img/icons/login-required.ts +0 -18
- package/src/assets/img/icons/mediatype/account.ts +0 -14
- package/src/assets/img/icons/mediatype/audio.ts +0 -14
- package/src/assets/img/icons/mediatype/collection.ts +0 -12
- package/src/assets/img/icons/mediatype/data.ts +0 -15
- package/src/assets/img/icons/mediatype/etree.ts +0 -14
- package/src/assets/img/icons/mediatype/film.ts +0 -14
- package/src/assets/img/icons/mediatype/images.ts +0 -13
- package/src/assets/img/icons/mediatype/radio.ts +0 -15
- package/src/assets/img/icons/mediatype/search.ts +0 -14
- package/src/assets/img/icons/mediatype/software.ts +0 -13
- package/src/assets/img/icons/mediatype/texts.ts +0 -13
- package/src/assets/img/icons/mediatype/tv-commercial.ts +0 -12
- package/src/assets/img/icons/mediatype/tv-fact-check.ts +0 -12
- package/src/assets/img/icons/mediatype/tv-quote.ts +0 -12
- package/src/assets/img/icons/mediatype/tv.ts +0 -14
- package/src/assets/img/icons/mediatype/video.ts +0 -14
- package/src/assets/img/icons/mediatype/web.ts +0 -13
- package/src/assets/img/icons/null-result.ts +0 -5
- package/src/assets/img/icons/quote.ts +0 -7
- package/src/assets/img/icons/restricted.ts +0 -13
- package/src/assets/img/icons/reviews.ts +0 -11
- package/src/assets/img/icons/upload.ts +0 -12
- package/src/assets/img/icons/views.ts +0 -11
- package/src/circular-activity-indicator.ts +0 -64
- package/src/collection-browser.ts +0 -3165
- package/src/collection-facets/facet-row-template.ts +0 -242
- package/src/collection-facets/facet-row.ts +0 -122
- package/src/collection-facets/facet-tombstone-row.ts +0 -40
- package/src/collection-facets/facets-template.ts +0 -85
- package/src/collection-facets/models.ts +0 -16
- package/src/collection-facets/more-facets-content.ts +0 -951
- package/src/collection-facets/more-facets-scroller.ts +0 -485
- package/src/collection-facets/page-window.ts +0 -247
- package/src/collection-facets/smart-facets/dedupe.ts +0 -44
- package/src/collection-facets/smart-facets/heuristics/browser-language/browser-language-heuristic.ts +0 -27
- package/src/collection-facets/smart-facets/heuristics/index.ts +0 -3
- package/src/collection-facets/smart-facets/heuristics/query-keywords/query-keywords-heuristic.ts +0 -17
- package/src/collection-facets/smart-facets/heuristics/query-keywords/query-keywords-map.ts +0 -70
- package/src/collection-facets/smart-facets/heuristics/wikidata/wikidata-entity-map.ts +0 -79
- package/src/collection-facets/smart-facets/heuristics/wikidata/wikidata-heuristic.ts +0 -93
- package/src/collection-facets/smart-facets/models.ts +0 -36
- package/src/collection-facets/smart-facets/smart-facet-bar.ts +0 -437
- package/src/collection-facets/smart-facets/smart-facet-button.ts +0 -145
- package/src/collection-facets/smart-facets/smart-facet-dropdown.ts +0 -185
- package/src/collection-facets/smart-facets/smart-facet-equals.ts +0 -16
- package/src/collection-facets/smart-facets/smart-facet-heuristics.ts +0 -26
- package/src/collection-facets/toggle-switch.ts +0 -175
- package/src/collection-facets.ts +0 -1013
- package/src/data-source/collection-browser-data-source-interface.ts +0 -351
- package/src/data-source/collection-browser-data-source.ts +0 -1474
- package/src/data-source/collection-browser-query-state.ts +0 -60
- package/src/data-source/models.ts +0 -56
- package/src/empty-placeholder.ts +0 -192
- package/src/expanded-date-picker.ts +0 -191
- package/src/language-code-handler/language-code-handler.ts +0 -64
- package/src/language-code-handler/language-code-mapping.ts +0 -564
- package/src/manage/manage-bar.ts +0 -276
- package/src/manage/remove-items-modal-content.ts +0 -102
- package/src/mediatype/mediatype-config.ts +0 -146
- package/src/models.ts +0 -912
- package/src/restoration-state-handler.ts +0 -550
- package/src/sort-filter-bar/alpha-bar-tooltip.ts +0 -53
- package/src/sort-filter-bar/alpha-bar.ts +0 -252
- package/src/sort-filter-bar/img/compact.ts +0 -5
- package/src/sort-filter-bar/img/list.ts +0 -5
- package/src/sort-filter-bar/img/sort-toggle-disabled.ts +0 -15
- package/src/sort-filter-bar/img/sort-toggle-down.ts +0 -17
- package/src/sort-filter-bar/img/sort-toggle-up.ts +0 -17
- package/src/sort-filter-bar/img/sort-triangle.ts +0 -5
- package/src/sort-filter-bar/img/tile.ts +0 -5
- package/src/sort-filter-bar/sort-filter-bar.ts +0 -733
- package/src/styles/ia-button.ts +0 -139
- package/src/styles/item-image-styles.ts +0 -124
- package/src/styles/sr-only.ts +0 -18
- package/src/styles/tile-action-styles.ts +0 -59
- package/src/tiles/base-tile-component.ts +0 -124
- package/src/tiles/collection-browser-loading-tile.ts +0 -26
- package/src/tiles/grid/account-tile.ts +0 -113
- package/src/tiles/grid/collection-tile.ts +0 -184
- package/src/tiles/grid/item-tile.ts +0 -347
- package/src/tiles/grid/search-tile.ts +0 -90
- package/src/tiles/grid/styles/tile-grid-shared-styles.ts +0 -130
- package/src/tiles/grid/tile-stats.ts +0 -211
- package/src/tiles/hover/hover-pane-controller.ts +0 -638
- package/src/tiles/hover/tile-hover-pane.ts +0 -184
- package/src/tiles/image-block.ts +0 -162
- package/src/tiles/item-image.ts +0 -214
- package/src/tiles/list/tile-list-compact-header.ts +0 -112
- package/src/tiles/list/tile-list-compact.ts +0 -278
- package/src/tiles/list/tile-list.ts +0 -718
- package/src/tiles/models.ts +0 -21
- package/src/tiles/overlay/icon-overlay.ts +0 -57
- package/src/tiles/overlay/text-overlay.ts +0 -79
- package/src/tiles/review-block.ts +0 -130
- package/src/tiles/text-snippet-block.ts +0 -132
- package/src/tiles/tile-dispatcher.ts +0 -637
- package/src/tiles/tile-display-value-provider.ts +0 -133
- package/src/tiles/tile-mediatype-icon.ts +0 -133
- package/src/utils/analytics-events.ts +0 -29
- package/src/utils/array-equals.ts +0 -8
- package/src/utils/collapse-repeated-quotes.ts +0 -13
- package/src/utils/date-filter-field.ts +0 -11
- package/src/utils/facet-utils.ts +0 -183
- package/src/utils/format-count.ts +0 -95
- package/src/utils/format-date.ts +0 -62
- package/src/utils/format-unit-size.ts +0 -43
- package/src/utils/local-date-from-utc.ts +0 -15
- package/src/utils/log.ts +0 -14
- package/src/utils/normalize-filter-text.ts +0 -54
- package/src/utils/resolve-mediatype.ts +0 -26
- package/src/utils/sha1.ts +0 -9
- package/test/collection-browser.test.ts +0 -2639
- package/test/collection-facets/facet-row.test.ts +0 -421
- package/test/collection-facets/facets-template.test.ts +0 -139
- package/test/collection-facets/more-facets-content.test.ts +0 -716
- package/test/collection-facets/more-facets-scroller.test.ts +0 -401
- package/test/collection-facets/page-window.test.ts +0 -208
- package/test/collection-facets/toggle-switch.test.ts +0 -164
- package/test/collection-facets.test.ts +0 -928
- package/test/data-source/collection-browser-data-source.test.ts +0 -193
- package/test/empty-placeholder.test.ts +0 -88
- package/test/expanded-date-picker.test.ts +0 -201
- package/test/icon-overlay.test.ts +0 -38
- package/test/image-block.test.ts +0 -247
- package/test/item-image.test.ts +0 -220
- package/test/manage/manage-bar.test.ts +0 -347
- package/test/manage/remove-items-modal-content.test.ts +0 -81
- package/test/mediatype-config.test.ts +0 -11
- package/test/mocks/mock-analytics-handler.ts +0 -30
- package/test/mocks/mock-search-responses.ts +0 -1420
- package/test/mocks/mock-search-service.ts +0 -136
- package/test/restoration-state-handler.test.ts +0 -480
- package/test/review-block.test.ts +0 -62
- package/test/sort-filter-bar/alpha-bar-tooltip.test.ts +0 -17
- package/test/sort-filter-bar/alpha-bar.test.ts +0 -101
- package/test/sort-filter-bar/sort-filter-bar.test.ts +0 -443
- package/test/text-overlay.test.ts +0 -55
- package/test/text-snippet-block.test.ts +0 -85
- package/test/tile-stats.test.ts +0 -191
- package/test/tiles/grid/account-tile.test.ts +0 -121
- package/test/tiles/grid/collection-tile.test.ts +0 -114
- package/test/tiles/grid/item-tile.test.ts +0 -520
- package/test/tiles/grid/search-tile.test.ts +0 -75
- package/test/tiles/hover/hover-pane-controller.test.ts +0 -482
- package/test/tiles/hover/tile-hover-pane.test.ts +0 -80
- package/test/tiles/list/tile-list-compact-header.test.ts +0 -43
- package/test/tiles/list/tile-list-compact.test.ts +0 -282
- package/test/tiles/list/tile-list.test.ts +0 -576
- package/test/tiles/tile-dispatcher.test.ts +0 -320
- package/test/tiles/tile-display-value-provider.test.ts +0 -172
- package/test/tiles/tile-mediatype-icon.test.ts +0 -160
- package/test/utils/array-equals.test.ts +0 -31
- package/test/utils/format-count.test.ts +0 -32
- package/test/utils/format-date.test.ts +0 -89
- package/test/utils/format-unit-size.test.ts +0 -21
- package/test/utils/local-date-from-utc.test.ts +0 -37
- package/test/utils/normalize-filter-text.test.ts +0 -87
- package/tsconfig.json +0 -25
- package/types/dompurify.d.ts +0 -1
- package/vite.config.ts +0 -29
- package/web-dev-server.config.mjs +0 -30
- package/web-test-runner.config.mjs +0 -57
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { expect } from '@open-wc/testing';
|
|
2
|
-
import { arrayEquals } from '../../src/utils/array-equals';
|
|
3
|
-
describe('arrayEquals', () => {
|
|
4
|
-
it('returns true for empty args', () => {
|
|
5
|
-
expect(arrayEquals([], [])).to.be.true;
|
|
6
|
-
});
|
|
7
|
-
it('returns true for identical array objects', () => {
|
|
8
|
-
const arr = ['foo', 'bar'];
|
|
9
|
-
expect(arrayEquals(arr, arr)).to.be.true;
|
|
10
|
-
});
|
|
11
|
-
it('returns true for arrays with identical contents', () => {
|
|
12
|
-
const arr1 = ['foo', 'bar'];
|
|
13
|
-
const arr2 = ['foo', 'bar'];
|
|
14
|
-
expect(arrayEquals(arr1, arr2)).to.be.true;
|
|
15
|
-
});
|
|
16
|
-
it('returns false for arrays of unequal length', () => {
|
|
17
|
-
const arr1 = [1, 2, 3];
|
|
18
|
-
const arr2 = [1, 2, 3, 4];
|
|
19
|
-
expect(arrayEquals(arr1, arr2)).to.be.false;
|
|
20
|
-
});
|
|
21
|
-
it('returns false for unequal arrays of same length', () => {
|
|
22
|
-
const arr1 = ['foo', 'bar'];
|
|
23
|
-
const arr2 = ['foo', 'qux'];
|
|
24
|
-
expect(arrayEquals(arr1, arr2)).to.be.false;
|
|
25
|
-
});
|
|
26
|
-
});
|
|
27
|
-
//# sourceMappingURL=array-equals.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"array-equals.test.js","sourceRoot":"","sources":["../../../test/utils/array-equals.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAE3D,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;IAC3B,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE;QACrC,MAAM,CAAC,WAAW,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;QAClD,MAAM,GAAG,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAC3B,MAAM,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;QACzD,MAAM,IAAI,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAC5B,MAAM,IAAI,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAC5B,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;QACpD,MAAM,IAAI,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QACvB,MAAM,IAAI,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAC1B,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;QACzD,MAAM,IAAI,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAC5B,MAAM,IAAI,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAC5B,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC;IAC9C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { expect } from '@open-wc/testing';\nimport { arrayEquals } from '../../src/utils/array-equals';\n\ndescribe('arrayEquals', () => {\n it('returns true for empty args', () => {\n expect(arrayEquals([], [])).to.be.true;\n });\n\n it('returns true for identical array objects', () => {\n const arr = ['foo', 'bar'];\n expect(arrayEquals(arr, arr)).to.be.true;\n });\n\n it('returns true for arrays with identical contents', () => {\n const arr1 = ['foo', 'bar'];\n const arr2 = ['foo', 'bar'];\n expect(arrayEquals(arr1, arr2)).to.be.true;\n });\n\n it('returns false for arrays of unequal length', () => {\n const arr1 = [1, 2, 3];\n const arr2 = [1, 2, 3, 4];\n expect(arrayEquals(arr1, arr2)).to.be.false;\n });\n\n it('returns false for unequal arrays of same length', () => {\n const arr1 = ['foo', 'bar'];\n const arr2 = ['foo', 'qux'];\n expect(arrayEquals(arr1, arr2)).to.be.false;\n });\n});\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { expect } from '@open-wc/testing';
|
|
2
|
-
import { formatCount } from '../../src/utils/format-count';
|
|
3
|
-
const testCount = 805342;
|
|
4
|
-
describe('formatCount', () => {
|
|
5
|
-
it('returns blank when undefined number', () => {
|
|
6
|
-
expect(formatCount(undefined)).to.equal('');
|
|
7
|
-
});
|
|
8
|
-
it('returns blank when negative number', () => {
|
|
9
|
-
expect(formatCount(testCount * -1)).to.equal('');
|
|
10
|
-
});
|
|
11
|
-
it('returns long number when no NumberFormat', () => {
|
|
12
|
-
expect(formatCount(testCount)).to.equal('805,342');
|
|
13
|
-
});
|
|
14
|
-
it('returns short number when short NumberFormat', () => {
|
|
15
|
-
expect(formatCount(testCount, 'short')).to.equal('805K');
|
|
16
|
-
});
|
|
17
|
-
it('returns decimal when value of significant digits < 10', () => {
|
|
18
|
-
expect(formatCount(testCount * 10, 'short', 'long')).to.equal('8.1 million');
|
|
19
|
-
});
|
|
20
|
-
it('returns locale formatted number', () => {
|
|
21
|
-
expect(formatCount(testCount, 'long', 'long', 'de-DE')).to.equal('805.342');
|
|
22
|
-
});
|
|
23
|
-
});
|
|
24
|
-
//# sourceMappingURL=format-count.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"format-count.test.js","sourceRoot":"","sources":["../../../test/utils/format-count.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAE3D,MAAM,SAAS,GAAG,MAAM,CAAC;AAEzB,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;IAC3B,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;QAC5C,MAAM,CAAC,WAAW,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;QAClD,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACtD,MAAM,CAAC,WAAW,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;QAC/D,MAAM,CAAC,WAAW,CAAC,SAAS,GAAG,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAC3D,aAAa,CACd,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QACzC,MAAM,CAAC,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAC9E,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { expect } from '@open-wc/testing';\nimport { formatCount } from '../../src/utils/format-count';\n\nconst testCount = 805342;\n\ndescribe('formatCount', () => {\n it('returns blank when undefined number', () => {\n expect(formatCount(undefined)).to.equal('');\n });\n\n it('returns blank when negative number', () => {\n expect(formatCount(testCount * -1)).to.equal('');\n });\n\n it('returns long number when no NumberFormat', () => {\n expect(formatCount(testCount)).to.equal('805,342');\n });\n\n it('returns short number when short NumberFormat', () => {\n expect(formatCount(testCount, 'short')).to.equal('805K');\n });\n\n it('returns decimal when value of significant digits < 10', () => {\n expect(formatCount(testCount * 10, 'short', 'long')).to.equal(\n '8.1 million',\n );\n });\n\n it('returns locale formatted number', () => {\n expect(formatCount(testCount, 'long', 'long', 'de-DE')).to.equal('805.342');\n });\n});\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { expect } from '@open-wc/testing';
|
|
2
|
-
import { formatDate } from '../../src/utils/format-date';
|
|
3
|
-
const testDate = new Date(2020, 11, 9);
|
|
4
|
-
describe('formatDate', () => {
|
|
5
|
-
it('returns blank when undefined date', () => {
|
|
6
|
-
expect(formatDate(undefined)).to.equal('');
|
|
7
|
-
});
|
|
8
|
-
it('returns short date when no DateFormat', () => {
|
|
9
|
-
expect(formatDate(testDate)).to.equal('Dec 2020');
|
|
10
|
-
});
|
|
11
|
-
it('returns long date when long DateFormat', () => {
|
|
12
|
-
expect(formatDate(testDate, 'long')).to.equal('Dec 09, 2020');
|
|
13
|
-
});
|
|
14
|
-
it('returns year-only date when year-only DateFormat', () => {
|
|
15
|
-
expect(formatDate(testDate, 'year-only')).to.equal('2020');
|
|
16
|
-
});
|
|
17
|
-
it('returns correct year for old "Jan 1 at midnight" dates and year-only DateFormat', () => {
|
|
18
|
-
// Many standard timezones have a discontinuity in date parsing at some point during
|
|
19
|
-
// the 19th or 20th century, corresponding to the creation of the timezone.
|
|
20
|
-
// Dates prior to the discontinuity generally have a non-hour-aligned timezone offset
|
|
21
|
-
// which can throw off the calculated year for dates which are close to a year boundary.
|
|
22
|
-
// This is particularly problematic for "Jan 1 at midnight" dates, which are what we
|
|
23
|
-
// receive from the search engine for date metadata that only specifies the year.
|
|
24
|
-
// So we must ensure these older dates still output the correct year, not the prior one.
|
|
25
|
-
expect(formatDate(new Date('1234-01-01T00:00:00Z'), 'year-only')).to.equal('1234');
|
|
26
|
-
});
|
|
27
|
-
it('uses UTC time zone by default or when useLocalTime is explicitly false', () => {
|
|
28
|
-
// Default options
|
|
29
|
-
expect(formatDate(new Date('2025-02-15T00:00:00Z'), 'long')).to.equal('Feb 15, 2025');
|
|
30
|
-
expect(formatDate(new Date('2025-02-15T23:59:59Z'), 'long')).to.equal('Feb 15, 2025');
|
|
31
|
-
// Explicit `useLocalTime: false` option
|
|
32
|
-
const options = { useLocalTime: false };
|
|
33
|
-
expect(formatDate(new Date('2025-02-15T00:00:00Z'), 'long', options)).to.equal('Feb 15, 2025');
|
|
34
|
-
expect(formatDate(new Date('2025-02-15T23:59:59Z'), 'long', options)).to.equal('Feb 15, 2025');
|
|
35
|
-
});
|
|
36
|
-
it('uses local time zone when specified', () => {
|
|
37
|
-
// N.B.:
|
|
38
|
-
// - Positive offset corresponds to UTC-x zones
|
|
39
|
-
// - Negative offset corresponds to UTC+x zones
|
|
40
|
-
const offset = new Date().getTimezoneOffset();
|
|
41
|
-
const options = { useLocalTime: true };
|
|
42
|
-
// The expected behavior depends on the local time where the tests are run:
|
|
43
|
-
if (offset > 0) {
|
|
44
|
-
// If we're testing under a positive offset, the first second of the UTC day should locally fall on the previous day
|
|
45
|
-
expect(formatDate(new Date('2025-02-15T00:00:00Z'), 'long', options)).to.equal('Feb 14, 2025');
|
|
46
|
-
}
|
|
47
|
-
else if (offset < 0) {
|
|
48
|
-
// If we're testing under a negative offset, the last second of the UTC day should locally fall on the next day
|
|
49
|
-
expect(formatDate(new Date('2025-02-15T23:59:59Z'), 'long', options)).to.equal('Feb 16, 2025');
|
|
50
|
-
}
|
|
51
|
-
else {
|
|
52
|
-
// If we're testing *in* UTC, then both seconds should locally fall on the same day
|
|
53
|
-
expect(formatDate(new Date('2025-02-15T00:00:00Z'), 'long', options)).to.equal('Feb 15, 2025');
|
|
54
|
-
expect(formatDate(new Date('2025-02-15T23:59:59Z'), 'long', options)).to.equal('Feb 15, 2025');
|
|
55
|
-
}
|
|
56
|
-
});
|
|
57
|
-
it('returns locale formatted date', () => {
|
|
58
|
-
expect(formatDate(testDate, 'long', { locale: 'de-DE' })).to.equal('09. Dez. 2020');
|
|
59
|
-
});
|
|
60
|
-
});
|
|
61
|
-
//# sourceMappingURL=format-date.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"format-date.test.js","sourceRoot":"","sources":["../../../test/utils/format-date.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { expect } from '@open-wc/testing';\nimport { formatDate } from '../../src/utils/format-date';\n\nconst testDate = new Date(2020, 11, 9);\n\ndescribe('formatDate', () => {\n it('returns blank when undefined date', () => {\n expect(formatDate(undefined)).to.equal('');\n });\n\n it('returns short date when no DateFormat', () => {\n expect(formatDate(testDate)).to.equal('Dec 2020');\n });\n\n it('returns long date when long DateFormat', () => {\n expect(formatDate(testDate, 'long')).to.equal('Dec 09, 2020');\n });\n\n it('returns year-only date when year-only DateFormat', () => {\n expect(formatDate(testDate, 'year-only')).to.equal('2020');\n });\n\n it('returns correct year for old \"Jan 1 at midnight\" dates and year-only DateFormat', () => {\n // Many standard timezones have a discontinuity in date parsing at some point during\n // the 19th or 20th century, corresponding to the creation of the timezone.\n // Dates prior to the discontinuity generally have a non-hour-aligned timezone offset\n // which can throw off the calculated year for dates which are close to a year boundary.\n // This is particularly problematic for \"Jan 1 at midnight\" dates, which are what we\n // receive from the search engine for date metadata that only specifies the year.\n // So we must ensure these older dates still output the correct year, not the prior one.\n expect(formatDate(new Date('1234-01-01T00:00:00Z'), 'year-only')).to.equal(\n '1234',\n );\n });\n\n it('uses UTC time zone by default or when useLocalTime is explicitly false', () => {\n // Default options\n expect(formatDate(new Date('2025-02-15T00:00:00Z'), 'long')).to.equal(\n 'Feb 15, 2025',\n );\n expect(formatDate(new Date('2025-02-15T23:59:59Z'), 'long')).to.equal(\n 'Feb 15, 2025',\n );\n\n // Explicit `useLocalTime: false` option\n const options = { useLocalTime: false };\n expect(\n formatDate(new Date('2025-02-15T00:00:00Z'), 'long', options),\n ).to.equal('Feb 15, 2025');\n expect(\n formatDate(new Date('2025-02-15T23:59:59Z'), 'long', options),\n ).to.equal('Feb 15, 2025');\n });\n\n it('uses local time zone when specified', () => {\n // N.B.:\n // - Positive offset corresponds to UTC-x zones\n // - Negative offset corresponds to UTC+x zones\n const offset = new Date().getTimezoneOffset();\n const options = { useLocalTime: true };\n\n // The expected behavior depends on the local time where the tests are run:\n if (offset > 0) {\n // If we're testing under a positive offset, the first second of the UTC day should locally fall on the previous day\n expect(\n formatDate(new Date('2025-02-15T00:00:00Z'), 'long', options),\n ).to.equal('Feb 14, 2025');\n } else if (offset < 0) {\n // If we're testing under a negative offset, the last second of the UTC day should locally fall on the next day\n expect(\n formatDate(new Date('2025-02-15T23:59:59Z'), 'long', options),\n ).to.equal('Feb 16, 2025');\n } else {\n // If we're testing *in* UTC, then both seconds should locally fall on the same day\n expect(\n formatDate(new Date('2025-02-15T00:00:00Z'), 'long', options),\n ).to.equal('Feb 15, 2025');\n expect(\n formatDate(new Date('2025-02-15T23:59:59Z'), 'long', options),\n ).to.equal('Feb 15, 2025');\n }\n });\n\n it('returns locale formatted date', () => {\n expect(formatDate(testDate, 'long', { locale: 'de-DE' })).to.equal(\n '09. Dez. 2020',\n );\n });\n});\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { expect } from '@open-wc/testing';
|
|
2
|
-
import { nothing } from 'lit';
|
|
3
|
-
import { formatUnitSize } from '../../src/utils/format-unit-size';
|
|
4
|
-
describe('formatUnitSize', () => {
|
|
5
|
-
it('returns blank when undefined number', () => {
|
|
6
|
-
expect(formatUnitSize(undefined, 1)).to.equal(nothing);
|
|
7
|
-
});
|
|
8
|
-
it('returns collection data is in singular form', () => {
|
|
9
|
-
expect(formatUnitSize(1025, 1)).to.equal('1 kilobyte');
|
|
10
|
-
});
|
|
11
|
-
it('return collection size data in kilobytes and plural form', () => {
|
|
12
|
-
expect(formatUnitSize(15000, 1)).to.equal('14.6 kilobytes');
|
|
13
|
-
});
|
|
14
|
-
it('return huge collection size data', () => {
|
|
15
|
-
expect(formatUnitSize(454154654134, 1)).to.equal('423 gigabytes');
|
|
16
|
-
});
|
|
17
|
-
});
|
|
18
|
-
//# sourceMappingURL=format-unit-size.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"format-unit-size.test.js","sourceRoot":"","sources":["../../../test/utils/format-unit-size.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAC9B,OAAO,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAElE,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;IAC9B,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,MAAM,CAAC,cAAc,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACrD,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0DAA0D,EAAE,GAAG,EAAE;QAClE,MAAM,CAAC,cAAc,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;IAC9D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAC1C,MAAM,CAAC,cAAc,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;IACpE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { expect } from '@open-wc/testing';\nimport { nothing } from 'lit';\nimport { formatUnitSize } from '../../src/utils/format-unit-size';\n\ndescribe('formatUnitSize', () => {\n it('returns blank when undefined number', () => {\n expect(formatUnitSize(undefined, 1)).to.equal(nothing);\n });\n\n it('returns collection data is in singular form', () => {\n expect(formatUnitSize(1025, 1)).to.equal('1 kilobyte');\n });\n\n it('return collection size data in kilobytes and plural form', () => {\n expect(formatUnitSize(15000, 1)).to.equal('14.6 kilobytes');\n });\n\n it('return huge collection size data', () => {\n expect(formatUnitSize(454154654134, 1)).to.equal('423 gigabytes');\n });\n});\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { expect } from '@open-wc/testing';
|
|
2
|
-
import { localDateFromUTC, isFirstMillisecondOfUTCYear, } from '../../src/utils/local-date-from-utc';
|
|
3
|
-
describe('localDateFromUTC', () => {
|
|
4
|
-
it('converts dates from UTC to local timezone', async () => {
|
|
5
|
-
const date = new Date(1990, 1, 2, 3, 4, 5, 6);
|
|
6
|
-
const dateFromUTC = new Date(Date.UTC(1990, 1, 2, 3, 4, 5, 6));
|
|
7
|
-
expect(localDateFromUTC(date).toISOString()).to.equal(dateFromUTC.toISOString());
|
|
8
|
-
});
|
|
9
|
-
});
|
|
10
|
-
describe('isFirstMillisecondOfUTCYear', () => {
|
|
11
|
-
it('returns true when date is exactly Jan 1 at midnight in UTC', async () => {
|
|
12
|
-
const midnightOnNewYearsDay = new Date('2010-01-01T00:00:00Z');
|
|
13
|
-
expect(isFirstMillisecondOfUTCYear(midnightOnNewYearsDay)).to.be.true;
|
|
14
|
-
});
|
|
15
|
-
it('returns false when date is not exactly Jan 1 at midnight in UTC', async () => {
|
|
16
|
-
const oneMillisecondTooEarly = new Date('2009-12-31T23:59:59.999Z');
|
|
17
|
-
expect(isFirstMillisecondOfUTCYear(oneMillisecondTooEarly)).to.be.false;
|
|
18
|
-
const oneMillisecondTooLate = new Date('2010-01-01T00:00:00.001Z');
|
|
19
|
-
expect(isFirstMillisecondOfUTCYear(oneMillisecondTooLate)).to.be.false;
|
|
20
|
-
const middleOfTheYear = new Date('2010-06-01T00:00:00Z');
|
|
21
|
-
expect(isFirstMillisecondOfUTCYear(middleOfTheYear)).to.be.false;
|
|
22
|
-
});
|
|
23
|
-
it('returns false when no date provided', async () => {
|
|
24
|
-
expect(isFirstMillisecondOfUTCYear(undefined)).to.be.false;
|
|
25
|
-
});
|
|
26
|
-
});
|
|
27
|
-
//# sourceMappingURL=local-date-from-utc.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"local-date-from-utc.test.js","sourceRoot":"","sources":["../../../test/utils/local-date-from-utc.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EACL,gBAAgB,EAChB,2BAA2B,GAC5B,MAAM,qCAAqC,CAAC;AAE7C,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAChC,EAAE,CAAC,2CAA2C,EAAE,KAAK,IAAI,EAAE;QACzD,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAC9C,MAAM,WAAW,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAC/D,MAAM,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CACnD,WAAW,CAAC,WAAW,EAAE,CAC1B,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,6BAA6B,EAAE,GAAG,EAAE;IAC3C,EAAE,CAAC,4DAA4D,EAAE,KAAK,IAAI,EAAE;QAC1E,MAAM,qBAAqB,GAAG,IAAI,IAAI,CAAC,sBAAsB,CAAC,CAAC;QAC/D,MAAM,CAAC,2BAA2B,CAAC,qBAAqB,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;IACxE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iEAAiE,EAAE,KAAK,IAAI,EAAE;QAC/E,MAAM,sBAAsB,GAAG,IAAI,IAAI,CAAC,0BAA0B,CAAC,CAAC;QACpE,MAAM,CAAC,2BAA2B,CAAC,sBAAsB,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC;QAExE,MAAM,qBAAqB,GAAG,IAAI,IAAI,CAAC,0BAA0B,CAAC,CAAC;QACnE,MAAM,CAAC,2BAA2B,CAAC,qBAAqB,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC;QAEvE,MAAM,eAAe,GAAG,IAAI,IAAI,CAAC,sBAAsB,CAAC,CAAC;QACzD,MAAM,CAAC,2BAA2B,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC;IACnE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,KAAK,IAAI,EAAE;QACnD,MAAM,CAAC,2BAA2B,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC;IAC7D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { expect } from '@open-wc/testing';\nimport {\n localDateFromUTC,\n isFirstMillisecondOfUTCYear,\n} from '../../src/utils/local-date-from-utc';\n\ndescribe('localDateFromUTC', () => {\n it('converts dates from UTC to local timezone', async () => {\n const date = new Date(1990, 1, 2, 3, 4, 5, 6);\n const dateFromUTC = new Date(Date.UTC(1990, 1, 2, 3, 4, 5, 6));\n expect(localDateFromUTC(date).toISOString()).to.equal(\n dateFromUTC.toISOString(),\n );\n });\n});\n\ndescribe('isFirstMillisecondOfUTCYear', () => {\n it('returns true when date is exactly Jan 1 at midnight in UTC', async () => {\n const midnightOnNewYearsDay = new Date('2010-01-01T00:00:00Z');\n expect(isFirstMillisecondOfUTCYear(midnightOnNewYearsDay)).to.be.true;\n });\n\n it('returns false when date is not exactly Jan 1 at midnight in UTC', async () => {\n const oneMillisecondTooEarly = new Date('2009-12-31T23:59:59.999Z');\n expect(isFirstMillisecondOfUTCYear(oneMillisecondTooEarly)).to.be.false;\n\n const oneMillisecondTooLate = new Date('2010-01-01T00:00:00.001Z');\n expect(isFirstMillisecondOfUTCYear(oneMillisecondTooLate)).to.be.false;\n\n const middleOfTheYear = new Date('2010-06-01T00:00:00Z');\n expect(isFirstMillisecondOfUTCYear(middleOfTheYear)).to.be.false;\n });\n\n it('returns false when no date provided', async () => {\n expect(isFirstMillisecondOfUTCYear(undefined)).to.be.false;\n });\n});\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
import { expect } from '@open-wc/testing';
|
|
2
|
-
import { filterTextIncludes, normalizeFilterText, } from '../../src/utils/normalize-filter-text';
|
|
3
|
-
/** Whether filtering for `filter` would find `text` */
|
|
4
|
-
function finds(text, filter) {
|
|
5
|
-
return filterTextIncludes(normalizeFilterText(text), normalizeFilterText(filter));
|
|
6
|
-
}
|
|
7
|
-
describe('normalizeFilterText', () => {
|
|
8
|
-
it('lowercases text', () => {
|
|
9
|
-
expect(normalizeFilterText('Puppies')).to.deep.equal({
|
|
10
|
-
spaced: 'puppies',
|
|
11
|
-
joined: 'puppies',
|
|
12
|
-
});
|
|
13
|
-
});
|
|
14
|
-
it('removes punctuation other than word joiners', () => {
|
|
15
|
-
expect(normalizeFilterText('A.O.R.').spaced).to.equal('aor');
|
|
16
|
-
expect(normalizeFilterText('Dr. Drew').spaced).to.equal('dr drew');
|
|
17
|
-
expect(normalizeFilterText("Children's books").spaced).to.equal('childrens books');
|
|
18
|
-
});
|
|
19
|
-
it('turns word joiners into spaces in one form and removes them in the other', () => {
|
|
20
|
-
expect(normalizeFilterText('WC-TV')).to.deep.equal({
|
|
21
|
-
spaced: 'wc tv',
|
|
22
|
-
joined: 'wctv',
|
|
23
|
-
});
|
|
24
|
-
expect(normalizeFilterText('AC/DC')).to.deep.equal({
|
|
25
|
-
spaced: 'ac dc',
|
|
26
|
-
joined: 'acdc',
|
|
27
|
-
});
|
|
28
|
-
expect(normalizeFilterText('snake_case')).to.deep.equal({
|
|
29
|
-
spaced: 'snake case',
|
|
30
|
-
joined: 'snakecase',
|
|
31
|
-
});
|
|
32
|
-
expect(normalizeFilterText('1950–1960').spaced).to.equal('1950 1960');
|
|
33
|
-
});
|
|
34
|
-
it('removes accents', () => {
|
|
35
|
-
expect(normalizeFilterText('Café Müller').spaced).to.equal('cafe muller');
|
|
36
|
-
});
|
|
37
|
-
it('collapses and trims whitespace', () => {
|
|
38
|
-
expect(normalizeFilterText(' Dogs -- Fiction ')).to.deep.equal({
|
|
39
|
-
spaced: 'dogs fiction',
|
|
40
|
-
joined: 'dogs fiction',
|
|
41
|
-
});
|
|
42
|
-
});
|
|
43
|
-
it('keeps symbols that carry meaning', () => {
|
|
44
|
-
expect(normalizeFilterText('C++').spaced).to.equal('c++');
|
|
45
|
-
});
|
|
46
|
-
it('reduces text that is only punctuation to nothing', () => {
|
|
47
|
-
expect(normalizeFilterText('...')).to.deep.equal({
|
|
48
|
-
spaced: '',
|
|
49
|
-
joined: '',
|
|
50
|
-
});
|
|
51
|
-
expect(normalizeFilterText(' - ').spaced).to.equal('');
|
|
52
|
-
});
|
|
53
|
-
});
|
|
54
|
-
describe('filterTextIncludes', () => {
|
|
55
|
-
it('matches hyphenated words typed apart or together', () => {
|
|
56
|
-
expect(finds('WC-TV', 'wc tv')).to.be.true;
|
|
57
|
-
expect(finds('WC-TV', 'wctv')).to.be.true;
|
|
58
|
-
expect(finds('WC-TV', 'wc-tv')).to.be.true;
|
|
59
|
-
expect(finds('Human-animal relationships', 'human animal')).to.be.true;
|
|
60
|
-
});
|
|
61
|
-
it('matches regardless of other punctuation', () => {
|
|
62
|
-
expect(finds('A.O.R.', 'aor')).to.be.true;
|
|
63
|
-
expect(finds('Dr. Drew', 'dr drew')).to.be.true;
|
|
64
|
-
});
|
|
65
|
-
it("doesn't match words that are apart in the value but typed together", () => {
|
|
66
|
-
expect(finds('WC TV', 'wctv')).to.be.false;
|
|
67
|
-
});
|
|
68
|
-
});
|
|
69
|
-
//# sourceMappingURL=normalize-filter-text.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"normalize-filter-text.test.js","sourceRoot":"","sources":["../../../test/utils/normalize-filter-text.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { expect } from '@open-wc/testing';\nimport {\n filterTextIncludes,\n normalizeFilterText,\n} from '../../src/utils/normalize-filter-text';\n\n/** Whether filtering for `filter` would find `text` */\nfunction finds(text: string, filter: string): boolean {\n return filterTextIncludes(\n normalizeFilterText(text),\n normalizeFilterText(filter),\n );\n}\n\ndescribe('normalizeFilterText', () => {\n it('lowercases text', () => {\n expect(normalizeFilterText('Puppies')).to.deep.equal({\n spaced: 'puppies',\n joined: 'puppies',\n });\n });\n\n it('removes punctuation other than word joiners', () => {\n expect(normalizeFilterText('A.O.R.').spaced).to.equal('aor');\n expect(normalizeFilterText('Dr. Drew').spaced).to.equal('dr drew');\n expect(normalizeFilterText(\"Children's books\").spaced).to.equal(\n 'childrens books',\n );\n });\n\n it('turns word joiners into spaces in one form and removes them in the other', () => {\n expect(normalizeFilterText('WC-TV')).to.deep.equal({\n spaced: 'wc tv',\n joined: 'wctv',\n });\n expect(normalizeFilterText('AC/DC')).to.deep.equal({\n spaced: 'ac dc',\n joined: 'acdc',\n });\n expect(normalizeFilterText('snake_case')).to.deep.equal({\n spaced: 'snake case',\n joined: 'snakecase',\n });\n expect(normalizeFilterText('1950–1960').spaced).to.equal('1950 1960');\n });\n\n it('removes accents', () => {\n expect(normalizeFilterText('Café Müller').spaced).to.equal('cafe muller');\n });\n\n it('collapses and trims whitespace', () => {\n expect(normalizeFilterText(' Dogs -- Fiction ')).to.deep.equal({\n spaced: 'dogs fiction',\n joined: 'dogs fiction',\n });\n });\n\n it('keeps symbols that carry meaning', () => {\n expect(normalizeFilterText('C++').spaced).to.equal('c++');\n });\n\n it('reduces text that is only punctuation to nothing', () => {\n expect(normalizeFilterText('...')).to.deep.equal({\n spaced: '',\n joined: '',\n });\n expect(normalizeFilterText(' - ').spaced).to.equal('');\n });\n});\n\ndescribe('filterTextIncludes', () => {\n it('matches hyphenated words typed apart or together', () => {\n expect(finds('WC-TV', 'wc tv')).to.be.true;\n expect(finds('WC-TV', 'wctv')).to.be.true;\n expect(finds('WC-TV', 'wc-tv')).to.be.true;\n expect(finds('Human-animal relationships', 'human animal')).to.be.true;\n });\n\n it('matches regardless of other punctuation', () => {\n expect(finds('A.O.R.', 'aor')).to.be.true;\n expect(finds('Dr. Drew', 'dr drew')).to.be.true;\n });\n\n it(\"doesn't match words that are apart in the value but typed together\", () => {\n expect(finds('WC TV', 'wctv')).to.be.false;\n });\n});\n"]}
|
|
@@ -1,214 +0,0 @@
|
|
|
1
|
-
# Horizontal column virtualization with page snapping
|
|
2
|
-
|
|
3
|
-
## Goal
|
|
4
|
-
A Lit component that scrolls thousands of fixed-width data columns horizontally.
|
|
5
|
-
Free scroll/fling during the gesture; on release, eases to the nearest page
|
|
6
|
-
boundary. Only a window of pages is in the DOM at any time.
|
|
7
|
-
|
|
8
|
-
## Constraints
|
|
9
|
-
- Dataset is fully in memory (thousands of column entries). No fetching.
|
|
10
|
-
- Column width is fixed and uniform. `colsPerPage` is derived from measured
|
|
11
|
-
viewport width, so a page is never wider than the viewport.
|
|
12
|
-
- Lit + LitElement. Page count can reach the high hundreds.
|
|
13
|
-
|
|
14
|
-
## Chosen approach
|
|
15
|
-
Native scrolling over a full-width sizer, with absolutely positioned page
|
|
16
|
-
elements at computed offsets, plus CSS scroll-snap for the page easing.
|
|
17
|
-
Positions are pure arithmetic — no measurement, no size estimation.
|
|
18
|
-
|
|
19
|
-
### Windowing controller
|
|
20
|
-
```ts
|
|
21
|
-
export class PageWindow implements ReactiveController {
|
|
22
|
-
first = 0;
|
|
23
|
-
last = -1;
|
|
24
|
-
private scroller?: HTMLElement;
|
|
25
|
-
private viewportW = 0;
|
|
26
|
-
private frame = 0;
|
|
27
|
-
private ro?: ResizeObserver;
|
|
28
|
-
|
|
29
|
-
constructor(
|
|
30
|
-
private host: ReactiveControllerHost,
|
|
31
|
-
private cfg: {colWidth: number; colsPerPage: number; total: number; buffer?: number}
|
|
32
|
-
) {
|
|
33
|
-
host.addController(this);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
get pageWidth() { return this.cfg.colWidth * this.cfg.colsPerPage; }
|
|
37
|
-
get pageCount() { return Math.ceil(this.cfg.total / this.cfg.colsPerPage); }
|
|
38
|
-
get totalWidth() { return this.cfg.colWidth * this.cfg.total; }
|
|
39
|
-
|
|
40
|
-
attach = (el?: Element) => {
|
|
41
|
-
if (!(el instanceof HTMLElement) || el === this.scroller) return;
|
|
42
|
-
this.scroller = el;
|
|
43
|
-
el.addEventListener('scroll', this.onScroll, {passive: true});
|
|
44
|
-
this.ro = new ResizeObserver(([e]) => {
|
|
45
|
-
this.viewportW = e.contentRect.width;
|
|
46
|
-
this.recompute();
|
|
47
|
-
});
|
|
48
|
-
this.ro.observe(el);
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
private onScroll = () => {
|
|
52
|
-
if (this.frame) return;
|
|
53
|
-
this.frame = requestAnimationFrame(() => {
|
|
54
|
-
this.frame = 0;
|
|
55
|
-
this.recompute();
|
|
56
|
-
});
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
private recompute() {
|
|
60
|
-
const pw = this.pageWidth;
|
|
61
|
-
const buf = this.cfg.buffer ?? 1;
|
|
62
|
-
const left = this.scroller!.scrollLeft;
|
|
63
|
-
const first = Math.max(0, Math.floor(left / pw) - buf);
|
|
64
|
-
const last = Math.min(this.pageCount - 1, Math.floor((left + this.viewportW) / pw) + buf);
|
|
65
|
-
if (first === this.first && last === this.last) return; // most scroll events end here
|
|
66
|
-
this.first = first;
|
|
67
|
-
this.last = last;
|
|
68
|
-
this.host.requestUpdate();
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
hostDisconnected() {
|
|
72
|
-
this.scroller?.removeEventListener('scroll', this.onScroll);
|
|
73
|
-
this.ro?.disconnect();
|
|
74
|
-
if (this.frame) cancelAnimationFrame(this.frame);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
### Template
|
|
80
|
-
Snap alignment lives on permanent empty stubs, one per page, *not* on the
|
|
81
|
-
rendered pages. See "Snap targets" below for why.
|
|
82
|
-
```ts
|
|
83
|
-
render() {
|
|
84
|
-
const w = this.win;
|
|
85
|
-
const all = [];
|
|
86
|
-
for (let i = 0; i < w.pageCount; i++) all.push(i);
|
|
87
|
-
const live = [];
|
|
88
|
-
for (let i = w.first; i <= w.last; i++) live.push(i);
|
|
89
|
-
|
|
90
|
-
return html`
|
|
91
|
-
<div class="scroller" ${ref(this.win.attach)}>
|
|
92
|
-
<div class="sizer" style="width:${w.totalWidth}px">
|
|
93
|
-
${repeat(all, i => i, i => html`
|
|
94
|
-
<div class="snap-stub"
|
|
95
|
-
style="left:${i * w.pageWidth}px;width:${w.pageWidth}px"></div>`)}
|
|
96
|
-
${repeat(live, i => i, i => html`
|
|
97
|
-
<div class="page"
|
|
98
|
-
style="left:${i * w.pageWidth}px;width:${w.pageWidth}px">
|
|
99
|
-
${this.renderPage(i)}
|
|
100
|
-
</div>`)}
|
|
101
|
-
</div>
|
|
102
|
-
</div>`;
|
|
103
|
-
}
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
### CSS
|
|
107
|
-
```css
|
|
108
|
-
.scroller {
|
|
109
|
-
overflow-x: auto;
|
|
110
|
-
overflow-y: hidden;
|
|
111
|
-
contain: strict; /* requires explicit dimensions on .scroller */
|
|
112
|
-
scroll-snap-type: x mandatory;
|
|
113
|
-
/* scroll-snap-stop stays at its default `normal` so a fling can cross
|
|
114
|
-
many pages before resting. `always` would force one page per gesture. */
|
|
115
|
-
}
|
|
116
|
-
.sizer { position: relative; height: 100%; }
|
|
117
|
-
.snap-stub {
|
|
118
|
-
position: absolute; top: 0; height: 100%;
|
|
119
|
-
scroll-snap-align: start;
|
|
120
|
-
pointer-events: none;
|
|
121
|
-
contain: strict;
|
|
122
|
-
}
|
|
123
|
-
.page {
|
|
124
|
-
position: absolute; top: 0; height: 100%;
|
|
125
|
-
contain: content;
|
|
126
|
-
content-visibility: auto;
|
|
127
|
-
contain-intrinsic-size: auto none;
|
|
128
|
-
}
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
### Landed-page reporting
|
|
132
|
-
```ts
|
|
133
|
-
const onEnd = () => {
|
|
134
|
-
this.currentPage = Math.round(el.scrollLeft / this.win.pageWidth);
|
|
135
|
-
};
|
|
136
|
-
if ('onscrollend' in window) {
|
|
137
|
-
el.addEventListener('scrollend', onEnd);
|
|
138
|
-
} else {
|
|
139
|
-
el.addEventListener('scroll', () => {
|
|
140
|
-
clearTimeout(this.endTimer);
|
|
141
|
-
this.endTimer = setTimeout(onEnd, 120);
|
|
142
|
-
}, {passive: true});
|
|
143
|
-
}
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
## Invariants — do not "optimize" these away
|
|
147
|
-
1. **The early-out in `recompute` must stay.** Scroll fires far more often than
|
|
148
|
-
the window changes. Re-render happens roughly once per page boundary
|
|
149
|
-
crossed, not once per scroll event.
|
|
150
|
-
2. **Keyed `repeat()`, keyed by page index.** Switching to `map()` re-renders
|
|
151
|
-
every live page on each window shift instead of creating one and removing one.
|
|
152
|
-
3. **Nothing reads layout in the scroll handler.** Viewport width comes from
|
|
153
|
-
`ResizeObserver` only. No `getBoundingClientRect` on the scroll path.
|
|
154
|
-
4. **Cells are plain DOM inside a page component.** Do not make each cell its
|
|
155
|
-
own custom element — element upgrade plus shadow-root creation will dominate
|
|
156
|
-
every other cost here.
|
|
157
|
-
|
|
158
|
-
## Snap targets
|
|
159
|
-
The browser re-evaluates its snap target continuously as a fling decelerates.
|
|
160
|
-
If the target box isn't mounted, or gets unmounted by a window shift
|
|
161
|
-
mid-fling, the result is a visible jump or a landing on the wrong boundary —
|
|
162
|
-
intermittent, and only on fast flings. The stubs decouple snap geometry from
|
|
163
|
-
virtualization: they always exist, so the geometry is always complete. Empty,
|
|
164
|
-
contained, childless divs cost very little.
|
|
165
|
-
|
|
166
|
-
If page count ever reaches the tens of thousands, flip to the alternative:
|
|
167
|
-
move `scroll-snap-align` onto `.page`, and defer *shrinking* the window until
|
|
168
|
-
`scrollend` so a selected target is never unmounted while scrolling.
|
|
169
|
-
|
|
170
|
-
## Rejected alternatives (with reasons — do not substitute)
|
|
171
|
-
- **`@lit-labs/virtualizer`** — works horizontally via
|
|
172
|
-
`flow({direction: 'horizontal'})`, but its value is measuring items of
|
|
173
|
-
unknown size, which is exactly what we don't need. Still 0.7.x under the
|
|
174
|
-
`@lit-labs` scope and self-described as late prerelease. Documented
|
|
175
|
-
Chromium flow-layout jank from correcting size estimates during smooth
|
|
176
|
-
scroll (maintainers say unfixable without replacing native scrolling with
|
|
177
|
-
JS scrolling), plus a Safari first-render transform bug
|
|
178
|
-
(https://github.com/lit/lit/issues/3243). Both stem from estimation.
|
|
179
|
-
- **TanStack Virtual** — good library, correct fallback *if column widths ever
|
|
180
|
-
become variable*. Unnecessary overhead while widths are uniform.
|
|
181
|
-
- **`content-visibility: auto` alone** — skips layout/paint for offscreen
|
|
182
|
-
pages but still creates all DOM. Used here as a second layer on top of
|
|
183
|
-
windowing, not as a replacement.
|
|
184
|
-
- **JS-animated `scrollLeft`** — the only way to control snap easing, but it
|
|
185
|
-
costs compositor-driven smoothness. Ship native snap first.
|
|
186
|
-
|
|
187
|
-
## Browser support notes
|
|
188
|
-
- Scroll snap: Baseline widely available since 2022 (Chrome 69, Firefox 68,
|
|
189
|
-
Safari 11).
|
|
190
|
-
- `scrollend`: Baseline since Dec 2025 (Chrome 114, Firefox 109, Safari 26.2).
|
|
191
|
-
Feature-detect with the timer fallback above if the support floor includes
|
|
192
|
-
older Safari.
|
|
193
|
-
- `content-visibility`: Baseline 2024 (Chrome 85, Firefox 125, Safari 18);
|
|
194
|
-
the web-features entry is more conservative about Safari. Treat as
|
|
195
|
-
progressive enhancement — unsupported browsers just render everything.
|
|
196
|
-
- `scrollsnapchanging` (fires when the browser decides where it *will* land,
|
|
197
|
-
useful for a live page indicator mid-fling): Chromium-only, Chrome 129+,
|
|
198
|
-
no Firefox or Safari. Optional enhancement over the `scrollend` path only.
|
|
199
|
-
|
|
200
|
-
## Acceptance criteria
|
|
201
|
-
- [ ] Scrolling the full dataset keeps live page elements at `2*buffer + visible`;
|
|
202
|
-
verify in DevTools that DOM node count stays flat.
|
|
203
|
-
- [ ] Performance profile during a sustained fling shows no layout thrash and
|
|
204
|
-
re-render count proportional to pages crossed, not scroll events.
|
|
205
|
-
- [ ] Release mid-page always eases to a page boundary — test slow drag, fast
|
|
206
|
-
fling across 50+ pages, trackpad, mouse wheel, and keyboard.
|
|
207
|
-
- [ ] Verified in Safari specifically (snap and first-render behavior).
|
|
208
|
-
- [ ] Resize recomputes `colsPerPage` and the window without losing position.
|
|
209
|
-
- [ ] `currentPage` is correct after every rest, including programmatic scrolls.
|
|
210
|
-
|
|
211
|
-
## Deferred
|
|
212
|
-
Page-element recycling (fixed slot pool, `pageIndex % N`, update data and
|
|
213
|
-
`left` in place). Only pursue if a profile shows element *creation* cost
|
|
214
|
-
during flings. Not needed up front.
|
package/eslint.config.mjs
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import typescriptEslint from '@typescript-eslint/eslint-plugin';
|
|
2
|
-
import html from 'eslint-plugin-html';
|
|
3
|
-
import tsParser from '@typescript-eslint/parser';
|
|
4
|
-
import path from 'node:path';
|
|
5
|
-
import { fileURLToPath } from 'node:url';
|
|
6
|
-
import js from '@eslint/js';
|
|
7
|
-
import { FlatCompat } from '@eslint/eslintrc';
|
|
8
|
-
|
|
9
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
10
|
-
const __dirname = path.dirname(__filename);
|
|
11
|
-
const compat = new FlatCompat({
|
|
12
|
-
baseDirectory: __dirname,
|
|
13
|
-
recommendedConfig: js.configs.recommended,
|
|
14
|
-
allConfig: js.configs.all,
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
export default [
|
|
18
|
-
...compat.extends('plugin:@typescript-eslint/recommended'),
|
|
19
|
-
{
|
|
20
|
-
plugins: {
|
|
21
|
-
'@typescript-eslint': typescriptEslint,
|
|
22
|
-
html,
|
|
23
|
-
},
|
|
24
|
-
|
|
25
|
-
languageOptions: {
|
|
26
|
-
parser: tsParser,
|
|
27
|
-
},
|
|
28
|
-
|
|
29
|
-
settings: {
|
|
30
|
-
'import/resolver': {
|
|
31
|
-
node: {
|
|
32
|
-
extensions: ['.ts', '.tsx'],
|
|
33
|
-
moduleDirectory: ['node_modules', 'src', 'demo'],
|
|
34
|
-
},
|
|
35
|
-
},
|
|
36
|
-
},
|
|
37
|
-
|
|
38
|
-
rules: {
|
|
39
|
-
'@typescript-eslint/no-unsafe-function-type': 'warn',
|
|
40
|
-
'@typescript-eslint/no-unused-vars': 'warn',
|
|
41
|
-
'@typescript-eslint/no-explicit-any': 'warn',
|
|
42
|
-
},
|
|
43
|
-
},
|
|
44
|
-
{
|
|
45
|
-
ignores: ['**/*.js', '**/*.mjs', '**/*.d.ts'],
|
|
46
|
-
},
|
|
47
|
-
{
|
|
48
|
-
files: ['**/*.test.ts'],
|
|
49
|
-
rules: {
|
|
50
|
-
'@typescript-eslint/no-unused-expressions': 'off',
|
|
51
|
-
},
|
|
52
|
-
},
|
|
53
|
-
];
|
package/index.html
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
<!doctype html>
|
|
2
|
-
<html lang="en-GB">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="utf-8">
|
|
5
|
-
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
6
|
-
<style>
|
|
7
|
-
html {
|
|
8
|
-
font-size: 10px; /* This is to match petabox's base font size */
|
|
9
|
-
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
body {
|
|
13
|
-
background: #F5F5F7;
|
|
14
|
-
color: #2C2C2C;
|
|
15
|
-
line-height: 1.42857143; /* Same as production */
|
|
16
|
-
}
|
|
17
|
-
</style>
|
|
18
|
-
|
|
19
|
-
</head>
|
|
20
|
-
<body>
|
|
21
|
-
<app-root></app-root>
|
|
22
|
-
<script type="module" src="./src/app-root"></script>
|
|
23
|
-
</body>
|
|
24
|
-
</html>
|
package/index.ts
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
export { CollectionBrowser } from './src/collection-browser';
|
|
2
|
-
export { CollectionBrowserDataSource } from './src/data-source/collection-browser-data-source';
|
|
3
|
-
export { CollectionBrowserDataSourceInterface } from './src/data-source/collection-browser-data-source-interface';
|
|
4
|
-
export { CollectionBrowserQueryState } from './src/data-source/collection-browser-query-state';
|
|
5
|
-
export { SortFilterBar } from './src/sort-filter-bar/sort-filter-bar';
|
|
6
|
-
export {
|
|
7
|
-
CollectionDisplayMode,
|
|
8
|
-
SortField,
|
|
9
|
-
TileModel,
|
|
10
|
-
FacetOption,
|
|
11
|
-
SelectedFacets,
|
|
12
|
-
getDefaultSelectedFacets,
|
|
13
|
-
} from './src/models';
|
|
14
|
-
export { CollectionBrowserLoadingTile } from './src/tiles/collection-browser-loading-tile';
|
|
15
|
-
export { CollectionTile } from './src/tiles/grid/collection-tile';
|
|
16
|
-
export { AccountTile } from './src/tiles/grid/account-tile';
|
|
17
|
-
export { ItemTile } from './src/tiles/grid/item-tile';
|
|
18
|
-
export { TileList } from './src/tiles/list/tile-list';
|
|
19
|
-
export { TileListCompact } from './src/tiles/list/tile-list-compact';
|
|
20
|
-
export { TileDispatcher } from './src/tiles/tile-dispatcher';
|
|
21
|
-
export { LayoutType } from './src/tiles/models';
|
|
22
|
-
export type { TileAction } from './src/tiles/models';
|
|
23
|
-
export {
|
|
24
|
-
SmartQueryHeuristic,
|
|
25
|
-
KeywordFacetMap,
|
|
26
|
-
SmartFacet,
|
|
27
|
-
} from './src/collection-facets/smart-facets/models';
|
|
28
|
-
export * from './src/collection-facets/smart-facets/heuristics/index';
|
|
29
|
-
export { SmartQueryHeuristicGroup } from './src/collection-facets/smart-facets/smart-facet-heuristics';
|