@internetarchive/ia-item-navigator 0.0.0 → 0.0.2

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 (70) hide show
  1. package/README.md +29 -19
  2. package/demo/app-root.ts +113 -22
  3. package/demo/index.html +12 -4
  4. package/dist/demo/app-root.d.ts +27 -7
  5. package/dist/demo/app-root.js +98 -23
  6. package/dist/demo/app-root.js.map +1 -1
  7. package/dist/src/interfaces/custom-theater-interface.d.ts +20 -0
  8. package/dist/src/interfaces/custom-theater-interface.js +2 -0
  9. package/dist/src/interfaces/custom-theater-interface.js.map +1 -0
  10. package/dist/src/interfaces/event-interfaces.d.ts +13 -23
  11. package/dist/src/interfaces/event-interfaces.js.map +1 -1
  12. package/dist/src/interfaces/menu-interfaces.d.ts +7 -7
  13. package/dist/src/interfaces/menu-interfaces.js.map +1 -1
  14. package/dist/src/interfaces/nav-controller-interface.d.ts +11 -6
  15. package/dist/src/interfaces/nav-controller-interface.js.map +1 -1
  16. package/dist/src/item-inspector/files-by-type/files-by-type-provider.js +5 -3
  17. package/dist/src/item-inspector/files-by-type/files-by-type-provider.js.map +1 -1
  18. package/dist/src/item-inspector/files-by-type/ia-files-by-type.d.ts +1 -0
  19. package/dist/src/item-inspector/files-by-type/ia-files-by-type.js +14 -0
  20. package/dist/src/item-inspector/files-by-type/ia-files-by-type.js.map +1 -1
  21. package/dist/src/item-inspector/item-inspector.d.ts +0 -31
  22. package/dist/src/item-inspector/item-inspector.js +253 -181
  23. package/dist/src/item-inspector/item-inspector.js.map +1 -1
  24. package/dist/src/item-inspector/visual-mod-provider.d.ts +19 -0
  25. package/dist/src/item-inspector/visual-mod-provider.js +46 -0
  26. package/dist/src/item-inspector/visual-mod-provider.js.map +1 -0
  27. package/dist/src/item-navigator.d.ts +50 -28
  28. package/dist/src/item-navigator.js +216 -132
  29. package/dist/src/item-navigator.js.map +1 -1
  30. package/dist/src/loader.d.ts +5 -0
  31. package/dist/src/loader.js +8 -2
  32. package/dist/src/loader.js.map +1 -1
  33. package/dist/src/no-theater-available.d.ts +9 -0
  34. package/dist/src/no-theater-available.js +79 -0
  35. package/dist/src/no-theater-available.js.map +1 -0
  36. package/dist/test/book-nav-stub.d.ts +22 -0
  37. package/dist/test/book-nav-stub.js +49 -0
  38. package/dist/test/book-nav-stub.js.map +1 -0
  39. package/dist/test/ia-item-navigator.test.d.ts +2 -0
  40. package/dist/test/ia-item-navigator.test.js +317 -0
  41. package/dist/test/ia-item-navigator.test.js.map +1 -0
  42. package/dist/test/ia-stub-goody.d.ts +210 -0
  43. package/dist/test/ia-stub-goody.js +276 -0
  44. package/dist/test/ia-stub-goody.js.map +1 -0
  45. package/dist/test/ia-stub.d.ts +22 -0
  46. package/dist/test/ia-stub.js +35 -0
  47. package/dist/test/ia-stub.js.map +1 -0
  48. package/dist/test/no-theater-available.test.d.ts +1 -0
  49. package/dist/test/no-theater-available.test.js +27 -0
  50. package/dist/test/no-theater-available.test.js.map +1 -0
  51. package/package.json +14 -5
  52. package/src/interfaces/custom-theater-interface.ts +28 -0
  53. package/src/interfaces/event-interfaces.ts +17 -24
  54. package/src/interfaces/menu-interfaces.ts +10 -9
  55. package/src/item-navigator.ts +257 -155
  56. package/src/loader.ts +9 -2
  57. package/src/no-theater-available.ts +85 -0
  58. package/test/book-nav-stub.ts +47 -0
  59. package/test/ia-item-navigator.test.ts +438 -0
  60. package/test/ia-stub.ts +79 -0
  61. package/test/no-theater-available.test.ts +32 -0
  62. package/demo/demo-book-manifest.json +0 -1163
  63. package/demo/demo-item-md.json +0 -247
  64. package/src/interfaces/nav-controller-interface.ts +0 -18
  65. package/src/item-inspector/files-by-type/files-by-type-provider.ts +0 -41
  66. package/src/item-inspector/files-by-type/ia-files-by-type.ts +0 -84
  67. package/src/item-inspector/item-inspector.ts +0 -202
  68. package/src/item-inspector/share-provider.ts +0 -51
  69. package/src/item-navigator-js.js +0 -372
  70. package/test/your-webcomponent.test.ts +0 -40
