@internetarchive/ia-item-navigator 1.1.1 → 2.0.0-alpha1

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/demo/app-root.ts +190 -28
  2. package/dist/demo/app-root.d.ts +7 -3
  3. package/dist/demo/app-root.js +158 -22
  4. package/dist/demo/app-root.js.map +1 -1
  5. package/dist/index.d.ts +4 -1
  6. package/dist/index.js +5 -1
  7. package/dist/index.js.map +1 -1
  8. package/dist/src/{item-navigator.js → iaux-item-navigator.js} +3 -10
  9. package/dist/src/iaux-item-navigator.js.map +1 -0
  10. package/dist/src/menus/iaux-sharing-options.d.ts +28 -0
  11. package/dist/src/menus/iaux-sharing-options.js +277 -0
  12. package/dist/src/menus/iaux-sharing-options.js.map +1 -0
  13. package/dist/src/menus/iaux-viewable-files.d.ts +32 -0
  14. package/dist/src/menus/iaux-viewable-files.js +367 -0
  15. package/dist/src/menus/iaux-viewable-files.js.map +1 -0
  16. package/dist/src/menus/share-providers/email.d.ts +11 -0
  17. package/dist/src/menus/share-providers/email.js +15 -0
  18. package/dist/src/menus/share-providers/email.js.map +1 -0
  19. package/dist/src/menus/share-providers/facebook.d.ts +11 -0
  20. package/dist/src/menus/share-providers/facebook.js +15 -0
  21. package/dist/src/menus/share-providers/facebook.js.map +1 -0
  22. package/dist/src/menus/share-providers/pinterest.d.ts +11 -0
  23. package/dist/src/menus/share-providers/pinterest.js +15 -0
  24. package/dist/src/menus/share-providers/pinterest.js.map +1 -0
  25. package/dist/src/menus/share-providers/provider.d.ts +20 -0
  26. package/dist/src/menus/share-providers/provider.js +37 -0
  27. package/dist/src/menus/share-providers/provider.js.map +1 -0
  28. package/dist/src/menus/share-providers/share-provider-interface.d.ts +13 -0
  29. package/dist/src/menus/share-providers/share-provider-interface.js +2 -0
  30. package/dist/src/menus/share-providers/share-provider-interface.js.map +1 -0
  31. package/dist/src/menus/share-providers/tumblr.d.ts +11 -0
  32. package/dist/src/menus/share-providers/tumblr.js +15 -0
  33. package/dist/src/menus/share-providers/tumblr.js.map +1 -0
  34. package/dist/src/menus/share-providers/twitter.d.ts +11 -0
  35. package/dist/src/menus/share-providers/twitter.js +15 -0
  36. package/dist/src/menus/share-providers/twitter.js.map +1 -0
  37. package/dist/test/iaux-item-navigator.test.d.ts +1 -0
  38. package/dist/test/{ia-item-navigator.test.js → iaux-item-navigator.test.js} +49 -27
  39. package/dist/test/iaux-item-navigator.test.js.map +1 -0
  40. package/dist/test/iaux-sharing-options.test.d.ts +1 -0
  41. package/dist/test/iaux-sharing-options.test.js +64 -0
  42. package/dist/test/iaux-sharing-options.test.js.map +1 -0
  43. package/index.ts +9 -1
  44. package/package.json +11 -4
  45. package/src/{item-navigator.ts → iaux-item-navigator.ts} +2 -10
  46. package/src/menus/foo.json +84 -0
  47. package/src/menus/iaux-sharing-options.ts +281 -0
  48. package/src/menus/iaux-viewable-files.ts +377 -0
  49. package/src/menus/share-providers/email.ts +23 -0
  50. package/src/menus/share-providers/facebook.ts +23 -0
  51. package/src/menus/share-providers/pinterest.ts +23 -0
  52. package/src/menus/share-providers/provider.ts +63 -0
  53. package/src/menus/share-providers/share-provider-interface.ts +17 -0
  54. package/src/menus/share-providers/tumblr.ts +23 -0
  55. package/src/menus/share-providers/twitter.ts +23 -0
  56. package/test/ia-sharing-options.test.js +78 -0
  57. package/test/{iaux-item-navigator.test.txt → iaux-item-navigator.test.ts} +46 -24
  58. package/dist/src/item-navigator.js.map +0 -1
  59. package/dist/test/ia-item-navigator.test.d.ts +0 -1
  60. package/dist/test/ia-item-navigator.test.js.map +0 -1
  61. package/test/ia-item-navigator.test.ts +0 -417
  62. /package/dist/src/{item-navigator.d.ts → iaux-item-navigator.d.ts} +0 -0
  63. /package/test/{iaux-sharing-options.test.txt → iaux-sharing-options.test.ts} +0 -0
