@internetarchive/collection-browser 0.0.1-alpha.7 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (238) hide show
  1. package/README.md +8 -11
  2. package/demo/app-root.ts +30 -96
  3. package/dist/demo/app-root.d.ts +3 -5
  4. package/dist/demo/app-root.js +28 -87
  5. package/dist/demo/app-root.js.map +1 -1
  6. package/dist/index.d.ts +6 -0
  7. package/dist/index.js +6 -0
  8. package/dist/index.js.map +1 -1
  9. package/dist/src/assets/img/icons/chevron.d.ts +2 -0
  10. package/dist/src/assets/img/icons/chevron.js +4 -0
  11. package/dist/src/assets/img/icons/chevron.js.map +1 -0
  12. package/dist/src/assets/img/icons/eye-closed.d.ts +2 -0
  13. package/dist/src/assets/img/icons/eye-closed.js +5 -0
  14. package/dist/src/assets/img/icons/eye-closed.js.map +1 -0
  15. package/dist/src/assets/img/icons/eye.d.ts +2 -0
  16. package/dist/src/assets/img/icons/eye.js +5 -0
  17. package/dist/src/assets/img/icons/eye.js.map +1 -0
  18. package/dist/src/assets/img/icons/mediatype/account.d.ts +1 -2
  19. package/dist/src/assets/img/icons/mediatype/account.js +6 -4
  20. package/dist/src/assets/img/icons/mediatype/account.js.map +1 -1
  21. package/dist/src/assets/img/icons/mediatype/audio.js +7 -4
  22. package/dist/src/assets/img/icons/mediatype/audio.js.map +1 -1
  23. package/dist/src/assets/img/icons/mediatype/collection.js +7 -4
  24. package/dist/src/assets/img/icons/mediatype/collection.js.map +1 -1
  25. package/dist/src/assets/img/icons/mediatype/data.d.ts +1 -0
  26. package/dist/src/assets/img/icons/mediatype/data.js +15 -0
  27. package/dist/src/assets/img/icons/mediatype/data.js.map +1 -0
  28. package/dist/src/assets/img/icons/mediatype/etree.js +10 -5
  29. package/dist/src/assets/img/icons/mediatype/etree.js.map +1 -1
  30. package/dist/src/assets/img/icons/mediatype/film.js +2 -1
  31. package/dist/src/assets/img/icons/mediatype/film.js.map +1 -1
  32. package/dist/src/assets/img/icons/mediatype/images.js +9 -6
  33. package/dist/src/assets/img/icons/mediatype/images.js.map +1 -1
  34. package/dist/src/assets/img/icons/mediatype/radio.d.ts +1 -0
  35. package/dist/src/assets/img/icons/mediatype/radio.js +15 -0
  36. package/dist/src/assets/img/icons/mediatype/radio.js.map +1 -0
  37. package/dist/src/assets/img/icons/mediatype/software.js +9 -6
  38. package/dist/src/assets/img/icons/mediatype/software.js.map +1 -1
  39. package/dist/src/assets/img/icons/mediatype/texts.js +9 -6
  40. package/dist/src/assets/img/icons/mediatype/texts.js.map +1 -1
  41. package/dist/src/assets/img/icons/mediatype/tv.js +10 -5
  42. package/dist/src/assets/img/icons/mediatype/tv.js.map +1 -1
  43. package/dist/src/assets/img/icons/mediatype/video.js +10 -6
  44. package/dist/src/assets/img/icons/mediatype/video.js.map +1 -1
  45. package/dist/src/assets/img/icons/mediatype/web.js +9 -6
  46. package/dist/src/assets/img/icons/mediatype/web.js.map +1 -1
  47. package/dist/src/collection-browser.d.ts +57 -20
  48. package/dist/src/collection-browser.js +511 -128
  49. package/dist/src/collection-browser.js.map +1 -1
  50. package/dist/src/collection-facets.d.ts +27 -6
  51. package/dist/src/collection-facets.js +316 -100
  52. package/dist/src/collection-facets.js.map +1 -1
  53. package/dist/src/language-code-handler/language-code-handler.d.ts +37 -0
  54. package/dist/src/language-code-handler/language-code-handler.js +27 -0
  55. package/dist/src/language-code-handler/language-code-handler.js.map +1 -0
  56. package/dist/src/language-code-handler/language-code-mapping.d.ts +1 -0
  57. package/dist/src/language-code-handler/language-code-mapping.js +563 -0
  58. package/dist/src/language-code-handler/language-code-mapping.js.map +1 -0
  59. package/dist/src/mediatype/mediatype-config.d.ts +3 -0
  60. package/dist/src/mediatype/mediatype-config.js +86 -0
  61. package/dist/src/mediatype/mediatype-config.js.map +1 -0
  62. package/dist/src/models.d.ts +72 -13
  63. package/dist/src/models.js +57 -1
  64. package/dist/src/models.js.map +1 -1
  65. package/dist/src/restoration-state-handler.d.ts +38 -0
  66. package/dist/src/restoration-state-handler.js +204 -0
  67. package/dist/src/restoration-state-handler.js.map +1 -0
  68. package/dist/src/sort-filter-bar/alpha-bar.d.ts +1 -2
  69. package/dist/src/sort-filter-bar/alpha-bar.js +12 -8
  70. package/dist/src/sort-filter-bar/alpha-bar.js.map +1 -1
  71. package/dist/src/sort-filter-bar/img/compact.d.ts +1 -0
  72. package/dist/src/sort-filter-bar/img/compact.js +5 -0
  73. package/dist/src/sort-filter-bar/img/compact.js.map +1 -0
  74. package/dist/src/sort-filter-bar/img/list.d.ts +1 -0
  75. package/dist/src/sort-filter-bar/img/list.js +5 -0
  76. package/dist/src/sort-filter-bar/img/list.js.map +1 -0
  77. package/dist/src/sort-filter-bar/img/sort-triangle.d.ts +1 -0
  78. package/dist/src/sort-filter-bar/img/sort-triangle.js +5 -0
  79. package/dist/src/sort-filter-bar/img/sort-triangle.js.map +1 -0
  80. package/dist/src/sort-filter-bar/img/tile.d.ts +1 -0
  81. package/dist/src/sort-filter-bar/img/tile.js +5 -0
  82. package/dist/src/sort-filter-bar/img/tile.js.map +1 -0
  83. package/dist/src/sort-filter-bar/sort-filter-bar.d.ts +74 -13
  84. package/dist/src/sort-filter-bar/sort-filter-bar.js +547 -172
  85. package/dist/src/sort-filter-bar/sort-filter-bar.js.map +1 -1
  86. package/dist/src/tiles/{loading-tile.d.ts → collection-browser-loading-tile.d.ts} +1 -1
  87. package/dist/src/tiles/collection-browser-loading-tile.js +32 -0
  88. package/dist/src/tiles/collection-browser-loading-tile.js.map +1 -0
  89. package/dist/src/tiles/grid/account-tile.d.ts +1 -1
  90. package/dist/src/tiles/grid/account-tile.js +5 -5
  91. package/dist/src/tiles/grid/account-tile.js.map +1 -1
  92. package/dist/src/tiles/grid/collection-tile.js +1 -2
  93. package/dist/src/tiles/grid/collection-tile.js.map +1 -1
  94. package/dist/src/tiles/grid/icons/views.d.ts +1 -1
  95. package/dist/src/tiles/grid/icons/views.js +2 -2
  96. package/dist/src/tiles/grid/icons/views.js.map +1 -1
  97. package/dist/src/tiles/grid/item-tile.d.ts +2 -2
  98. package/dist/src/tiles/grid/item-tile.js +58 -150
  99. package/dist/src/tiles/grid/item-tile.js.map +1 -1
  100. package/dist/src/tiles/item-image.d.ts +19 -0
  101. package/dist/src/tiles/item-image.js +204 -0
  102. package/dist/src/tiles/item-image.js.map +1 -0
  103. package/dist/src/tiles/list/account-label.d.ts +1 -0
  104. package/dist/src/tiles/list/account-label.js +7 -0
  105. package/dist/src/tiles/list/account-label.js.map +1 -0
  106. package/dist/src/tiles/list/date-label.d.ts +1 -0
  107. package/dist/src/tiles/list/date-label.js +13 -0
  108. package/dist/src/tiles/list/date-label.js.map +1 -0
  109. package/dist/src/tiles/list/tile-list-compact-header.d.ts +12 -0
  110. package/dist/src/tiles/list/tile-list-compact-header.js +84 -0
  111. package/dist/src/tiles/list/tile-list-compact-header.js.map +1 -0
  112. package/dist/src/tiles/list/tile-list-compact.d.ts +12 -0
  113. package/dist/src/tiles/list/tile-list-compact.js +203 -6
  114. package/dist/src/tiles/list/tile-list-compact.js.map +1 -1
  115. package/dist/src/tiles/list/tile-list.d.ts +35 -10
  116. package/dist/src/tiles/list/tile-list.js +368 -104
  117. package/dist/src/tiles/list/tile-list.js.map +1 -1
  118. package/dist/src/{mediatype-icon.d.ts → tiles/mediatype-icon.d.ts} +2 -2
  119. package/dist/src/tiles/mediatype-icon.js +78 -0
  120. package/dist/src/tiles/mediatype-icon.js.map +1 -0
  121. package/dist/src/tiles/tile-dispatcher.d.ts +11 -4
  122. package/dist/src/tiles/tile-dispatcher.js +56 -19
  123. package/dist/src/tiles/tile-dispatcher.js.map +1 -1
  124. package/dist/src/utils/format-date.js +2 -2
  125. package/dist/src/utils/format-date.js.map +1 -1
  126. package/dist/test/collection-browser.test.d.ts +1 -0
  127. package/dist/test/collection-browser.test.js +16 -2
  128. package/dist/test/collection-browser.test.js.map +1 -1
  129. package/dist/test/{utils/format-string.test.d.ts → mediatype-config.test.d.ts} +0 -0
  130. package/dist/test/mediatype-config.test.js +17 -0
  131. package/dist/test/mediatype-config.test.js.map +1 -0
  132. package/dist/test/utils/format-date.test.js +1 -1
  133. package/dist/test/utils/format-date.test.js.map +1 -1
  134. package/index.ts +6 -0
  135. package/local.archive.org.cert +86 -0
  136. package/local.archive.org.key +27 -0
  137. package/package.json +9 -5
  138. package/src/assets/img/icons/chevron.ts +4 -0
  139. package/src/assets/img/icons/eye-closed.ts +5 -0
  140. package/src/assets/img/icons/eye.ts +5 -0
  141. package/src/assets/img/icons/mediatype/account.ts +6 -4
  142. package/src/assets/img/icons/mediatype/audio.ts +7 -4
  143. package/src/assets/img/icons/mediatype/collection.ts +7 -4
  144. package/src/assets/img/icons/mediatype/data.ts +15 -0
  145. package/src/assets/img/icons/mediatype/etree.ts +10 -5
  146. package/src/assets/img/icons/mediatype/film.ts +2 -1
  147. package/src/assets/img/icons/mediatype/images.ts +9 -6
  148. package/src/assets/img/icons/mediatype/radio.ts +15 -0
  149. package/src/assets/img/icons/mediatype/software.ts +9 -6
  150. package/src/assets/img/icons/mediatype/texts.ts +9 -6
  151. package/src/assets/img/icons/mediatype/tv.ts +10 -5
  152. package/src/assets/img/icons/mediatype/video.ts +10 -6
  153. package/src/assets/img/icons/mediatype/web.ts +9 -6
  154. package/src/collection-browser.ts +537 -123
  155. package/src/collection-facets.ts +352 -132
  156. package/src/language-code-handler/language-code-handler.ts +64 -0
  157. package/src/language-code-handler/language-code-mapping.ts +564 -0
  158. package/src/mediatype/mediatype-config.ts +86 -0
  159. package/src/models.ts +141 -13
  160. package/src/restoration-state-handler.ts +266 -0
  161. package/src/sort-filter-bar/alpha-bar.ts +12 -8
  162. package/src/sort-filter-bar/img/compact.ts +5 -0
  163. package/src/sort-filter-bar/img/list.ts +5 -0
  164. package/src/sort-filter-bar/img/sort-triangle.ts +5 -0
  165. package/src/sort-filter-bar/img/tile.ts +5 -0
  166. package/src/sort-filter-bar/sort-filter-bar.ts +604 -176
  167. package/src/tiles/collection-browser-loading-tile.ts +29 -0
  168. package/src/tiles/grid/account-tile.ts +1 -1
  169. package/src/tiles/grid/collection-tile.ts +1 -2
  170. package/src/tiles/grid/icons/views.ts +2 -2
  171. package/src/tiles/grid/item-tile.ts +57 -162
  172. package/src/tiles/item-image.ts +206 -0
  173. package/src/tiles/list/account-label.ts +6 -0
  174. package/src/tiles/list/date-label.ts +12 -0
  175. package/src/tiles/list/tile-list-compact-header.ts +77 -0
  176. package/src/tiles/list/tile-list-compact.ts +218 -0
  177. package/src/tiles/list/tile-list.ts +412 -107
  178. package/src/tiles/mediatype-icon.ts +75 -0
  179. package/src/tiles/tile-dispatcher.ts +66 -18
  180. package/src/utils/format-date.ts +2 -2
  181. package/test/collection-browser.test.ts +20 -1
  182. package/test/mediatype-config.test.ts +18 -0
  183. package/test/utils/format-date.test.ts +1 -1
  184. package/web-dev-server.config.mjs +3 -1
  185. package/dist/src/assets/img/icons/audio.d.ts +0 -1
  186. package/dist/src/assets/img/icons/audio.js +0 -9
  187. package/dist/src/assets/img/icons/audio.js.map +0 -1
  188. package/dist/src/assets/img/icons/collection.d.ts +0 -1
  189. package/dist/src/assets/img/icons/collection.js +0 -9
  190. package/dist/src/assets/img/icons/collection.js.map +0 -1
  191. package/dist/src/assets/img/icons/etree.d.ts +0 -1
  192. package/dist/src/assets/img/icons/etree.js +0 -9
  193. package/dist/src/assets/img/icons/etree.js.map +0 -1
  194. package/dist/src/assets/img/icons/images.d.ts +0 -1
  195. package/dist/src/assets/img/icons/images.js +0 -10
  196. package/dist/src/assets/img/icons/images.js.map +0 -1
  197. package/dist/src/assets/img/icons/mediatype/etree copy.d.ts +0 -1
  198. package/dist/src/assets/img/icons/mediatype/etree copy.js +0 -9
  199. package/dist/src/assets/img/icons/mediatype/etree copy.js.map +0 -1
  200. package/dist/src/assets/img/icons/mediatype/livemusic.d.ts +0 -1
  201. package/dist/src/assets/img/icons/mediatype/livemusic.js +0 -7
  202. package/dist/src/assets/img/icons/mediatype/livemusic.js.map +0 -1
  203. package/dist/src/assets/img/icons/mediatype/photos.d.ts +0 -1
  204. package/dist/src/assets/img/icons/mediatype/photos.js +0 -7
  205. package/dist/src/assets/img/icons/mediatype/photos.js.map +0 -1
  206. package/dist/src/assets/img/icons/software.d.ts +0 -1
  207. package/dist/src/assets/img/icons/software.js +0 -10
  208. package/dist/src/assets/img/icons/software.js.map +0 -1
  209. package/dist/src/assets/img/icons/texts.d.ts +0 -1
  210. package/dist/src/assets/img/icons/texts.js +0 -10
  211. package/dist/src/assets/img/icons/texts.js.map +0 -1
  212. package/dist/src/assets/img/icons/tv.d.ts +0 -1
  213. package/dist/src/assets/img/icons/tv.js +0 -9
  214. package/dist/src/assets/img/icons/tv.js.map +0 -1
  215. package/dist/src/assets/img/icons/video.d.ts +0 -1
  216. package/dist/src/assets/img/icons/video.js +0 -10
  217. package/dist/src/assets/img/icons/video.js.map +0 -1
  218. package/dist/src/assets/img/icons/web.d.ts +0 -1
  219. package/dist/src/assets/img/icons/web.js +0 -10
  220. package/dist/src/assets/img/icons/web.js.map +0 -1
  221. package/dist/src/mediatype-icon.js +0 -89
  222. package/dist/src/mediatype-icon.js.map +0 -1
  223. package/dist/src/search-handler.d.ts +0 -11
  224. package/dist/src/search-handler.js +0 -34
  225. package/dist/src/search-handler.js.map +0 -1
  226. package/dist/src/tiles/list/tile-list-detail.d.ts +0 -7
  227. package/dist/src/tiles/list/tile-list-detail.js +0 -28
  228. package/dist/src/tiles/list/tile-list-detail.js.map +0 -1
  229. package/dist/src/tiles/loading-tile.js +0 -73
  230. package/dist/src/tiles/loading-tile.js.map +0 -1
  231. package/dist/src/utils/format-string.d.ts +0 -2
  232. package/dist/src/utils/format-string.js +0 -7
  233. package/dist/src/utils/format-string.js.map +0 -1
  234. package/dist/test/utils/format-string.test.js +0 -17
  235. package/dist/test/utils/format-string.test.js.map +0 -1
  236. package/src/assets/img/icons/mediatype/foo.svg +0 -5
  237. package/src/mediatype-icon.ts +0 -83
  238. package/src/tiles/loading-tile.ts +0 -70
