@internetarchive/collection-browser 4.3.0 → 4.3.1-alpha-webdev8257.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 (63) hide show
  1. package/dist/index.d.ts +1 -0
  2. package/dist/index.js.map +1 -1
  3. package/dist/src/app-root.d.ts +11 -0
  4. package/dist/src/app-root.js +107 -0
  5. package/dist/src/app-root.js.map +1 -1
  6. package/dist/src/collection-browser.d.ts +8 -4
  7. package/dist/src/collection-browser.js +19 -20
  8. package/dist/src/collection-browser.js.map +1 -1
  9. package/dist/src/data-source/collection-browser-data-source.js.map +1 -1
  10. package/dist/src/manage/manage-bar.d.ts +7 -2
  11. package/dist/src/manage/manage-bar.js +25 -3
  12. package/dist/src/manage/manage-bar.js.map +1 -1
  13. package/dist/src/styles/tile-action-styles.d.ts +14 -0
  14. package/dist/src/styles/tile-action-styles.js +52 -0
  15. package/dist/src/styles/tile-action-styles.js.map +1 -0
  16. package/dist/src/tiles/base-tile-component.d.ts +17 -1
  17. package/dist/src/tiles/base-tile-component.js +48 -1
  18. package/dist/src/tiles/base-tile-component.js.map +1 -1
  19. package/dist/src/tiles/grid/item-tile.js +1 -0
  20. package/dist/src/tiles/grid/item-tile.js.map +1 -1
  21. package/dist/src/tiles/list/tile-list-compact-header.js +66 -46
  22. package/dist/src/tiles/list/tile-list-compact-header.js.map +1 -1
  23. package/dist/src/tiles/list/tile-list-compact.d.ts +1 -1
  24. package/dist/src/tiles/list/tile-list-compact.js +132 -100
  25. package/dist/src/tiles/list/tile-list-compact.js.map +1 -1
  26. package/dist/src/tiles/list/tile-list.d.ts +1 -1
  27. package/dist/src/tiles/list/tile-list.js +316 -298
  28. package/dist/src/tiles/list/tile-list.js.map +1 -1
  29. package/dist/src/tiles/models.d.ts +14 -0
  30. package/dist/src/tiles/models.js.map +1 -1
  31. package/dist/src/tiles/tile-dispatcher.d.ts +14 -0
  32. package/dist/src/tiles/tile-dispatcher.js +107 -4
  33. package/dist/src/tiles/tile-dispatcher.js.map +1 -1
  34. package/dist/src/tiles/tile-display-value-provider.js.map +1 -1
  35. package/dist/test/data-source/collection-browser-data-source.test.js +2 -2
  36. package/dist/test/data-source/collection-browser-data-source.test.js.map +1 -1
  37. package/dist/test/manage/manage-bar.test.d.ts +1 -0
  38. package/dist/test/manage/manage-bar.test.js +123 -1
  39. package/dist/test/manage/manage-bar.test.js.map +1 -1
  40. package/dist/test/tiles/list/tile-list-compact-header.test.js +12 -12
  41. package/dist/test/tiles/list/tile-list-compact-header.test.js.map +1 -1
  42. package/dist/test/tiles/list/tile-list.test.js +134 -134
  43. package/dist/test/tiles/list/tile-list.test.js.map +1 -1
  44. package/index.ts +1 -0
  45. package/package.json +1 -1
  46. package/src/app-root.ts +115 -0
  47. package/src/collection-browser.ts +16 -30
  48. package/src/data-source/collection-browser-data-source.ts +1465 -1465
  49. package/src/manage/manage-bar.ts +33 -4
  50. package/src/styles/tile-action-styles.ts +52 -0
  51. package/src/tiles/base-tile-component.ts +57 -1
  52. package/src/tiles/grid/item-tile.ts +1 -0
  53. package/src/tiles/list/tile-list-compact-header.ts +106 -86
  54. package/src/tiles/list/tile-list-compact.ts +273 -239
  55. package/src/tiles/list/tile-list.ts +718 -700
  56. package/src/tiles/models.ts +16 -0
  57. package/src/tiles/tile-dispatcher.ts +114 -4
  58. package/src/tiles/tile-display-value-provider.ts +134 -134
  59. package/test/data-source/collection-browser-data-source.test.ts +193 -193
  60. package/test/manage/manage-bar.test.ts +192 -2
  61. package/test/tiles/list/tile-list-compact-header.test.ts +43 -43
  62. package/test/tiles/list/tile-list.test.ts +576 -576
  63. package/.claude/settings.local.json +0 -11