@@ -0,0 +1,281 @@
1
+ /* eslint-disable lit-a11y/click-events-have-key-events */
2
+ /* eslint-disable lit-a11y/list */
3
+ import { classMap } from 'lit/directives/class-map.js';
4
+ import { ifDefined } from 'lit/directives/if-defined.js';
5
+ import {
6
+ css,
7
+ CSSResult,
8
+ html,
9
+ LitElement,
10
+ nothing,
11
+ PropertyValues,
12
+ TemplateResult,
13
+ } from 'lit';
14
+ import { customElement, property } from 'lit/decorators.js';
15
+ import '@internetarchive/icon-link/icon-link';
16
+ import '@internetarchive/icon-share/icon-share';
17
+
18
+ import EmailProvider from './share-providers/email';
19
+ import FacebookProvider from './share-providers/facebook';
20
+ import PinterestProvider from './share-providers/pinterest';
21
+ import TumblrProvider from './share-providers/tumblr';
22
+ import TwitterProvider from './share-providers/twitter';
23
+ import { ProviderParams } from './share-providers/share-provider-interface';
24
+ import type Provider from './share-providers/provider';
25
+
26
+ const copyToClipboard = (options: Record<any, any>) => {
27
+ const currentTarget = options.currentTarget as HTMLElement;
28
+ const textarea = currentTarget.querySelector('textarea');
29
+ const note = currentTarget.querySelector('small') as any;
30
+ textarea!.select();
31
+ document.execCommand('copy');
32
+ textarea!.blur();
33
+ note.classList.add('visible');
34
+ clearTimeout(note.timeout);
35
+ note.timeout = setTimeout(() => note.classList.remove('visible'), 4000);
36
+ };
37
+
38
+ export const iauxShareIcon: TemplateResult = html`<ia-icon-share
39
+ style="width: var(--iconWidth); height: var(--iconHeight);"
40
+ ></ia-icon-share>`;
41
+
42
+ @customElement('iaux-sharing-options')
43
+ export class IauxSharingOptions extends LitElement {
44
+ @property({ type: String }) baseHost = 'archive.org';
45
+
46
+ @property({ type: String }) creator = '';
47
+
48
+ @property({ type: String }) description = '';
49
+
50
+ @property({ type: Boolean }) embedOptionsVisible = false;
51
+
52
+ @property({ type: String }) identifier = '';
53
+
54
+ @property({ type: Array }) sharingOptions: Provider[] = [];
55
+
56
+ @property({ type: String }) type = '';
57
+
58
+ @property({ type: Boolean }) renderHeader = false;
59
+
60
+ @property({ type: String }) fileSubPrefix = '';
61
+
62
+ updated(changed: PropertyValues) {
63
+ if (changed.has('sharingOptions') && !this.sharingOptions.length) {
64
+ this.loadProviders();
65
+ }
66
+ }
67
+
68
+ loadProviders() {
69
+ const { baseHost, creator, description, identifier, type, fileSubPrefix } =
70
+ this;
71
+ const params = {
72
+ baseHost,
73
+ creator,
74
+ description,
75
+ identifier,
76
+ type,
77
+ fileSubPrefix,
78
+ } as unknown as ProviderParams;
79
+
80
+ this.sharingOptions = [
81
+ new TwitterProvider(params),
82
+ new FacebookProvider(params),
83
+ new TumblrProvider(params),
84
+ new PinterestProvider(params),
85
+ new EmailProvider(params),
86
+ ];
87
+ }
88
+
89
+ get sharingItems() {
90
+ return this.sharingOptions.map(
91
+ option =>
92
+ html`<li>
93
+ <a
94
+ class="${ifDefined(option.class)}"
95
+ href="${option.url}"
96
+ target="_blank"
97
+ >
98
+ ${option.icon} ${option.name}
99
+ </a>
100
+ </li>`,
101
+ );
102
+ }
103
+
104
+ get embedOption() {
105
+ return html`<li>
106
+ <a href="#" @click=${this.toggleEmbedOptions}>
107
+ <ia-icon-link></ia-icon-link>
108
+ Get an embeddable link
109
+ </a>
110
+ </li>`;
111
+ }
112
+
113
+ get iframeEmbed() {
114
+ return html`&lt;iframe
115
+ src="https://${this.baseHost}/embed/${this.identifier}" width="560"
116
+ height="384" frameborder="0" webkitallowfullscreen="true"
117
+ mozallowfullscreen="true" allowfullscreen&gt;&lt;/iframe&gt;`;
118
+ }
119
+
120
+ get bbcodeEmbed() {
121
+ return `[archiveorg ${this.identifier} width=560 height=384 frameborder=0 webkitallowfullscreen=true mozallowfullscreen=true]`;
122
+ }
123
+
124
+ get helpURL() {
125
+ return `https://${this.baseHost}/help/audio.php?identifier=${this.identifier}`;
126
+ }
127
+
128
+ toggleEmbedOptions(e: Event) {
129
+ e.preventDefault();
130
+ this.embedOptionsVisible = !this.embedOptionsVisible;
131
+ }
132
+
133
+ get header() {
134
+ const header = html`<header><h3>Share this ${this.type}</h3></header>`;
135
+ return this.renderHeader ? header : nothing;
136
+ }
137
+
138
+ render() {
139
+ return html`
140
+ ${this.header}
141
+ <ul>
142
+ ${this.sharingItems} ${this.embedOption}
143
+ <div
144
+ class=${classMap({ visible: this.embedOptionsVisible, embed: true })}
145
+ >
146
+ <h4>Embed</h4>
147
+ <div class="code" @click=${copyToClipboard}>
148
+ <textarea readonly>${this.iframeEmbed}</textarea>
149
+ <small>Copied to clipboard</small>
150
+ </div>
151
+ <h4>
152
+ Embed for wordpress.com hosted blogs and archive.org item
153
+ &lt;description&gt; tags
154
+ </h4>
155
+ <div class="code" @click=${copyToClipboard}>
156
+ <textarea readonly>${this.bbcodeEmbed}</textarea>
157
+ <small>Copied to clipboard</small>
158
+ </div>
159
+ <p>
160
+ Want more?
161
+ <a href=${this.helpURL}
162
+ >Advanced embedding details, examples, and help</a
163
+ >!
164
+ </p>
165
+ </div>
166
+ </ul>
167
+ `;
168
+ }
169
+
170
+ get providerIcon(): TemplateResult {
171
+ return html`<ia-icon-share
172
+ style="width: var(--iconWidth); height: var(--iconHeight);"
173
+ ></ia-icon-share>`;
174
+ }
175
+
176
+ static get styles(): CSSResult {
177
+ return css`
178
+ :host {
179
+ display: block;
180
+ height: 100%;
181
+ overflow-y: auto;
182
+ font-size: 1.4rem;
183
+ box-sizing: border-box;
184
+ }
185
+
186
+ header {
187
+ display: flex;
188
+ align-items: baseline;
189
+ }
190
+
191
+ h3 {
192
+ padding: 0;
193
+ margin: 0 1rem 0 0;
194
+ font-size: 1.6rem;
195
+ }
196
+
197
+ h4 {
198
+ font-size: 1.4rem;
199
+ }
200
+
201
+ ul {
202
+ padding: 0 0 2rem 0;
203
+ list-style: none;
204
+ }
205
+
206
+ li {
207
+ padding: 0 0 1rem 0;
208
+ }
209
+
210
+ li a {
211
+ font-size: 1.6rem;
212
+ text-decoration: none;
213
+ color: var(--shareLinkColor);
214
+ }
215
+
216
+ li a * {
217
+ display: inline-block;
218
+ padding: 0.2rem;
219
+ margin-right: 1rem;
220
+ vertical-align: middle;
221
+ border: 1px solid var(--shareIconBorder);
222
+ border-radius: 7px;
223
+ background: var(--shareIconBg);
224
+ }
225
+
226
+ .embed {
227
+ display: none;
228
+ }
229
+ .embed.visible {
230
+ display: block;
231
+ width: 95%;
232
+ }
233
+
234
+ .embed a {
235
+ color: var(--shareLinkColor);
236
+ }
237
+
238
+ .code {
239
+ position: relative;
240
+ }
241
+
242
+ textarea {
243
+ display: block;
244
+ width: 100%;
245
+ height: 120px;
246
+ padding: 0.8rem 1rem;
247
+ box-sizing: border-box;
248
+ resize: none;
249
+ cursor: pointer;
250
+ font:
251
+ normal 1.4rem 'Helvetica Neue',
252
+ Helvetica,
253
+ Arial,
254
+ sans-serif;
255
+ color: var(--textareaColor, #fff);
256
+ background: var(--textareaBg, #151515);
257
+ }
258
+
259
+ small {
260
+ position: absolute;
261
+ bottom: 0;
262
+ left: 0;
263
+ height: 3rem;
264
+ padding: 0.5rem 1rem;
265
+ box-sizing: border-box;
266
+ font:
267
+ normal 1.2rem/2rem 'Helvetica Neue',
268
+ Helvetica,
269
+ Arial,
270
+ sans-serif;
271
+ color: var(--textareaBg, #151515);
272
+ background: var(--textareaColor, #fff);
273
+ opacity: 0;
274
+ transition: opacity 300ms linear;
275
+ }
276
+ small.visible {
277
+ opacity: 1;
278
+ }
279
+ `;
280
+ }
281
+ }
@@ -0,0 +1,377 @@
1
+ /* eslint-disable max-classes-per-file */
2
+ /* eslint-disable lit-a11y/list */
3
+ import { css, html, LitElement, nothing, TemplateResult } from 'lit';
4
+ import { customElement, property } from 'lit/decorators.js';
5
+ import { repeat } from 'lit/directives/repeat.js';
6
+
7
+ // sort icons
8
+ const sortAscIcon = html`
9
+ <svg
10
+ name="sort-asc"
11
+ height="18"
12
+ viewBox="0 0 18 18"
13
+ width="18"
14
+ xmlns="http://www.w3.org/2000/svg"
15
+ >
16
+ <g fill="none" fill-rule="evenodd">
17
+ <path
18
+ d="m2.32514544 8.30769231.7756949-2.08468003h2.92824822l.75630252 2.08468003h1.01809955l-2.70523594-6.92307693h-1.01809955l-2.69553976 6.92307693zm3.41305753-2.86037492h-2.34647705l1.17323853-3.22883h.01939237z"
19
+ fill="#fff"
20
+ fill-rule="nonzero"
21
+ />
22
+ <path
23
+ d="m7.1689722 16.6153846v-.7756949h-4.4117647l4.29541047-5.3716871v-.77569491h-5.06140918v.77569491h3.97543633l-4.30510666 5.3716871v.7756949z"
24
+ fill="#fff"
25
+ fill-rule="nonzero"
26
+ />
27
+ <path
28
+ d="m10.3846154 11.0769231 2.7692308 5.5384615 2.7692307-5.5384615m-2.7692307 4.1538461v-13.15384612"
29
+ stroke="#fff"
30
+ stroke-linecap="round"
31
+ stroke-linejoin="round"
32
+ stroke-width="1.661538"
33
+ transform="matrix(1 0 0 -1 0 18.692308)"
34
+ />
35
+ </g>
36
+ </svg>
37
+ `;
38
+ const sortDescIcon = html`
39
+ <svg
40
+ name="sort-desc"
41
+ height="18"
42
+ viewBox="0 0 18 18"
43
+ width="18"
44
+ xmlns="http://www.w3.org/2000/svg"
45
+ >
46
+ <g fill="none" fill-rule="evenodd">
47
+ <path
48
+ d="m2.32514544 8.30769231.7756949-2.08468003h2.92824822l.75630252 2.08468003h1.01809955l-2.70523594-6.92307693h-1.01809955l-2.69553976 6.92307693zm3.41305753-2.86037492h-2.34647705l1.17323853-3.22883h.01939237z"
49
+ fill="#fff"
50
+ fill-rule="nonzero"
51
+ />
52
+ <path
53
+ d="m7.1689722 16.6153846v-.7756949h-4.4117647l4.29541047-5.3716871v-.77569491h-5.06140918v.77569491h3.97543633l-4.30510666 5.3716871v.7756949z"
54
+ fill="#fff"
55
+ fill-rule="nonzero"
56
+ />
57
+ <path
58
+ d="m10.3846154 11.0769231 2.7692308 5.5384615 2.7692307-5.5384615m-2.7692307 4.1538461v-13.15384612"
59
+ stroke="#fff"
60
+ stroke-linecap="round"
61
+ stroke-linejoin="round"
62
+ stroke-width="1.661538"
63
+ />
64
+ </g>
65
+ </svg>
66
+ `;
67
+ const sortNeutralIcon = html`
68
+ <svg
69
+ name="sort-neutral"
70
+ height="18"
71
+ viewBox="0 0 18 18"
72
+ width="18"
73
+ xmlns="http://www.w3.org/2000/svg"
74
+ >
75
+ <g fill="#fff" fill-rule="evenodd">
76
+ <path
77
+ d="m2.32514544 8.30769231.7756949-2.08468003h2.92824822l.75630252 2.08468003h1.01809955l-2.70523594-6.92307693h-1.01809955l-2.69553976 6.92307693zm3.41305753-2.86037492h-2.34647705l1.17323853-3.22883h.01939237z"
78
+ fill-rule="nonzero"
79
+ />
80
+ <path
81
+ d="m7.1689722 16.6153846v-.7756949h-4.4117647l4.29541047-5.3716871v-.77569491h-5.06140918v.77569491h3.97543633l-4.30510666 5.3716871v.7756949z"
82
+ fill-rule="nonzero"
83
+ />
84
+ <circle cx="13" cy="9" r="2" />
85
+ </g>
86
+ </svg>
87
+ `;
88
+
89
+ // extra components
90
+ export const viewableFilesIcon = html`
91
+ <svg
92
+ height="24"
93
+ viewBox="0 0 24 24"
94
+ width="24"
95
+ xmlns="http://www.w3.org/2000/svg"
96
+ aria-labelledby="volumesTitleID volumesDescID"
97
+ >
98
+ <title id="volumesTitleID">Viewable Files</title>
99
+ <g fill="#ffffff">
100
+ <path
101
+ fill="#ffffff"
102
+ d="m9.83536396 0h10.07241114c.1725502.47117517.3378411.76385809.4958725.87804878.1295523.11419069.3199719.1998337.5712586.25692905.2512868.05709534.4704647.08564301.6575337.08564301h.2806036v15.24362526h-4.3355343v3.8106985h-4.44275v3.7250554h-12.01318261c-.27306495 0-.50313194-.085643-.69020098-.256929-.18706903-.1712861-.30936193-.3425721-.36687867-.5138581l-.06449694-.2785477v-14.2159091c0-.32815965.08627512-.5922949.25882537-.79240577.17255024-.20011086.34510049-.32150776.51765073-.36419068l.25882537-.0640244h3.36472977v-2.54767184c0-.31374722.08627513-.57067627.25882537-.77078714.17255025-.20011086.34510049-.32150776.51765074-.36419068l.25882536-.06402439h3.36472978v-2.56929047c0-.32815964.08627512-.5922949.25882537-.79240576.17255024-.20011087.34510049-.31430156.51765073-.34257207zm10.78355264 15.6294346v-13.53076498c-.2730649-.08536585-.4456152-.16380266-.5176507-.23531042-.1725502-.1424612-.2730649-.27078714-.3015441-.38497783v13.36031043h-9.87808272c0 .0144124-.02149898.0144124-.06449694 0-.04299795-.0144124-.08962561.006929-.13988296.0640244-.05025735.0570953-.07538603.1427383-.07538603.256929s.02149898.210643.06449694.289357c.04299795.078714.08599591.1322062.12899387.1604767l.06449693.0216187h10.71905571zm-10.2449613-2.4412417h7.98003v-11.60421286h-7.98003zm1.6827837-9.41990022h4.6153002c.1725502 0 .3199718.05349224.4422647.16047672s.1834393.23891353.1834393.39578714c0 .15687362-.0611464.28519956-.1834393.38497783s-.2697145.1496674-.4422647.1496674h-4.6153002c-.1725503 0-.3199719-.04988913-.4422647-.1496674-.1222929-.09977827-.1834394-.22810421-.1834394-.38497783 0-.15687361.0611465-.28880266.1834394-.39578714.1222928-.10698448.2697144-.16047672.4422647-.16047672zm-6.08197737 13.50997782h7.72120467v-.8131929h-3.79610541c-.27306495 0-.49950224-.085643-.67931188-.256929-.17980964-.1712861-.29847284-.3425721-.35598958-.5138581l-.06449694-.2785477v-10.02023282h-2.82530086zm6.77217827-11.36890243h3.2139578c.1295522 0 .240956.05709534.3342113.17128603.0932554.11419069.139883.24972284.139883.40659645 0 .15687362-.0466276.28880267-.139883.39578714-.0932553.10698448-.2046591.16047672-.3342113.16047672h-3.2139578c-.1295523 0-.2373264-.05349224-.3233223-.16047672-.0859959-.10698447-.1289938-.23891352-.1289938-.39578714 0-.15687361.0429979-.29240576.1289938-.40659645s.19377-.17128603.3233223-.17128603zm-11.15043132 15.11557653h7.69942646v-.7491685h-3.79610539c-.25854616 0-.48135376-.0892462-.66842279-.2677384-.18706904-.1784922-.30936193-.3605876-.36687868-.546286l-.06449694-.2569291v-10.04101994h-2.80352266zm14.62237682-4.5606985h-.8191949v2.1410754h-9.89986085s-.04299796.0285477-.12899387.085643c-.08599592.0570954-.12201369.1427384-.10805331.2569291 0 .1141907.01786928.210643.05360784.289357.03573856.0787139.07538603.125.1189424.138858l.06449694.0432373h10.71905575v-2.9542683zm-4.3991936 3.8106985h-.8191949v2.077051h-9.8563045c0 .0144124-.02149898.0144124-.06449694 0-.04299795-.0144125-.08962561.0105321-.13988296.0748337-.05025735.0643015-.07538603.1607538-.07538603.289357 0 .1141906.02149898.2070399.06449694.2785476.04299795.0715078.08599591.1141907.12899387.1280488l.06449693.0216186h10.69811519v-2.8686252z"
103
+ />
104
+ </g>
105
+ </svg>
106
+ `;
107
+
108
+ type sortOptions = 'title_asc' | 'title_desc' | 'default';
109
+
110
+ type ItemInfo = {
111
+ url_path: string;
112
+ image: string;
113
+ title: string;
114
+ author: string;
115
+ file_subprefix: string;
116
+ };
117
+
118
+ @customElement('iaux-sort-viewable-files')
119
+ export class IauxSortFilesButton extends LitElement {
120
+ @property({ type: Array }) fileListRaw: any[] = [];
121
+
122
+ @property({ type: Array }) fileListSorted: any[] = [];
123
+
124
+ @property({ type: String }) sortOrderBy: sortOptions = 'default';
125
+
126
+ render() {
127
+ return html`<div class="sort-multi-file-list">${this.sortButton}</div>`;
128
+ }
129
+
130
+ get sortButton() {
131
+ const sortIcons = {
132
+ default: html`
133
+ <button
134
+ class="sort-by neutral-icon"
135
+ aria-label="Sort volumes in initial order"
136
+ @click=${() => this.sortVolumes('title_asc')}
137
+ >
138
+ ${sortNeutralIcon}
139
+ </button>
140
+ `,
141
+ title_asc: html`
142
+ <button
143
+ class="sort-by asc-icon"
144
+ aria-label="Sort volumes in ascending order"
145
+ @click=${() => this.sortVolumes('title_desc')}
146
+ >
147
+ ${sortAscIcon}
148
+ </button>
149
+ `,
150
+ title_desc: html`
151
+ <button
152
+ class="sort-by desc-icon"
153
+ aria-label="Sort volumes in descending order"
154
+ @click=${() => this.sortVolumes('default')}
155
+ >
156
+ ${sortDescIcon}
157
+ </button>
158
+ `,
159
+ };
160
+
161
+ return sortIcons[this.sortOrderBy];
162
+ }
163
+
164
+ sortVolumes(sortType: sortOptions) {
165
+ this.sortOrderBy = sortType;
166
+ let sortedFiles = [];
167
+
168
+ sortedFiles = this.fileListRaw.sort((a, b) => {
169
+ if (sortType === 'title_asc') return a.title.localeCompare(b.title);
170
+ if (sortType === 'title_desc') return b.title.localeCompare(a.title);
171
+ return a.orig_sort - b.orig_sort;
172
+ });
173
+
174
+ this.dispatchEvent(
175
+ new CustomEvent('fileListSorted', {
176
+ detail: {
177
+ sortType,
178
+ sortedFiles,
179
+ },
180
+ bubbles: true,
181
+ composed: true,
182
+ }),
183
+ );
184
+ this.fileListSorted = sortedFiles;
185
+ }
186
+
187
+ static get styles() {
188
+ return css`
189
+ button.sort-by {
190
+ padding: 0px;
191
+ background-color: transparent;
192
+ border: 0px;
193
+ --iconWidth: var(--menuSliderHeaderIconWidth);
194
+ --iconHeight: var(--menuSliderHeaderIconHeight);
195
+ }
196
+ `;
197
+ }
198
+ }
199
+
200
+ @customElement('iaux-viewable-files')
201
+ export class IauxViewableFiles extends LitElement {
202
+ @property({ type: String }) hostUrl: string = 'archive.org';
203
+
204
+ @property({ type: String }) sortOrderBy:
205
+ | 'default'
206
+ | 'title_asc'
207
+ | 'title_desc' = 'default';
208
+
209
+ @property({ type: String }) subPrefix: string = '';
210
+
211
+ @property({ type: Array }) fileList: any[] = [];
212
+
213
+ firstUpdated() {
214
+ const activeFile = this.shadowRoot!.querySelector('.content.active') as any;
215
+ // allow for css animations to run before scrolling to active file
216
+ setTimeout(() => {
217
+ // scroll active file into view if needed
218
+ // note: `scrollIntoViewIfNeeded` handles auto-scroll gracefully for Chrome, Safari
219
+ // Firefox does not have this capability yet as it does not support `scrollIntoViewIfNeeded`
220
+ activeFile?.scrollIntoViewIfNeeded(true);
221
+
222
+ // Todo: support `scrollIntoView` or `parentContainer.crollTop = x` for FF & "IE 11"
223
+ // currently, the hard `position: absolutes` misaligns subpanel when `scrollIntoView` is applied :(
224
+ }, 350);
225
+ }
226
+
227
+ volumeItemWithImageTitle(item: ItemInfo) {
228
+ const hrefUrl =
229
+ this.sortOrderBy === 'default'
230
+ ? `${this.hostUrl}${item.url_path}`
231
+ : `${this.hostUrl}${item.url_path}?sort=${this.sortOrderBy}`;
232
+
233
+ return html`
234
+ <li class="content active">
235
+ <div class="separator"></div>
236
+ <a class="container" href="${hrefUrl}">
237
+ <div class="image">
238
+ <img src="${item.image}" alt="preview" />
239
+ </div>
240
+ <div class="text">
241
+ <p class="item-title">${item.title}</p>
242
+ <small>by: ${item.author}</small>
243
+ </div>
244
+ </a>
245
+ </li>
246
+ `;
247
+ }
248
+
249
+ fileLi(item: ItemInfo) {
250
+ const activeClass = this.subPrefix === item.file_subprefix ? ' active' : '';
251
+
252
+ const hrefUrl =
253
+ this.sortOrderBy === 'default'
254
+ ? `${this.hostUrl}${item.url_path}`
255
+ : `${this.hostUrl}${item.url_path}?sort=${this.sortOrderBy}`;
256
+
257
+ return html`
258
+ <li>
259
+ <div class="separator"></div>
260
+ <div class="content${activeClass}">
261
+ <a href="https://${hrefUrl}">
262
+ <p class="item-title">${item.title}</p>
263
+ </a>
264
+ </div>
265
+ </li>
266
+ `;
267
+ }
268
+
269
+ get fileListTemplate(): TemplateResult {
270
+ const filesDisplay = repeat(
271
+ this.fileList,
272
+ file => file?.file_prefix,
273
+ this.fileLi.bind(this),
274
+ );
275
+ return html`
276
+ <ul>
277
+ ${filesDisplay}
278
+ <div class="separator"></div>
279
+ </ul>
280
+ `;
281
+ }
282
+
283
+ render() {
284
+ return html` ${this.fileList.length ? this.fileListTemplate : nothing} `;
285
+ }
286
+
287
+ static get styles() {
288
+ return css`
289
+ :host {
290
+ display: block;
291
+ overflow-y: auto;
292
+ box-sizing: border-box;
293
+ color: var(--primaryTextColor);
294
+ margin-top: 14px;
295
+ margin-bottom: 2rem;
296
+ --activeBorderWidth: 2px;
297
+ }
298
+
299
+ a {
300
+ color: #ffffff;
301
+ text-decoration: none;
302
+ }
303
+
304
+ img {
305
+ width: 35px;
306
+ height: 45px;
307
+ }
308
+
309
+ ul {
310
+ padding: 0;
311
+ list-style: none;
312
+ margin: var(--activeBorderWidth) 0.5rem 1rem 0;
313
+ }
314
+
315
+ ul > li:first-child .separator {
316
+ display: none;
317
+ }
318
+
319
+ li {
320
+ cursor: pointer;
321
+ outline: none;
322
+ position: relative;
323
+ }
324
+
325
+ li .content {
326
+ padding: 2px 0 4px 2px;
327
+ border: var(--activeBorderWidth) solid transparent;
328
+ padding: 0.2rem 0 0.4rem 0.2rem;
329
+ }
330
+
331
+ li .content.active {
332
+ border: var(--activeBorderWidth) solid #538bc5;
333
+ }
334
+
335
+ small {
336
+ font-style: italic;
337
+ white-space: initial;
338
+ }
339
+
340
+ .container {
341
+ display: flex;
342
+ align-items: center;
343
+ justify-content: center;
344
+ }
345
+
346
+ .item-title {
347
+ margin-block-start: 0em;
348
+ margin-block-end: 0em;
349
+ font-size: 14px;
350
+ font-weight: bold;
351
+ word-wrap: break-word;
352
+ padding-left: 5px;
353
+ }
354
+
355
+ .separator {
356
+ background-color: var(--secondaryBGColor);
357
+ width: 98%;
358
+ margin: 1px auto;
359
+ height: 1px;
360
+ }
361
+
362
+ .text {
363
+ padding-left: 10px;
364
+ }
365
+
366
+ .icon {
367
+ display: inline-block;
368
+ width: 14px;
369
+ height: 14px;
370
+ margin-left: 0.7rem;
371
+ border: 1px solid var(--primaryTextColor);
372
+ border-radius: 2px;
373
+ background: var(--activeButtonBg) 50% 50% no-repeat;
374
+ }
375
+ `;
376
+ }
377
+ }
@@ -0,0 +1,23 @@
1
+ import '@internetarchive/icon-email/icon-email';
2
+ import { TemplateResult, html } from 'lit';
3
+ import Provider from './provider';
4
+ import type { ProviderParams } from './share-provider-interface';
5
+
6
+ export default class extends Provider {
7
+ name: string;
8
+
9
+ icon: TemplateResult;
10
+
11
+ class: string;
12
+
13
+ constructor(params: ProviderParams) {
14
+ super(params);
15
+ this.name = 'Email';
16
+ this.icon = html`<ia-icon-email></ia-icon-email>`;
17
+ this.class = 'email';
18
+ }
19
+
20
+ override get url(): string {
21
+ return `mailto:?body=https://${this.baseHost}/details/${this.itemPath}&subject=${this.description} : ${this.creator}${this.promoCopy}`;
22
+ }
23
+ }
@@ -0,0 +1,23 @@
1
+ import '@internetarchive/icon-facebook/icon-facebook';
2
+ import { TemplateResult, html } from 'lit';
3
+ import Provider from './provider';
4
+ import type { ProviderParams } from './share-provider-interface';
5
+
6
+ export default class extends Provider {
7
+ name: string;
8
+
9
+ icon: TemplateResult;
10
+
11
+ class: string;
12
+
13
+ constructor(params: ProviderParams) {
14
+ super(params);
15
+ this.name = 'Facebook';
16
+ this.icon = html`<ia-icon-facebook></ia-icon-facebook>`;
17
+ this.class = 'facebook';
18
+ }
19
+
20
+ override get url(): string {
21
+ return `https://www.facebook.com/sharer/sharer.php?u=https://${this.baseHost}/details/${this.itemPath}`;
22
+ }
23
+ }