@@ -1,372 +0,0 @@
1
- import { css, html, LitElement } from 'lit-element';
2
- import { nothing } from 'lit-html';
3
- import { IAMenuSlider } from '@internetarchive/ia-menu-slider';
4
- import { ModalConfig } from '@internetarchive/modal-manager';
5
-
6
- export default class ItemNavigator extends LitElement {
7
- static get properties() {
8
- return {
9
- baseHost: { type: String },
10
- item: {
11
- type: Object,
12
- converter(value) {
13
- return !value ? {} : JSON.parse(atob(value));
14
- },
15
- },
16
- itemType: { type: String },
17
- menuShortcuts: {
18
- type: Array,
19
- hasChanged(newVal, oldVal) {
20
- if (newVal !== oldVal) {
21
- return true;
22
- }
23
- return false;
24
- },
25
- },
26
- menuOpened: { type: Boolean },
27
- menuContents: { type: Array },
28
- openMenu: { type: String },
29
- signedIn: {
30
- type: Boolean,
31
- converter: (arg) => {
32
- if (typeof (arg) === 'boolean') {
33
- return arg;
34
- }
35
- return arg === 'true';
36
- },
37
- },
38
- viewportInFullscreen: { type: Boolean },
39
- };
40
- }
41
-
42
- constructor() {
43
- /** TODO: Request BookModel.js
44
- * Request BookNavigator.js
45
- * Show loading spinner
46
- * When JS assets loaded:
47
- * - render book-navigator component
48
- */
49
- super();
50
- this.baseHost = 'archive.org';
51
- this.item = {};
52
- this.itemType = '';
53
- this.menuOpened = false;
54
- this.signedIn = false;
55
- this.menuShortcuts = [];
56
- this.menuContents = [];
57
- this.viewportInFullscreen = false;
58
- this.openMenu = '';
59
- this.renderModalManager();
60
- }
61
-
62
- showItemNavigatorModal({ detail }) {
63
- this.modal.showModal({
64
- config: this.modalConfig,
65
- customModalContent: detail.customModalContent,
66
- });
67
- }
68
-
69
- closeItemNavigatorModal() {
70
- this.modal.closeModal();
71
- }
72
-
73
- /**
74
- * Event handler - handles viewport slot going into fullscreen
75
- * @param {Event} e - custom event object
76
- */
77
- manageViewportFullscreen({ detail }) {
78
- const { isFullScreen } = detail;
79
- this.viewportInFullscreen = isFullScreen;
80
- }
81
-
82
- /**
83
- * Event handler - handles viewport slot going into fullscreen
84
- * @param {Event} e - custom event object
85
- * @param {object} event.detail - custom event detail
86
- * @param {string} detail.action - open, toggle, close
87
- * @param {string} detail.menuId - menu id to be shown
88
- */
89
- manageSideMenuEvents({ detail }) {
90
- const { action = '', menuId = '' } = detail;
91
- if (menuId) {
92
- if (action === 'open') {
93
- this.openShortcut(menuId);
94
- } else if (action === 'toggle') {
95
- this.openMenu = menuId;
96
- this.toggleMenu();
97
- }
98
- }
99
- }
100
-
101
- toggleMenu() {
102
- this.menuOpened = !this.menuOpened;
103
- }
104
-
105
- closeMenu() {
106
- this.menuOpened = false;
107
- }
108
-
109
- /**
110
- * Opens menu to selected menu
111
- * @param {string} selectedMenuId
112
- */
113
- openShortcut(selectedMenuId = '') {
114
- // open sidemenu to proper tab
115
- this.openMenu = selectedMenuId;
116
- this.menuOpened = true;
117
- }
118
-
119
- setOpenMenu({ detail }) {
120
- const { id } = detail;
121
- this.openMenu = id === this.openMenu ? '' : id;
122
- }
123
-
124
- setMenuContents({ detail }) {
125
- this.menuContents = [...detail];
126
- }
127
-
128
- setMenuShortcuts({ detail }) {
129
- this.menuShortcuts = [...detail];
130
- }
131
-
132
- /**
133
- * computes classes for item-navigator <section> node
134
- */
135
- get menuClass() {
136
- const drawerState = this.menuOpened ? 'open' : '';
137
- const fullscreenState = this.viewportInFullscreen ? 'fullscreen' : '';
138
- return `${drawerState} ${fullscreenState}`;
139
- }
140
-
141
- get menuToggleButton() {
142
- // <ia-icon icon="ellipses" style="width: var(--iconWidth); height: var(--iconHeight);"></ia-icon>
143
- return html`
144
- <button class="toggle-menu" @click=${this.toggleMenu.bind(this)} title="Toggle theater side panels">
145
- <div>
146
- <ia-icon-ellipses style="width: var(--iconWidth); height: var(--iconHeight);"></ia-icon-ellipses>
147
- </div>
148
- </button>
149
- `;
150
- }
151
-
152
- get menuSlider() {
153
- return html`
154
- <div id="menu">
155
- <ia-menu-slider
156
- .menus=${this.menuContents}
157
- .open=${true}
158
- .selectedMenu=${this.openMenu}
159
- @menuTypeSelected=${this.setOpenMenu}
160
- @menuSliderClosed=${this.closeMenu}
161
- ?manuallyHandleClose=${true}
162
- ?animateMenuOpen=${false}
163
- ></ia-menu-slider>
164
- </div>
165
- `;
166
- }
167
-
168
- /**
169
- * Returns the shortcut buttons for minimized view
170
- * @return html
171
- */
172
- get shortcuts() {
173
- // todo: aria tags
174
- const shortcuts = this.menuShortcuts.map(({
175
- icon,
176
- id,
177
- }) => html`
178
- <button class="shortcut ${id}" @click="${(e) => { this.openShortcut(id); }}">
179
- ${icon}
180
- </button>
181
- `);
182
-
183
- return html`<div class="shortcuts">${shortcuts}</div>`;
184
- }
185
-
186
- /**
187
- * Returns the side menu given it's open/close state
188
- * @return html
189
- */
190
- get renderSideMenu() {
191
- // todo: aria tags
192
- return html`
193
- <nav>
194
- <div class="minimized">
195
- ${this.shortcuts}
196
- ${this.menuToggleButton}
197
- </div>
198
- ${this.menuSlider}
199
- </nav>
200
- `;
201
- }
202
-
203
- /**
204
- * Given a itemType, this chooses the proper viewport component
205
- * @return html
206
- */
207
- get renderViewport() {
208
- if (this.itemType === 'bookreader') {
209
- return html`
210
- <book-navigator
211
- .baseHost=${this.baseHost}
212
- .book=${this.item}
213
- ?signedIn=${this.signedIn}
214
- ?sideMenuOpen=${this.menuOpened}
215
- @ViewportInFullScreen=${this.manageViewportFullscreen}
216
- @updateSideMenu=${this.manageSideMenuEvents}
217
- @menuUpdated=${this.setMenuContents}
218
- @menuShortcutsUpdated=${this.setMenuShortcuts}
219
- @showItemNavigatorModal=${this.showItemNavigatorModal}
220
- @closeItemNavigatorModal=${this.closeItemNavigatorModal}
221
- >
222
- <div slot="bookreader">
223
- <slot name="bookreader"></slot>
224
- </div>
225
- </book-navigator>
226
- `;
227
- }
228
- return html`<div class="viewport"></div>`;
229
- }
230
-
231
- renderModalManager() {
232
- this.modal = document.createElement('modal-manager');
233
- this.modal.setAttribute('id', 'item-navigator-modal');
234
- this.modalConfig = new ModalConfig();
235
- this.modalConfig.title = 'Delete Bookmark';
236
- this.modalConfig.headline = 'This bookmark contains a note. Deleting it will permanently delete the note. Are you sure?';
237
- this.modalConfig.headerColor = '#194880';
238
- document.body.appendChild(this.modal);
239
- }
240
-
241
- render() {
242
- const renderMenu = this.menuContents.length || this.menuShortcuts.length;
243
- return html`
244
- <div id="frame" class=${this.menuClass}>
245
- <slot name="item-nav-header"></slot>
246
- <div class="menu-and-reader">
247
- ${renderMenu ? this.renderSideMenu : nothing}
248
- <div id="reader">
249
- ${this.renderViewport}
250
- </div>
251
- </div>
252
- </div>
253
- `;
254
- }
255
-
256
- static get styles() {
257
- const subnavWidth = css`var(--menuWidth, 320px)`;
258
- const tabletPlusQuery = css`@media (min-width: 640px)`;
259
- const transitionTiming = css`var(--animationTiming, 200ms)`;
260
- const transitionEffect = css`transform ${transitionTiming} ease-out`;
261
-
262
- return css`
263
- #frame {
264
- position: relative;
265
- overflow: hidden;
266
- }
267
-
268
- #frame.fullscreen,
269
- #frame.fullscreen #reader {
270
- height: 100vh;
271
- }
272
-
273
- button {
274
- cursor: pointer;
275
- padding: 0;
276
- border: 0;
277
- }
278
-
279
- button:focus,
280
- button:active {
281
- outline: none;
282
- }
283
-
284
- .menu-and-reader {
285
- position: relative;
286
- }
287
-
288
- nav button {
289
- background: none;
290
- }
291
-
292
- nav .minimized {
293
- background: rgba(0, 0, 0, .7);
294
- border-bottom-right-radius: 5%;
295
- position: absolute;
296
- padding-top: .6rem;
297
- left: 0;
298
- width: 4rem;
299
- z-index: 2;
300
- }
301
-
302
- nav .minimized button {
303
- width: var(--iconWidth);
304
- height: var(--iconHeight);
305
- margin: auto;
306
- display: inline-flex;
307
- vertical-align: middle;
308
- -webkit-box-align: center;
309
- align-items: center;
310
- -webkit-box-pack: center;
311
- justify-content: center;
312
- width: 4rem;
313
- height: 4rem;
314
- }
315
-
316
- nav .minimized button.toggle-menu > * {
317
- border: 2px solid var(--iconStrokeColor);
318
- border-radius: var(--iconWidth);
319
- width: var(--iconWidth);
320
- height: var(--iconHeight);
321
- margin: auto;
322
- }
323
-
324
- #menu {
325
- position: absolute;
326
- top: 0;
327
- bottom: 0;
328
- left: 0;
329
- z-index: 3;
330
- overflow: hidden;
331
- transform: translateX(-${subnavWidth});
332
- width: ${subnavWidth};
333
- transform: translateX(calc(${subnavWidth} * -1));
334
- transition: ${transitionEffect};
335
- }
336
-
337
- #reader {
338
- position: relative;
339
- z-index: 1;
340
- transition: ${transitionEffect};
341
- transform: translateX(0);
342
- width: 100%;
343
- }
344
-
345
- .open #menu {
346
- width: ${subnavWidth};
347
- transform: translateX(0);
348
- transition: ${transitionEffect};
349
- }
350
-
351
- ${tabletPlusQuery} {
352
- .open #reader {
353
- transition: ${transitionEffect};
354
- transform: translateX(${subnavWidth});
355
- width: calc(100% - ${subnavWidth});
356
- }
357
- }
358
-
359
- #loading-indicator {
360
- display: none;
361
- }
362
-
363
- #loading-indicator.visible {
364
- display: block;
365
- }
366
- `;
367
- }
368
- }
369
-
370
- // customElements.define('ia-icon', IAIcon);
371
- customElements.define('ia-menu-slider', IAMenuSlider);
372
- customElements.define('item-navigator', ItemNavigator);
@@ -1,40 +0,0 @@
1
- // import { html, fixture, expect } from '@open-wc/testing';
2
-
3
- // import type { YourWebComponent } from '../src/your-webcomponent';
4
- // import '../src/your-webcomponent';
5
-
6
- // describe('YourWebComponent', () => {
7
- // it('has a default title "Hey there" and counter 5', async () => {
8
- // const el = await fixture<YourWebComponent>(
9
- // html`<your-webcomponent></your-webcomponent>`
10
- // );
11
-
12
- // expect(el.title).to.equal('Hey there');
13
- // expect(el.counter).to.equal(5);
14
- // });
15
-
16
- // it('increases the counter on button click', async () => {
17
- // const el = await fixture<YourWebComponent>(
18
- // html`<your-webcomponent></your-webcomponent>`
19
- // );
20
- // el.shadowRoot!.querySelector('button')!.click();
21
-
22
- // expect(el.counter).to.equal(6);
23
- // });
24
-
25
- // it('can override the title via attribute', async () => {
26
- // const el = await fixture<YourWebComponent>(
27
- // html`<your-webcomponent title="attribute title"></your-webcomponent>`
28
- // );
29
-
30
- // expect(el.title).to.equal('attribute title');
31
- // });
32
-
33
- // it('passes the a11y audit', async () => {
34
- // const el = await fixture<YourWebComponent>(
35
- // html`<your-webcomponent></your-webcomponent>`
36
- // );
37
-
38
- // await expect(el).shadowDom.to.be.accessible();
39
- // });
40
- // });