@@ -11,6 +11,7 @@ import { suppressedCollections } from '../../models';
11
11
  import { BaseTileComponent } from '../base-tile-component';
12
12
  import { formatCount } from '../../utils/format-count';
13
13
  import { isFirstMillisecondOfUTCYear } from '../../utils/local-date-from-utc';
14
+ import { tileActionStyles } from '../../styles/tile-action-styles';
14
15
  import '../image-block';
15
16
  import '../review-block';
16
17
  import '../text-snippet-block';
@@ -20,6 +21,7 @@ let TileList = class TileList extends BaseTileComponent {
20
21
  /*
21
22
  * Reactive properties inherited from BaseTileComponent:
22
23
  * - model?: TileModel;
24
+ * - tileActions: TileAction[] = [];
23
25
  * - currentWidth?: number;
24
26
  * - currentHeight?: number;
25
27
  * - baseNavigationUrl?: string;
@@ -37,41 +39,45 @@ let TileList = class TileList extends BaseTileComponent {
37
39
  this.collectionLinks = [];
38
40
  }
39
41
  render() {
40
- return html `
41
- <div id="list-line" class="${this.classSize}">
42
+ return html `
43
+ <div id="list-line" class="${this.classSize}">
42
44
  ${this.classSize === 'mobile'
43
45
  ? this.mobileTemplate
44
- : this.desktopTemplate}
45
- </div>
46
+ : this.desktopTemplate}
47
+ </div>
46
48
  `;
47
49
  }
48
50
  /**
49
51
  * Templates
50
52
  */
51
53
  get mobileTemplate() {
52
- return html `
53
- <div id="list-line-top">
54
- <div id="list-line-left">${this.imageBlockTemplate}</div>
55
- <div id="list-line-right">
56
- <div id="title-line">
57
- <div id="title">${this.titleTemplate}</div>
58
- ${this.iconRightTemplate}
59
- </div>
60
- </div>
61
- </div>
62
- <div id="list-line-bottom">${this.detailsTemplate}</div>
54
+ return html `
55
+ <div id="list-line-top">
56
+ <div id="list-line-left">
57
+ ${this.imageBlockTemplate} ${this.renderTileActions('list-detail')}
58
+ </div>
59
+ <div id="list-line-right">
60
+ <div id="title-line">
61
+ <div id="title">${this.titleTemplate}</div>
62
+ ${this.iconRightTemplate}
63
+ </div>
64
+ </div>
65
+ </div>
66
+ <div id="list-line-bottom">${this.detailsTemplate}</div>
63
67
  `;
64
68
  }
65
69
  get desktopTemplate() {
66
- return html `
67
- <div id="list-line-left">${this.imageBlockTemplate}</div>
68
- <div id="list-line-right">
69
- <div id="title-line">
70
- <div id="title">${this.titleTemplate}</div>
71
- ${this.iconRightTemplate}
72
- </div>
73
- ${this.detailsTemplate}
74
- </div>
70
+ return html `
71
+ <div id="list-line-left">
72
+ ${this.imageBlockTemplate} ${this.renderTileActions('list-detail')}
73
+ </div>
74
+ <div id="list-line-right">
75
+ <div id="title-line">
76
+ <div id="title">${this.titleTemplate}</div>
77
+ ${this.iconRightTemplate}
78
+ </div>
79
+ ${this.detailsTemplate}
80
+ </div>
75
81
  `;
76
82
  }
77
83
  get imageBlockTemplate() {
@@ -79,48 +85,48 @@ let TileList = class TileList extends BaseTileComponent {
79
85
  return nothing;
80
86
  const isCollection = this.model.mediatype === 'collection';
81
87
  const href = this.displayValueProvider.itemPageUrl(this.model.identifier, isCollection);
82
- return html `<a
83
- id="image-link"
84
- title=${msg(str `View ${this.model?.title}`)}
85
- href=${href}
86
- >
87
- <image-block
88
- .model=${this.model}
89
- .baseImageUrl=${this.baseImageUrl}
90
- .isCompactTile=${false}
91
- .isListTile=${true}
92
- .viewSize=${this.classSize}
93
- .loggedIn=${this.loggedIn}
94
- .suppressBlurring=${this.suppressBlurring}
95
- >
96
- </image-block>
88
+ return html `<a
89
+ id="image-link"
90
+ title=${msg(str `View ${this.model?.title}`)}
91
+ href=${href}
92
+ >
93
+ <image-block
94
+ .model=${this.model}
95
+ .baseImageUrl=${this.baseImageUrl}
96
+ .isCompactTile=${false}
97
+ .isListTile=${true}
98
+ .viewSize=${this.classSize}
99
+ .loggedIn=${this.loggedIn}
100
+ .suppressBlurring=${this.suppressBlurring}
101
+ >
102
+ </image-block>
97
103
  </a> `;
98
104
  }
99
105
  get detailsTemplate() {
100
- return html `
101
- ${this.itemLineTemplate} ${this.creatorTemplate}
102
- <div id="dates-line">
103
- ${this.datePublishedTemplate} ${this.dateSortByTemplate}
104
- ${this.webArchivesCaptureDatesTemplate}
105
- </div>
106
- <div id="views-line">
107
- ${this.viewsTemplate} ${this.ratingTemplate} ${this.reviewsTemplate}
108
- </div>
109
- ${this.topicsTemplate} ${this.collectionsTemplate}
110
- ${this.descriptionTemplate} ${this.textSnippetsTemplate}
111
- ${this.reviewBlockTemplate}
106
+ return html `
107
+ ${this.itemLineTemplate} ${this.creatorTemplate}
108
+ <div id="dates-line">
109
+ ${this.datePublishedTemplate} ${this.dateSortByTemplate}
110
+ ${this.webArchivesCaptureDatesTemplate}
111
+ </div>
112
+ <div id="views-line">
113
+ ${this.viewsTemplate} ${this.ratingTemplate} ${this.reviewsTemplate}
114
+ </div>
115
+ ${this.topicsTemplate} ${this.collectionsTemplate}
116
+ ${this.descriptionTemplate} ${this.textSnippetsTemplate}
117
+ ${this.reviewBlockTemplate}
112
118
  `;
113
119
  }
114
120
  // Data templates
115
121
  get iconRightTemplate() {
116
- return html `
117
- <a
118
- id="icon-right"
119
- href=${this.mediatypeURL}
120
- title=${msg(str `See more: ${this.model?.mediatype}`)}
121
- >
122
- <tile-mediatype-icon .model=${this.model}> </tile-mediatype-icon>
123
- </a>
122
+ return html `
123
+ <a
124
+ id="icon-right"
125
+ href=${this.mediatypeURL}
126
+ title=${msg(str `See more: ${this.model?.mediatype}`)}
127
+ >
128
+ <tile-mediatype-icon .model=${this.model}> </tile-mediatype-icon>
129
+ </a>
124
130
  `;
125
131
  }
126
132
  get titleTemplate() {
@@ -130,8 +136,8 @@ let TileList = class TileList extends BaseTileComponent {
130
136
  // If the model has a server-specified href, use it
131
137
  // Otherwise construct a details link using the identifier
132
138
  return this.model?.href
133
- ? html `<a href="${this.baseNavigationUrl}${this.model.href}"
134
- >${this.model.title ?? this.model.identifier}</a
139
+ ? html `<a href="${this.baseNavigationUrl}${this.model.href}"
140
+ >${this.model.title ?? this.model.identifier}</a
135
141
  >`
136
142
  : this.detailsLink(this.model.identifier, this.model.title, this.model.mediatype === 'collection');
137
143
  }
@@ -148,11 +154,11 @@ let TileList = class TileList extends BaseTileComponent {
148
154
  if (!this.model?.source) {
149
155
  return nothing;
150
156
  }
151
- return html `
152
- <div id="source" class="metadata">
153
- ${this.labelTemplate(msg('Source'))}
154
- ${this.searchLink('source', this.model.source)}
155
- </div>
157
+ return html `
158
+ <div id="source" class="metadata">
159
+ ${this.labelTemplate(msg('Source'))}
160
+ ${this.searchLink('source', this.model.source)}
161
+ </div>
156
162
  `;
157
163
  }
158
164
  get volumeTemplate() {
@@ -164,23 +170,23 @@ let TileList = class TileList extends BaseTileComponent {
164
170
  get creatorTemplate() {
165
171
  // "Archivist since" if account
166
172
  if (this.model?.mediatype === 'account') {
167
- return html `
168
- <div id="creator" class="metadata">
169
- <span class="label"
170
- >${this.displayValueProvider.accountLabel ?? nothing}</span
171
- >
172
- </div>
173
+ return html `
174
+ <div id="creator" class="metadata">
175
+ <span class="label"
176
+ >${this.displayValueProvider.accountLabel ?? nothing}</span
177
+ >
178
+ </div>
173
179
  `;
174
180
  }
175
181
  // "Creator" if not account tile
176
182
  if (!this.model?.creators || this.model.creators.length === 0) {
177
183
  return nothing;
178
184
  }
179
- return html `
180
- <div id="creator" class="metadata">
181
- ${this.labelTemplate(msg('By'))}
182
- ${join(map(this.model.creators, id => this.searchLink('creator', id)), ', ')}
183
- </div>
185
+ return html `
186
+ <div id="creator" class="metadata">
187
+ ${this.labelTemplate(msg('By'))}
188
+ ${join(map(this.model.creators, id => this.searchLink('creator', id)), ', ')}
189
+ </div>
184
190
  `;
185
191
  }
186
192
  get datePublishedTemplate() {
@@ -228,22 +234,22 @@ let TileList = class TileList extends BaseTileComponent {
228
234
  if (!this.model?.subjects || this.model.subjects.length === 0) {
229
235
  return nothing;
230
236
  }
231
- return html `
232
- <div id="topics" class="metadata">
233
- ${this.labelTemplate(msg('Topics'))}
234
- ${join(map(this.model.subjects, id => this.searchLink('subject', id)), ', ')}
235
- </div>
237
+ return html `
238
+ <div id="topics" class="metadata">
239
+ ${this.labelTemplate(msg('Topics'))}
240
+ ${join(map(this.model.subjects, id => this.searchLink('subject', id)), ', ')}
241
+ </div>
236
242
  `;
237
243
  }
238
244
  get collectionsTemplate() {
239
245
  if (!this.collectionLinks || this.collectionLinks.length === 0) {
240
246
  return nothing;
241
247
  }
242
- return html `
243
- <div id="collections" class="metadata">
244
- ${this.labelTemplate(msg('Collections'))}
245
- ${join(this.collectionLinks, ', ')}
246
- </div>
248
+ return html `
249
+ <div id="collections" class="metadata">
250
+ ${this.labelTemplate(msg('Collections'))}
251
+ ${join(this.collectionLinks, ', ')}
252
+ </div>
247
253
  `;
248
254
  }
249
255
  get descriptionTemplate() {
@@ -255,22 +261,22 @@ let TileList = class TileList extends BaseTileComponent {
255
261
  if (!this.model?.review)
256
262
  return nothing;
257
263
  const { reviewtitle, reviewbody, stars } = this.model.review;
258
- return html `
259
- <review-block
260
- viewsize="list"
261
- title=${ifDefined(reviewtitle)}
262
- body=${ifDefined(reviewbody)}
263
- starRating=${ifDefined(stars)}
264
- >
265
- </review-block>
264
+ return html `
265
+ <review-block
266
+ viewsize="list"
267
+ title=${ifDefined(reviewtitle)}
268
+ body=${ifDefined(reviewbody)}
269
+ starRating=${ifDefined(stars)}
270
+ >
271
+ </review-block>
266
272
  `;
267
273
  }
268
274
  get textSnippetsTemplate() {
269
275
  if (!this.hasSnippets)
270
276
  return nothing;
271
- return html `<text-snippet-block
272
- viewsize="list"
273
- .snippets=${this.model?.snippets}
277
+ return html `<text-snippet-block
278
+ viewsize="list"
279
+ .snippets=${this.model?.snippets}
274
280
  ></text-snippet-block>`;
275
281
  }
276
282
  get hasSnippets() {
@@ -279,12 +285,12 @@ let TileList = class TileList extends BaseTileComponent {
279
285
  get webArchivesCaptureDatesTemplate() {
280
286
  if (!this.model?.captureDates || !this.model.title)
281
287
  return nothing;
282
- return html `
283
- <ul class="capture-dates">
284
- ${map(this.model.captureDates, date => html `<li>
285
- ${this.displayValueProvider.webArchivesCaptureLink(this.model.title, date)}
286
- </li>`)}
287
- </ul>
288
+ return html `
289
+ <ul class="capture-dates">
290
+ ${map(this.model.captureDates, date => html `<li>
291
+ ${this.displayValueProvider.webArchivesCaptureLink(this.model.title, date)}
292
+ </li>`)}
293
+ </ul>
288
294
  `;
289
295
  }
290
296
  // Utility functions
@@ -292,10 +298,10 @@ let TileList = class TileList extends BaseTileComponent {
292
298
  metadataTemplate(text, label = '', id) {
293
299
  if (!text)
294
300
  return nothing;
295
- return html `
296
- <div id=${ifDefined(id)} class="metadata">
297
- ${this.labelTemplate(label)} ${text}
298
- </div>
301
+ return html `
302
+ <div id=${ifDefined(id)} class="metadata">
303
+ ${this.labelTemplate(label)} ${text}
304
+ </div>
299
305
  `;
300
306
  }
301
307
  labelTemplate(label) {
@@ -310,11 +316,11 @@ let TileList = class TileList extends BaseTileComponent {
310
316
  const query = encodeURIComponent(`${field}:"${searchTerm}"`);
311
317
  // No whitespace after closing tag
312
318
  // Note: single ' for href='' to wrap " in query var gets changed back by yarn format
313
- return html `<a
314
- href="${this.baseNavigationUrl}/search?query=${query}"
315
- rel="nofollow"
316
- >
317
- ${DOMPurify.sanitize(searchTerm)}</a
319
+ return html `<a
320
+ href="${this.baseNavigationUrl}/search?query=${query}"
321
+ rel="nofollow"
322
+ >
323
+ ${DOMPurify.sanitize(searchTerm)}</a
318
324
  >`;
319
325
  }
320
326
  detailsLink(identifier, text, isCollection = false) {
@@ -401,191 +407,203 @@ let TileList = class TileList extends BaseTileComponent {
401
407
  return 'long';
402
408
  }
403
409
  static get styles() {
404
- return css `
405
- html {
406
- font-size: unset;
407
- }
408
-
409
- div {
410
- font-size: 14px;
411
- }
412
-
413
- div a {
414
- text-decoration: none;
415
- }
416
-
417
- div a:link {
418
- color: var(--ia-theme-link-color, #4b64ff);
419
- }
420
-
421
- .label {
422
- font-weight: bold;
423
- }
424
-
425
- #list-line.mobile {
426
- --infiniteScrollerRowGap: 20px;
427
- --infiniteScrollerRowHeight: auto;
428
- }
429
-
430
- #list-line.desktop {
431
- --infiniteScrollerRowGap: 30px;
432
- --infiniteScrollerRowHeight: auto;
433
- }
434
-
435
- /* fields */
436
- #icon-right {
437
- width: 20px;
438
- padding-top: 5px;
439
- --iconHeight: 20px;
440
- --iconWidth: 20px;
441
- --iconTextAlign: right;
442
- margin-top: -8px;
443
- text-align: right;
444
- }
445
-
446
- #title {
447
- color: #4b64ff;
448
- text-decoration: none;
449
- font-size: 22px;
450
- font-weight: bold;
451
- /* align top of text with image */
452
- line-height: 25px;
453
- margin-top: -4px;
454
- padding-bottom: 2px;
455
- flex-grow: 1;
456
-
457
- display: -webkit-box;
458
- -webkit-box-orient: vertical;
459
- -webkit-line-clamp: 3;
460
- overflow: hidden;
461
- overflow-wrap: anywhere;
462
- }
463
-
464
- .metadata {
465
- line-height: 20px;
466
- }
467
-
468
- #description,
469
- #creator,
470
- #topics,
471
- #source {
472
- text-align: left;
473
- overflow: hidden;
474
- text-overflow: ellipsis;
475
- -webkit-box-orient: vertical;
476
- display: -webkit-box;
477
- word-break: break-word;
478
- -webkit-line-clamp: 3; /* number of lines to show */
479
- line-clamp: 3;
480
-
481
- /*
482
- * Safari doesn't always respect the line-clamping rules above,
483
- * so we add this to ensure these fields still get truncated
484
- */
485
- max-height: 60px;
486
- }
487
-
488
- #collections {
489
- display: -webkit-box;
490
- -webkit-box-orient: vertical;
491
- -webkit-line-clamp: 3;
492
- overflow: hidden;
493
- overflow-wrap: anywhere;
494
- }
495
-
496
- #collections > a {
497
- display: inline-block;
498
- }
499
-
500
- #icon {
501
- padding-top: 5px;
502
- }
503
-
504
- #description {
505
- padding-top: 10px;
506
- }
507
-
508
- /* Top level container */
509
- #list-line {
510
- display: flex;
511
- }
512
-
513
- #list-line.mobile {
514
- flex-direction: column;
515
- }
516
-
517
- #list-line.desktop {
518
- column-gap: 10px;
519
- }
520
-
521
- #list-line-top {
522
- display: flex;
523
- column-gap: 7px;
524
- }
525
-
526
- #list-line-bottom {
527
- padding-top: 4px;
528
- }
529
-
530
- #list-line-right,
531
- #list-line-top,
532
- #list-line-bottom {
533
- width: 100%;
534
- }
535
-
536
- /*
537
- * If the container becomes very tiny, don't let the thumbnail side take
538
- * up too much space. Shouldn't make a difference on ordinary viewport sizes.
539
- */
540
- #list-line-left {
541
- max-width: 25%;
542
-
543
- display: flex;
544
- flex-direction: column;
545
- row-gap: 5px;
546
- }
547
-
548
- div a:hover {
549
- text-decoration: underline;
550
- }
551
-
552
- /* Lines containing multiple div as row */
553
- #item-line,
554
- #dates-line,
555
- #views-line,
556
- #title-line {
557
- display: flex;
558
- flex-direction: row;
559
- column-gap: 10px;
560
- }
561
-
562
- /*
563
- * With the exception of the title line, allow these to wrap if
564
- * the space becomes too small to accommodate them together.
565
- *
566
- * The title line is excluded because it contains the mediatype icon
567
- * which we don't want to wrap.
568
- */
569
- #item-line,
570
- #dates-line,
571
- #views-line {
572
- flex-wrap: wrap;
573
- }
574
-
575
- .capture-dates {
576
- margin: 0;
577
- padding: 0;
578
- list-style-type: none;
579
- }
580
-
581
- .capture-dates a:link {
582
- text-decoration: none;
583
- color: var(--ia-theme-link-color, #4b64ff);
584
- }
585
- .capture-dates a:hover {
586
- text-decoration: underline;
587
- }
588
- `;
410
+ return [
411
+ tileActionStyles,
412
+ css `
413
+ html {
414
+ font-size: unset;
415
+ }
416
+
417
+ div {
418
+ font-size: 14px;
419
+ }
420
+
421
+ div a {
422
+ text-decoration: none;
423
+ }
424
+
425
+ div a:link {
426
+ color: var(--ia-theme-link-color, #4b64ff);
427
+ }
428
+
429
+ .label {
430
+ font-weight: bold;
431
+ }
432
+
433
+ #list-line.mobile {
434
+ --infiniteScrollerRowGap: 20px;
435
+ --infiniteScrollerRowHeight: auto;
436
+ }
437
+
438
+ #list-line.desktop {
439
+ --infiniteScrollerRowGap: 30px;
440
+ --infiniteScrollerRowHeight: auto;
441
+ }
442
+
443
+ /* fields */
444
+ #icon-right {
445
+ width: 20px;
446
+ padding-top: 5px;
447
+ --iconHeight: 20px;
448
+ --iconWidth: 20px;
449
+ --iconTextAlign: right;
450
+ margin-top: -8px;
451
+ text-align: right;
452
+ }
453
+
454
+ #title {
455
+ color: #4b64ff;
456
+ text-decoration: none;
457
+ font-size: 22px;
458
+ font-weight: bold;
459
+ /* align top of text with image */
460
+ line-height: 25px;
461
+ margin-top: -4px;
462
+ padding-bottom: 2px;
463
+ flex-grow: 1;
464
+
465
+ display: -webkit-box;
466
+ -webkit-box-orient: vertical;
467
+ -webkit-line-clamp: 3;
468
+ overflow: hidden;
469
+ overflow-wrap: anywhere;
470
+ }
471
+
472
+ .metadata {
473
+ line-height: 20px;
474
+ }
475
+
476
+ #description,
477
+ #creator,
478
+ #topics,
479
+ #source {
480
+ text-align: left;
481
+ overflow: hidden;
482
+ text-overflow: ellipsis;
483
+ -webkit-box-orient: vertical;
484
+ display: -webkit-box;
485
+ word-break: break-word;
486
+ -webkit-line-clamp: 3; /* number of lines to show */
487
+ line-clamp: 3;
488
+
489
+ /*
490
+ * Safari doesn't always respect the line-clamping rules above,
491
+ * so we add this to ensure these fields still get truncated
492
+ */
493
+ max-height: 60px;
494
+ }
495
+
496
+ #collections {
497
+ display: -webkit-box;
498
+ -webkit-box-orient: vertical;
499
+ -webkit-line-clamp: 3;
500
+ overflow: hidden;
501
+ overflow-wrap: anywhere;
502
+ }
503
+
504
+ #collections > a {
505
+ display: inline-block;
506
+ }
507
+
508
+ #icon {
509
+ padding-top: 5px;
510
+ }
511
+
512
+ #description {
513
+ padding-top: 10px;
514
+ }
515
+
516
+ /* Top level container */
517
+ #list-line {
518
+ display: flex;
519
+ }
520
+
521
+ #list-line.mobile {
522
+ flex-direction: column;
523
+ }
524
+
525
+ #list-line.desktop {
526
+ column-gap: 10px;
527
+ }
528
+
529
+ #list-line-top {
530
+ display: flex;
531
+ column-gap: 7px;
532
+ }
533
+
534
+ #list-line-bottom {
535
+ padding-top: 4px;
536
+ }
537
+
538
+ #list-line-right,
539
+ #list-line-top,
540
+ #list-line-bottom {
541
+ width: 100%;
542
+ }
543
+
544
+ /*
545
+ * If the container becomes very tiny, don't let the thumbnail side take
546
+ * up too much space. Shouldn't make a difference on ordinary viewport sizes.
547
+ */
548
+ #list-line-left {
549
+ max-width: 25%;
550
+
551
+ display: flex;
552
+ flex-direction: column;
553
+ row-gap: 5px;
554
+ }
555
+
556
+ div a:hover {
557
+ text-decoration: underline;
558
+ }
559
+
560
+ /* Lines containing multiple div as row */
561
+ #item-line,
562
+ #dates-line,
563
+ #views-line,
564
+ #title-line {
565
+ display: flex;
566
+ flex-direction: row;
567
+ column-gap: 10px;
568
+ }
569
+
570
+ /*
571
+ * With the exception of the title line, allow these to wrap if
572
+ * the space becomes too small to accommodate them together.
573
+ *
574
+ * The title line is excluded because it contains the mediatype icon
575
+ * which we don't want to wrap.
576
+ */
577
+ #item-line,
578
+ #dates-line,
579
+ #views-line {
580
+ flex-wrap: wrap;
581
+ }
582
+
583
+ .capture-dates {
584
+ margin: 0;
585
+ padding: 0;
586
+ list-style-type: none;
587
+ }
588
+
589
+ .capture-dates a:link {
590
+ text-decoration: none;
591
+ color: var(--ia-theme-link-color, #4b64ff);
592
+ }
593
+ .capture-dates a:hover {
594
+ text-decoration: underline;
595
+ }
596
+
597
+ /*
598
+ * Tile-list (extended) action row sits under the thumbnail in the left
599
+ * column. The image-block above already has its own bottom padding via
600
+ * the parent's row-gap, so we don't need extra spacing here.
601
+ */
602
+ .tile-actions.list-detail {
603
+ width: 100%;
604
+ }
605
+ `,
606
+ ];
589
607
  }
590
608
  };
591
609
  __decorate([