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

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) 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/menu-slider/ia-menu-slider.js +1 -1
  11. package/dist/src/menu-slider/ia-menu-slider.js.map +1 -1
  12. package/dist/src/menus/iaux-sharing-options.d.ts +28 -0
  13. package/dist/src/menus/iaux-sharing-options.js +277 -0
  14. package/dist/src/menus/iaux-sharing-options.js.map +1 -0
  15. package/dist/src/menus/iaux-viewable-files.d.ts +32 -0
  16. package/dist/src/menus/iaux-viewable-files.js +367 -0
  17. package/dist/src/menus/iaux-viewable-files.js.map +1 -0
  18. package/dist/src/menus/share-providers/email.d.ts +11 -0
  19. package/dist/src/menus/share-providers/email.js +15 -0
  20. package/dist/src/menus/share-providers/email.js.map +1 -0
  21. package/dist/src/menus/share-providers/facebook.d.ts +11 -0
  22. package/dist/src/menus/share-providers/facebook.js +15 -0
  23. package/dist/src/menus/share-providers/facebook.js.map +1 -0
  24. package/dist/src/menus/share-providers/pinterest.d.ts +11 -0
  25. package/dist/src/menus/share-providers/pinterest.js +15 -0
  26. package/dist/src/menus/share-providers/pinterest.js.map +1 -0
  27. package/dist/src/menus/share-providers/provider.d.ts +20 -0
  28. package/dist/src/menus/share-providers/provider.js +37 -0
  29. package/dist/src/menus/share-providers/provider.js.map +1 -0
  30. package/dist/src/menus/share-providers/share-provider-interface.d.ts +13 -0
  31. package/dist/src/menus/share-providers/share-provider-interface.js +2 -0
  32. package/dist/src/menus/share-providers/share-provider-interface.js.map +1 -0
  33. package/dist/src/menus/share-providers/tumblr.d.ts +11 -0
  34. package/dist/src/menus/share-providers/tumblr.js +15 -0
  35. package/dist/src/menus/share-providers/tumblr.js.map +1 -0
  36. package/dist/src/menus/share-providers/twitter.d.ts +11 -0
  37. package/dist/src/menus/share-providers/twitter.js +15 -0
  38. package/dist/src/menus/share-providers/twitter.js.map +1 -0
  39. package/dist/test/iaux-item-navigator.test.d.ts +1 -0
  40. package/dist/test/{ia-item-navigator.test.js → iaux-item-navigator.test.js} +49 -27
  41. package/dist/test/iaux-item-navigator.test.js.map +1 -0
  42. package/dist/test/iaux-sharing-options.test.d.ts +1 -0
  43. package/dist/test/iaux-sharing-options.test.js +64 -0
  44. package/dist/test/iaux-sharing-options.test.js.map +1 -0
  45. package/index.ts +9 -1
  46. package/package.json +11 -4
  47. package/src/{item-navigator.ts → iaux-item-navigator.ts} +2 -10
  48. package/src/menu-slider/ia-menu-slider.ts +1 -1
  49. package/src/menus/foo.json +84 -0
  50. package/src/menus/iaux-sharing-options.ts +281 -0
  51. package/src/menus/iaux-viewable-files.ts +377 -0
  52. package/src/menus/share-providers/email.ts +23 -0
  53. package/src/menus/share-providers/facebook.ts +23 -0
  54. package/src/menus/share-providers/pinterest.ts +23 -0
  55. package/src/menus/share-providers/provider.ts +63 -0
  56. package/src/menus/share-providers/share-provider-interface.ts +17 -0
  57. package/src/menus/share-providers/tumblr.ts +23 -0
  58. package/src/menus/share-providers/twitter.ts +23 -0
  59. package/test/ia-sharing-options.test.js +78 -0
  60. package/test/{ia-item-navigator.test.ts → iaux-item-navigator.test.ts} +49 -27
  61. package/test/iaux-sharing-options.test.ts +84 -0
  62. package/dist/src/item-navigator.js.map +0 -1
  63. package/dist/test/ia-item-navigator.test.d.ts +0 -1
  64. package/dist/test/ia-item-navigator.test.js.map +0 -1
  65. /package/dist/src/{item-navigator.d.ts → iaux-item-navigator.d.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
+ }