@@ -1,121 +1,51 @@
1
1
  import { __decorate } from "tslib";
2
- import { SortParam } from '@internetarchive/search-service';
3
- import { LitElement, html, css, nothing } from 'lit';
4
- import { customElement, property, state } from 'lit/decorators.js';
2
+ import { LitElement, html, css, nothing, } from 'lit';
3
+ import { customElement, property, query, state } from 'lit/decorators.js';
4
+ import { SortField, SortFieldDisplayName, } from '../models';
5
5
  import './alpha-bar';
6
+ import { sortIcon } from './img/sort-triangle';
7
+ import { tileIcon } from './img/tile';
8
+ import { listIcon } from './img/list';
9
+ import { compactIcon } from './img/compact';
6
10
  let SortFilterBar = class SortFilterBar extends LitElement {
7
11
  constructor() {
8
12
  super(...arguments);
9
- this.displayMode = 'grid';
10
- this.sortDirection = 'desc';
11
- this.sortField = 'week';
12
- this.titleSelectorVisible = false;
13
- this.creatorSelectorVisible = false;
13
+ this.sortDirection = null;
14
+ this.selectedSort = SortField.relevance;
15
+ this.selectedTitleFilter = null;
16
+ this.selectedCreatorFilter = null;
17
+ this.showRelevance = true;
18
+ this.alphaSelectorVisible = null;
14
19
  this.dateSortSelectorVisible = false;
20
+ this.desktopSelectorBarWidth = 0;
21
+ this.selectorBarContainerWidth = 0;
22
+ this.hoveringOverDateSortOptions = false;
23
+ this.boundDateSelectorEscapeListener = (e) => {
24
+ if (e.key === 'Escape') {
25
+ this.dateSortSelectorVisible = false;
26
+ }
27
+ };
15
28
  }
16
29
  render() {
17
30
  return html `
18
31
  <div id="container">
19
32
  <div id="sort-bar">
20
- <div id="sort-selector">
21
- <ul>
22
- <li>
23
- <div id="sort-direction-container">
24
- <button
25
- class="sort-button"
26
- @click=${() => {
27
- this.sortDirection = 'asc';
28
- }}
29
- >
30
-
31
- </button>
32
- <button
33
- class="sort-button"
34
- @click=${() => {
35
- this.sortDirection = 'desc';
36
- }}
37
- >
38
-
39
- </button>
40
- </div>
41
- </li>
42
- <li>Sort By</li>
43
- <li>
44
- <a
45
- href="#"
46
- @click=${(e) => {
47
- e.preventDefault();
48
- this.sortField = 'week';
49
- }}
50
- >
51
- Views
52
- </a>
53
- </li>
54
- <li>
55
- <a
56
- href="#"
57
- @click=${(e) => {
58
- e.preventDefault();
59
- this.titleSelectorVisible = !this.titleSelectorVisible;
60
- this.sortField = 'titleSorter';
61
- }}
62
- >
63
- Title
64
- </a>
65
- </li>
66
- <li>
67
- <a
68
- href="#"
69
- @click=${(e) => {
70
- e.preventDefault();
71
- this.dateSortSelectorVisible =
72
- !this.dateSortSelectorVisible;
73
- }}
74
- >
75
- Date Archived
76
- </a>
77
- </li>
78
- <li>
79
- <a
80
- href="#"
81
- @click=${(e) => {
82
- e.preventDefault();
83
- this.creatorSelectorVisible = !this.creatorSelectorVisible;
84
- this.sortField = 'creatorSorter';
85
- }}
86
- >
87
- Creator
88
- </a>
89
- </li>
90
- </ul>
33
+ <div id="sort-direction-container">
34
+ ${this.sortDirectionSelectorTemplate}
91
35
  </div>
92
36
 
93
- <div id="display-style">
94
- <ul>
95
- ${this.displayMode !== 'grid'
96
- ? html `<li>
97
- <input type="checkbox" @click=${this.detailSelected} />
98
- Details
99
- </li>`
100
- : nothing}
101
-
102
- <li>
103
- <button id="grid-button" @click=${this.gridSelected}>
104
- Grid
105
- </button>
106
- </li>
107
- <li>
108
- <button id="list-button" @click=${this.listSelected}>
109
- List
110
- </button>
111
- </li>
112
- </ul>
37
+ <div id="sort-selector-container">
38
+ ${this.mobileSortSelectorTemplate}
39
+ ${this.desktopSortSelectorTemplate}
113
40
  </div>
41
+
42
+ <div id="display-style-selector">${this.displayOptionTemplate}</div>
114
43
  </div>
115
44
 
116
- ${this.dateSortSelectorVisible ? this.dateSortSelector : nothing}
117
- ${this.titleSelectorVisible ? this.titleSelectorBar : nothing}
118
- ${this.creatorSelectorVisible ? this.creatorSelectorBar : nothing}
45
+ ${this.dateSortSelectorVisible && !this.mobileSelectorVisible
46
+ ? this.dateSortSelector
47
+ : nothing}
48
+ ${this.alphaBarTemplate}
119
49
 
120
50
  <div id="bottom-shadow"></div>
121
51
  </div>
@@ -125,106 +55,399 @@ let SortFilterBar = class SortFilterBar extends LitElement {
125
55
  if (changed.has('displayMode')) {
126
56
  this.displayModeChanged();
127
57
  }
128
- if (changed.has('sortDirection') || changed.has('sortField')) {
129
- this.sortChanged();
58
+ if (changed.has('selectedSort') && this.sortDirection === null) {
59
+ this.sortDirection = 'desc';
60
+ }
61
+ if (changed.has('selectedTitleFilter') && this.selectedTitleFilter) {
62
+ this.alphaSelectorVisible = 'title';
63
+ }
64
+ if (changed.has('selectedCreatorFilter') && this.selectedCreatorFilter) {
65
+ this.alphaSelectorVisible = 'creator';
66
+ }
67
+ if (changed.has('dateSortSelectorVisible')) {
68
+ this.setupEscapeListeners();
69
+ }
70
+ if (changed.has('resizeObserver')) {
71
+ const oldObserver = changed.get('resizeObserver');
72
+ if (oldObserver)
73
+ this.disconnectResizeObserver(oldObserver);
74
+ this.setupResizeObserver();
130
75
  }
131
76
  }
132
- get dateSortSelector() {
77
+ setupEscapeListeners() {
78
+ if (this.dateSortSelectorVisible) {
79
+ document.addEventListener('keydown', this.boundDateSelectorEscapeListener);
80
+ }
81
+ else {
82
+ document.removeEventListener('keydown', this.boundDateSelectorEscapeListener);
83
+ }
84
+ }
85
+ disconnectedCallback() {
86
+ if (this.resizeObserver) {
87
+ this.disconnectResizeObserver(this.resizeObserver);
88
+ }
89
+ }
90
+ disconnectResizeObserver(resizeObserver) {
91
+ resizeObserver.removeObserver({
92
+ target: this.sortSelectorContainer,
93
+ handler: this,
94
+ });
95
+ resizeObserver.removeObserver({
96
+ target: this.desktopSortSelector,
97
+ handler: this,
98
+ });
99
+ }
100
+ setupResizeObserver() {
101
+ if (!this.resizeObserver)
102
+ return;
103
+ this.resizeObserver.addObserver({
104
+ target: this.sortSelectorContainer,
105
+ handler: this,
106
+ });
107
+ this.resizeObserver.addObserver({
108
+ target: this.desktopSortSelector,
109
+ handler: this,
110
+ });
111
+ }
112
+ get mobileSelectorVisible() {
113
+ return this.selectorBarContainerWidth - 10 < this.desktopSelectorBarWidth;
114
+ }
115
+ get alphaBarTemplate() {
116
+ if (!['title', 'creator'].includes(this.selectedSort))
117
+ return nothing;
118
+ if (this.alphaSelectorVisible === null) {
119
+ if (this.selectedSort === 'creator')
120
+ return this.creatorSelectorBar;
121
+ if (this.selectedSort === 'title')
122
+ return this.titleSelectorBar;
123
+ }
124
+ else {
125
+ return this.alphaSelectorVisible === 'creator'
126
+ ? this.creatorSelectorBar
127
+ : this.titleSelectorBar;
128
+ }
129
+ return nothing;
130
+ }
131
+ handleResize(entry) {
132
+ if (entry.target === this.desktopSortSelector) {
133
+ this.desktopSelectorBarWidth = entry.contentRect.width;
134
+ }
135
+ else if (entry.target === this.sortSelectorContainer) {
136
+ this.selectorBarContainerWidth = entry.contentRect.width;
137
+ }
138
+ }
139
+ get sortDirectionSelectorTemplate() {
133
140
  return html `
134
- <div id="date-sort-selector">
135
- <ul>
136
- <li>
137
- <button
138
- @click=${() => {
139
- this.sortField = 'publicdate';
141
+ <div id="sort-direction-selector">
142
+ <button
143
+ id="sort-ascending-btn"
144
+ class="sort-button ${this.sortDirection === 'asc' ? 'selected' : ''}"
145
+ ?disabled=${this.selectedSort === 'relevance'}
146
+ @click=${() => {
147
+ this.setSortDirections('asc');
148
+ }}
149
+ >
150
+ ${sortIcon}
151
+ </button>
152
+ <button
153
+ id="sort-descending-btn"
154
+ class="sort-button ${this.sortDirection === 'desc' ? 'selected' : ''}"
155
+ ?disabled=${this.selectedSort === 'relevance'}
156
+ @click=${() => {
157
+ this.setSortDirections('desc');
158
+ }}
159
+ >
160
+ ${sortIcon}
161
+ </button>
162
+ </div>
163
+ `;
164
+ }
165
+ get desktopSortSelectorTemplate() {
166
+ return html `
167
+ <ul
168
+ id="desktop-sort-selector"
169
+ class=${this.mobileSelectorVisible ? 'hidden' : 'visible'}
170
+ >
171
+ <li id="sort-by-text">Sort By</li>
172
+ <li>
173
+ ${this.showRelevance
174
+ ? this.getSortDisplayOption(SortField.relevance)
175
+ : nothing}
176
+ </li>
177
+ <li>${this.getSortDisplayOption(SortField.views)}</li>
178
+ <li>
179
+ ${this.getSortDisplayOption(SortField.title, {
180
+ clickEvent: () => {
181
+ this.alphaSelectorVisible = 'title';
182
+ this.selectedCreatorFilter = null;
183
+ this.dateSortSelectorVisible = false;
184
+ this.setSelectedSort(SortField.title);
185
+ this.emitCreatorLetterChangedEvent();
186
+ },
187
+ })}
188
+ </li>
189
+ <li>
190
+ ${this.getSortDisplayOption(SortField.date, {
191
+ clickEvent: () => {
192
+ if (!this.dateOptionSelected)
193
+ this.setSelectedSort(SortField.date);
194
+ this.dateSortSelectorVisible = !this.dateSortSelectorVisible;
195
+ this.alphaSelectorVisible = null;
196
+ this.selectedTitleFilter = null;
197
+ this.selectedCreatorFilter = null;
198
+ this.emitTitleLetterChangedEvent();
199
+ this.emitCreatorLetterChangedEvent();
200
+ },
201
+ displayName: html `${this.dateSortField}`,
202
+ isSelected: () => this.dateOptionSelected,
203
+ })}
204
+ </li>
205
+ <li>
206
+ ${this.getSortDisplayOption(SortField.creator, {
207
+ clickEvent: () => {
208
+ this.alphaSelectorVisible = 'creator';
209
+ this.selectedTitleFilter = null;
210
+ this.dateSortSelectorVisible = false;
211
+ this.setSelectedSort(SortField.creator);
212
+ this.emitTitleLetterChangedEvent();
213
+ },
214
+ })}
215
+ </li>
216
+ </ul>
217
+ `;
218
+ }
219
+ /**
220
+ * This generates each of the sort option links.
221
+ *
222
+ * It manages the display value and the selected state of the option.
223
+ *
224
+ * @param sortField
225
+ * @param options {
226
+ * additionalClickEvent?: () => void; If this is provided, it will also be called when the option is clicked.
227
+ * displayName?: TemplateResult; The name to display for the option. Defaults to the sortField display name.
228
+ * isSelected?: () => boolean; A function that returns true if the option is selected. Defaults to the selectedSort === sortField.
229
+ * }
230
+ * @returns
231
+ */
232
+ getSortDisplayOption(sortField, options) {
233
+ var _a, _b;
234
+ const isSelected = (_a = options === null || options === void 0 ? void 0 : options.isSelected) !== null && _a !== void 0 ? _a : (() => this.selectedSort === sortField);
235
+ const displayName = (_b = options === null || options === void 0 ? void 0 : options.displayName) !== null && _b !== void 0 ? _b : SortFieldDisplayName[sortField];
236
+ return html `
237
+ <a
238
+ href="#"
239
+ @click=${(e) => {
240
+ e.preventDefault();
241
+ if (options === null || options === void 0 ? void 0 : options.clickEvent) {
242
+ options.clickEvent(e);
243
+ }
244
+ else {
245
+ this.alphaSelectorVisible = null;
246
+ this.dateSortSelectorVisible = false;
247
+ this.selectedTitleFilter = null;
248
+ this.selectedCreatorFilter = null;
249
+ this.setSelectedSort(sortField);
250
+ this.emitTitleLetterChangedEvent();
251
+ this.emitCreatorLetterChangedEvent();
252
+ }
140
253
  }}
141
- >
142
- Date Archived
143
- </button>
144
- </li>
145
- <li>
146
- <button
147
- @click=${() => {
148
- this.sortField = 'date';
254
+ class=${isSelected() ? 'selected' : ''}
255
+ >
256
+ ${displayName}
257
+ </a>
258
+ `;
259
+ }
260
+ get mobileSortSelectorTemplate() {
261
+ return html `
262
+ <select
263
+ id="mobile-sort-selector"
264
+ @change=${this.mobileSortChanged}
265
+ class=${this.mobileSelectorVisible ? 'visible' : 'hidden'}
266
+ >
267
+ ${Object.keys(SortField).map(field => html `
268
+ <option value="${field}" ?selected=${this.selectedSort === field}>
269
+ ${SortFieldDisplayName[field]}
270
+ </option>
271
+ `)}
272
+ </select>
273
+ `;
274
+ }
275
+ mobileSortChanged(e) {
276
+ const target = e.target;
277
+ this.setSelectedSort(target.value);
278
+ }
279
+ get displayOptionTemplate() {
280
+ return html `
281
+ <ul>
282
+ <li>
283
+ <button
284
+ id="grid-button"
285
+ @click=${() => {
286
+ this.displayMode = 'grid';
149
287
  }}
150
- >
151
- Date Published
152
- </button>
153
- </li>
154
- <li>
155
- <button
156
- @click=${() => {
157
- this.sortField = 'reviewdate';
288
+ class=${this.displayMode === 'grid' ? 'active' : ''}
289
+ >
290
+ ${tileIcon}
291
+ </button>
292
+ </li>
293
+ <li>
294
+ <button
295
+ id="grid-button"
296
+ @click=${() => {
297
+ this.displayMode = 'list-detail';
158
298
  }}
159
- >
160
- Date Reviewed
161
- </button>
162
- </li>
163
- <li>
164
- <button
165
- @click=${() => {
166
- this.sortField = 'addeddate';
299
+ class=${this.displayMode === 'list-detail' ? 'active' : ''}
300
+ >
301
+ ${listIcon}
302
+ </button>
303
+ </li>
304
+ <li>
305
+ <button
306
+ id="list-button"
307
+ @click=${() => {
308
+ this.displayMode = 'list-compact';
167
309
  }}
168
- >
169
- Date Added
170
- </button>
171
- </li>
310
+ class=${this.displayMode === 'list-compact' ? 'active' : ''}
311
+ >
312
+ ${compactIcon}
313
+ </button>
314
+ </li>
315
+ </ul>
316
+ `;
317
+ }
318
+ get dateSortSelector() {
319
+ return html `
320
+ <div
321
+ id="date-sort-selector-backdrop"
322
+ @keyup=${() => {
323
+ this.dateSortSelectorVisible = false;
324
+ }}
325
+ @click=${() => {
326
+ this.dateSortSelectorVisible = false;
327
+ }}
328
+ ></div>
329
+ <div id="date-sort-selector">
330
+ <ul>
331
+ <li>${this.getDateSortButton(SortField.datearchived)}</li>
332
+ <li>${this.getDateSortButton(SortField.date)}</li>
333
+ <li>${this.getDateSortButton(SortField.datereviewed)}</li>
334
+ <li>${this.getDateSortButton(SortField.dateadded)}</li>
172
335
  </ul>
173
336
  </div>
174
337
  `;
175
338
  }
339
+ getDateSortButton(sortField) {
340
+ return html `
341
+ <button
342
+ @click=${() => {
343
+ this.selectDateSort(sortField);
344
+ }}
345
+ class=${this.selectedSort === sortField ? 'selected' : ''}
346
+ >
347
+ ${SortFieldDisplayName[sortField]}
348
+ </button>
349
+ `;
350
+ }
351
+ selectDateSort(sortField) {
352
+ this.dateSortSelectorVisible = false;
353
+ this.setSelectedSort(sortField);
354
+ }
355
+ setSortDirections(sortDirection) {
356
+ this.sortDirection = sortDirection;
357
+ this.emitSortChangedEvent();
358
+ }
359
+ setSelectedSort(sort) {
360
+ this.selectedSort = sort;
361
+ this.emitSortChangedEvent();
362
+ }
363
+ /**
364
+ * There are four date sort options.
365
+ *
366
+ * This checks to see if the current sort is one of them.
367
+ *
368
+ * @readonly
369
+ * @private
370
+ * @type {boolean}
371
+ * @memberof SortFilterBar
372
+ */
373
+ get dateOptionSelected() {
374
+ const dateSortFields = [
375
+ SortField.datearchived,
376
+ SortField.date,
377
+ SortField.datereviewed,
378
+ SortField.dateadded,
379
+ ];
380
+ return dateSortFields.includes(this.selectedSort);
381
+ }
382
+ /**
383
+ * The display name of the current date field
384
+ *
385
+ * @readonly
386
+ * @private
387
+ * @type {string}
388
+ * @memberof SortFilterBar
389
+ */
390
+ get dateSortField() {
391
+ var _a;
392
+ const defaultSort = SortFieldDisplayName[SortField.date];
393
+ const name = this.dateOptionSelected
394
+ ? (_a = SortFieldDisplayName[this.selectedSort]) !== null && _a !== void 0 ? _a : defaultSort
395
+ : defaultSort;
396
+ return name;
397
+ }
176
398
  get titleSelectorBar() {
177
399
  return html ` <alpha-bar
178
- headline="Title Starts With"
400
+ .selectedLetter=${this.selectedTitleFilter}
179
401
  @letterChanged=${this.titleLetterChanged}
180
402
  ></alpha-bar>`;
181
403
  }
182
404
  get creatorSelectorBar() {
183
405
  return html ` <alpha-bar
184
- headline="Creator Starts With"
406
+ .selectedLetter=${this.selectedCreatorFilter}
185
407
  @letterChanged=${this.creatorLetterChanged}
186
408
  ></alpha-bar>`;
187
409
  }
188
410
  titleLetterChanged(e) {
411
+ var _a;
412
+ this.selectedTitleFilter = (_a = e.detail.selectedLetter) !== null && _a !== void 0 ? _a : null;
413
+ this.emitTitleLetterChangedEvent();
414
+ }
415
+ creatorLetterChanged(e) {
416
+ var _a;
417
+ this.selectedCreatorFilter = (_a = e.detail.selectedLetter) !== null && _a !== void 0 ? _a : null;
418
+ this.emitCreatorLetterChangedEvent();
419
+ }
420
+ emitTitleLetterChangedEvent() {
189
421
  const event = new CustomEvent('titleLetterChanged', {
190
- detail: { selectedLetter: e.detail.selectedLetter },
422
+ detail: { selectedLetter: this.selectedTitleFilter },
191
423
  });
192
424
  this.dispatchEvent(event);
193
425
  }
194
- creatorLetterChanged(e) {
426
+ emitCreatorLetterChangedEvent() {
195
427
  const event = new CustomEvent('creatorLetterChanged', {
196
- detail: { selectedLetter: e.detail.selectedLetter },
428
+ detail: { selectedLetter: this.selectedCreatorFilter },
197
429
  });
198
430
  this.dispatchEvent(event);
199
431
  }
200
- gridSelected() {
201
- this.displayMode = 'grid';
202
- }
203
- listSelected() {
204
- this.displayMode = 'list-compact';
205
- }
206
- detailSelected(e) {
207
- this.displayMode = e.target.checked
208
- ? 'list-detail'
209
- : 'list-compact';
210
- }
211
432
  displayModeChanged() {
212
433
  const event = new CustomEvent('displayModeChanged', {
213
434
  detail: { displayMode: this.displayMode },
214
435
  });
215
436
  this.dispatchEvent(event);
216
437
  }
217
- sortChanged() {
218
- const sort = new SortParam(this.sortField, this.sortDirection);
438
+ emitSortChangedEvent() {
219
439
  const event = new CustomEvent('sortChanged', {
220
- detail: { sort },
440
+ detail: {
441
+ selectedSort: this.selectedSort,
442
+ sortDirection: this.sortDirection,
443
+ },
221
444
  });
222
445
  this.dispatchEvent(event);
223
446
  }
224
447
  };
225
448
  SortFilterBar.styles = css `
226
449
  #container {
227
- margin: 0 1rem 2.5rem 1rem;
450
+ position: relative;
228
451
  }
229
452
 
230
453
  #sort-bar {
@@ -232,7 +455,15 @@ SortFilterBar.styles = css `
232
455
  justify-content: space-between;
233
456
  border: 1px solid rgb(232, 232, 232);
234
457
  align-items: center;
235
- padding: 0.1rem 0.5rem;
458
+ padding: 0.5rem 1.5rem;
459
+ }
460
+
461
+ #sort-direction-container {
462
+ flex: 0;
463
+ }
464
+
465
+ #sort-by-text {
466
+ text-transform: uppercase;
236
467
  }
237
468
 
238
469
  #bottom-shadow {
@@ -251,7 +482,7 @@ SortFilterBar.styles = css `
251
482
  }
252
483
 
253
484
  li {
254
- padding: 0.5rem 0 0.5rem 0;
485
+ padding: 0;
255
486
  }
256
487
 
257
488
  .sort-button {
@@ -259,41 +490,161 @@ SortFilterBar.styles = css `
259
490
  color: inherit;
260
491
  border: none;
261
492
  padding: 0;
262
- font: inherit;
263
493
  cursor: pointer;
264
494
  outline: inherit;
495
+ width: 12px;
496
+ height: 12px;
497
+ opacity: 0.5;
265
498
  }
266
499
 
267
- #sort-direction-container {
500
+ .sort-button.selected {
501
+ opacity: 1;
502
+ }
503
+
504
+ .sort-button:disabled {
505
+ opacity: 0.25;
506
+ cursor: default;
507
+ }
508
+
509
+ #date-sort-selector {
510
+ position: absolute;
511
+ left: 150px;
512
+ top: 45px;
513
+
514
+ z-index: 1;
515
+ padding: 1rem;
516
+ background-color: white;
517
+ border-radius: 2.5rem;
518
+ border: 1px solid #404142;
519
+ }
520
+
521
+ #date-sort-selector button {
522
+ background: none;
523
+ border-radius: 15px;
524
+ color: #404142;
525
+ border: none;
526
+ appearance: none;
527
+ cursor: pointer;
528
+ -webkit-appearance: none;
529
+ font-size: 1.4rem;
530
+ font-weight: 400;
531
+ padding: 0.5rem 1.2rem;
532
+ }
533
+
534
+ #date-sort-selector button.selected {
535
+ background-color: #404142;
536
+ color: white;
537
+ }
538
+
539
+ #show-details {
540
+ text-transform: uppercase;
541
+ cursor: pointer;
542
+ display: flex;
543
+ }
544
+
545
+ #show-details input {
546
+ margin-right: 0.5rem;
547
+ flex: 0 0 12px;
548
+ }
549
+
550
+ #sort-descending-btn {
551
+ transform: rotate(180deg);
552
+ }
553
+
554
+ #sort-direction-selector {
268
555
  display: flex;
269
556
  flex-direction: column;
557
+ gap: 3px;
558
+ margin-right: 1rem;
270
559
  }
271
560
 
272
- #sort-selector li {
561
+ #sort-selector-container {
562
+ flex: 1;
563
+ }
564
+
565
+ /*
566
+ we move the desktop sort selector offscreen instead of display: none
567
+ because we need to observe the width of it vs its container to determine
568
+ if it's wide enough to display the desktop version and if you displY: none,
569
+ the width becomes 0
570
+ */
571
+ #desktop-sort-selector.hidden {
572
+ position: absolute;
573
+ top: -9999px;
574
+ left: -9999px;
575
+ }
576
+
577
+ #mobile-sort-selector.hidden {
578
+ display: none;
579
+ }
580
+
581
+ #date-sort-selector-backdrop {
582
+ position: fixed;
583
+ top: 0;
584
+ left: 0;
585
+ width: 100%;
586
+ height: 100%;
587
+ z-index: 1;
588
+ background-color: rgba(255, 255, 255, 0.5);
589
+ }
590
+
591
+ #desktop-sort-selector {
592
+ display: inline-flex;
593
+ }
594
+
595
+ #desktop-sort-selector li {
273
596
  display: flex;
274
597
  align-items: center;
275
598
  }
276
599
 
277
- #sort-selector li a {
600
+ #desktop-sort-selector li a {
278
601
  text-decoration: none;
279
602
  text-transform: uppercase;
280
603
  font-size: 1.4rem;
281
604
  color: #333;
605
+ line-height: 2.5;
282
606
  }
283
607
 
284
- #sort-selector li::after {
608
+ #desktop-sort-selector li a.selected {
609
+ font-weight: bold;
610
+ }
611
+
612
+ #desktop-sort-selector li::after {
285
613
  content: '•';
286
614
  padding-left: 1rem;
287
615
  padding-right: 1rem;
288
616
  }
289
617
 
290
- #sort-selector li:first-child::after {
618
+ #desktop-sort-selector li:first-child::after {
291
619
  content: '';
292
620
  }
293
621
 
294
- #sort-selector li:last-child::after {
622
+ #desktop-sort-selector li:last-child::after {
295
623
  content: '';
296
624
  }
625
+
626
+ #display-style-selector {
627
+ flex: 0;
628
+ }
629
+
630
+ #display-style-selector button {
631
+ background: none;
632
+ color: inherit;
633
+ border: none;
634
+ appearance: none;
635
+ cursor: pointer;
636
+ -webkit-appearance: none;
637
+ opacity: 0.5;
638
+ }
639
+
640
+ #display-style-selector button.active {
641
+ opacity: 1;
642
+ }
643
+
644
+ #display-style-selector button svg {
645
+ width: 24px;
646
+ height: 24px;
647
+ }
297
648
  `;
298
649
  __decorate([
299
650
  property({ type: String })
@@ -303,16 +654,40 @@ __decorate([
303
654
  ], SortFilterBar.prototype, "sortDirection", void 0);
304
655
  __decorate([
305
656
  property({ type: String })
306
- ], SortFilterBar.prototype, "sortField", void 0);
657
+ ], SortFilterBar.prototype, "selectedSort", void 0);
307
658
  __decorate([
308
- state()
309
- ], SortFilterBar.prototype, "titleSelectorVisible", void 0);
659
+ property({ type: String })
660
+ ], SortFilterBar.prototype, "selectedTitleFilter", void 0);
661
+ __decorate([
662
+ property({ type: String })
663
+ ], SortFilterBar.prototype, "selectedCreatorFilter", void 0);
664
+ __decorate([
665
+ property({ type: Boolean })
666
+ ], SortFilterBar.prototype, "showRelevance", void 0);
667
+ __decorate([
668
+ property({ type: Object })
669
+ ], SortFilterBar.prototype, "resizeObserver", void 0);
310
670
  __decorate([
311
671
  state()
312
- ], SortFilterBar.prototype, "creatorSelectorVisible", void 0);
672
+ ], SortFilterBar.prototype, "alphaSelectorVisible", void 0);
313
673
  __decorate([
314
674
  state()
315
675
  ], SortFilterBar.prototype, "dateSortSelectorVisible", void 0);
676
+ __decorate([
677
+ state()
678
+ ], SortFilterBar.prototype, "desktopSelectorBarWidth", void 0);
679
+ __decorate([
680
+ state()
681
+ ], SortFilterBar.prototype, "selectorBarContainerWidth", void 0);
682
+ __decorate([
683
+ state()
684
+ ], SortFilterBar.prototype, "hoveringOverDateSortOptions", void 0);
685
+ __decorate([
686
+ query('#desktop-sort-selector')
687
+ ], SortFilterBar.prototype, "desktopSortSelector", void 0);
688
+ __decorate([
689
+ query('#sort-selector-container')
690
+ ], SortFilterBar.prototype, "sortSelectorContainer", void 0);
316
691
  SortFilterBar = __decorate([
317
692
  customElement('sort-filter-bar')
318
693
  ], SortFilterBar);