@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.
- package/README.md +29 -19
- package/demo/app-root.ts +113 -22
- package/demo/index.html +12 -4
- package/dist/demo/app-root.d.ts +27 -7
- package/dist/demo/app-root.js +98 -23
- package/dist/demo/app-root.js.map +1 -1
- package/dist/src/interfaces/custom-theater-interface.d.ts +20 -0
- package/dist/src/interfaces/custom-theater-interface.js +2 -0
- package/dist/src/interfaces/custom-theater-interface.js.map +1 -0
- package/dist/src/interfaces/event-interfaces.d.ts +13 -23
- package/dist/src/interfaces/event-interfaces.js.map +1 -1
- package/dist/src/interfaces/menu-interfaces.d.ts +7 -7
- package/dist/src/interfaces/menu-interfaces.js.map +1 -1
- package/dist/src/interfaces/nav-controller-interface.d.ts +11 -6
- package/dist/src/interfaces/nav-controller-interface.js.map +1 -1
- package/dist/src/item-inspector/files-by-type/files-by-type-provider.js +5 -3
- package/dist/src/item-inspector/files-by-type/files-by-type-provider.js.map +1 -1
- package/dist/src/item-inspector/files-by-type/ia-files-by-type.d.ts +1 -0
- package/dist/src/item-inspector/files-by-type/ia-files-by-type.js +14 -0
- package/dist/src/item-inspector/files-by-type/ia-files-by-type.js.map +1 -1
- package/dist/src/item-inspector/item-inspector.d.ts +0 -31
- package/dist/src/item-inspector/item-inspector.js +253 -181
- package/dist/src/item-inspector/item-inspector.js.map +1 -1
- package/dist/src/item-inspector/visual-mod-provider.d.ts +19 -0
- package/dist/src/item-inspector/visual-mod-provider.js +46 -0
- package/dist/src/item-inspector/visual-mod-provider.js.map +1 -0
- package/dist/src/item-navigator.d.ts +50 -28
- package/dist/src/item-navigator.js +216 -132
- package/dist/src/item-navigator.js.map +1 -1
- package/dist/src/loader.d.ts +5 -0
- package/dist/src/loader.js +8 -2
- package/dist/src/loader.js.map +1 -1
- package/dist/src/no-theater-available.d.ts +9 -0
- package/dist/src/no-theater-available.js +79 -0
- package/dist/src/no-theater-available.js.map +1 -0
- package/dist/test/book-nav-stub.d.ts +22 -0
- package/dist/test/book-nav-stub.js +49 -0
- package/dist/test/book-nav-stub.js.map +1 -0
- package/dist/test/ia-item-navigator.test.d.ts +2 -0
- package/dist/test/ia-item-navigator.test.js +317 -0
- package/dist/test/ia-item-navigator.test.js.map +1 -0
- package/dist/test/ia-stub-goody.d.ts +210 -0
- package/dist/test/ia-stub-goody.js +276 -0
- package/dist/test/ia-stub-goody.js.map +1 -0
- package/dist/test/ia-stub.d.ts +22 -0
- package/dist/test/ia-stub.js +35 -0
- package/dist/test/ia-stub.js.map +1 -0
- package/dist/test/no-theater-available.test.d.ts +1 -0
- package/dist/test/no-theater-available.test.js +27 -0
- package/dist/test/no-theater-available.test.js.map +1 -0
- package/package.json +14 -5
- package/src/interfaces/custom-theater-interface.ts +28 -0
- package/src/interfaces/event-interfaces.ts +17 -24
- package/src/interfaces/menu-interfaces.ts +10 -9
- package/src/item-navigator.ts +257 -155
- package/src/loader.ts +9 -2
- package/src/no-theater-available.ts +85 -0
- package/test/book-nav-stub.ts +47 -0
- package/test/ia-item-navigator.test.ts +438 -0
- package/test/ia-stub.ts +79 -0
- package/test/no-theater-available.test.ts +32 -0
- package/demo/demo-book-manifest.json +0 -1163
- package/demo/demo-item-md.json +0 -247
- package/src/interfaces/nav-controller-interface.ts +0 -18
- package/src/item-inspector/files-by-type/files-by-type-provider.ts +0 -41
- package/src/item-inspector/files-by-type/ia-files-by-type.ts +0 -84
- package/src/item-inspector/item-inspector.ts +0 -202
- package/src/item-inspector/share-provider.ts +0 -51
- package/src/item-navigator-js.js +0 -372
- package/test/your-webcomponent.test.ts +0 -40
package/src/item-navigator-js.js
DELETED
@@ -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
|
-
// });
|