@internetarchive/ia-item-navigator 0.0.4-4 → 0.0.5
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 +1 -12
- package/demo/app-root.ts +180 -23
- package/demo/index.html +4 -0
- package/dist/demo/app-root.d.ts +16 -4
- package/dist/demo/app-root.js +163 -30
- package/dist/demo/app-root.js.map +1 -1
- package/dist/src/item-navigator.d.ts +1 -5
- package/dist/src/item-navigator.js +30 -32
- package/dist/src/item-navigator.js.map +1 -1
- package/dist/test/ia-item-navigator.test.js +12 -14
- package/dist/test/ia-item-navigator.test.js.map +1 -1
- package/package.json +1 -1
- package/src/item-navigator.ts +28 -31
- package/test/ia-item-navigator.test.ts +13 -15
package/src/item-navigator.ts
CHANGED
@@ -37,9 +37,6 @@ import {
|
|
37
37
|
} from './interfaces/menu-interfaces';
|
38
38
|
import './no-theater-available';
|
39
39
|
|
40
|
-
export enum ItemType {
|
41
|
-
OPEN = 'open',
|
42
|
-
}
|
43
40
|
@customElement('ia-item-navigator')
|
44
41
|
export class ItemNavigator
|
45
42
|
extends LitElement
|
@@ -55,7 +52,7 @@ export class ItemNavigator
|
|
55
52
|
})
|
56
53
|
item?: MetadataResponse;
|
57
54
|
|
58
|
-
@property({ type:
|
55
|
+
@property({ type: Boolean }) viewAvailable: Boolean = true;
|
59
56
|
|
60
57
|
@property({ type: String }) baseHost = 'archive.org';
|
61
58
|
|
@@ -92,9 +89,9 @@ export class ItemNavigator
|
|
92
89
|
|
93
90
|
@query('#frame') private frame!: HTMLDivElement;
|
94
91
|
|
95
|
-
@query('slot[name="
|
92
|
+
@query('slot[name="header"]') private headerSlot!: HTMLSlotElement;
|
96
93
|
|
97
|
-
@query('slot[name="
|
94
|
+
@query('slot[name="main"]') private mainSlot!: HTMLSlotElement;
|
98
95
|
|
99
96
|
disconnectedCallback() {
|
100
97
|
this.removeResizeObserver();
|
@@ -151,12 +148,6 @@ export class ItemNavigator
|
|
151
148
|
return this.viewportInFullscreen ? 'Internet Archive' : '';
|
152
149
|
}
|
153
150
|
|
154
|
-
get readerHeightStyle(): string {
|
155
|
-
const calcFSHeight = `calc(100% - ${this.headerSlot?.offsetHeight || 0}px)`;
|
156
|
-
|
157
|
-
return this.headerSlot?.offsetHeight > 0 ? `height: ${calcFSHeight}` : '';
|
158
|
-
}
|
159
|
-
|
160
151
|
get loadingArea() {
|
161
152
|
return html`
|
162
153
|
<div class="loading-area">
|
@@ -180,13 +171,16 @@ export class ItemNavigator
|
|
180
171
|
|
181
172
|
render(): TemplateResult {
|
182
173
|
const displayReaderClass = this.loaded ? '' : 'hidden';
|
174
|
+
const headerHeight =
|
175
|
+
(this.headerSlot?.assignedNodes()[0] as HTMLElement)?.offsetHeight || 0;
|
183
176
|
return html`
|
184
177
|
<div id="frame" class=${this.menuClass}>
|
185
178
|
<slot
|
186
|
-
name="
|
179
|
+
name="header"
|
180
|
+
style=${`height: ${headerHeight}px`}
|
187
181
|
@slotchange=${(e: Event) => this.slotChange(e, 'header')}
|
188
182
|
></slot>
|
189
|
-
<div class="menu-and-reader"
|
183
|
+
<div class="menu-and-reader">
|
190
184
|
${this.shouldRenderMenu ? this.renderSideMenu : nothing}
|
191
185
|
<div id="reader" class=${displayReaderClass}>
|
192
186
|
${this.renderViewport}
|
@@ -205,19 +199,15 @@ export class ItemNavigator
|
|
205
199
|
}
|
206
200
|
|
207
201
|
get renderViewport(): TemplateResult | typeof nothing {
|
208
|
-
if (!this.
|
209
|
-
return nothing;
|
210
|
-
}
|
211
|
-
if (this.itemType !== ItemType.OPEN) {
|
202
|
+
if (!this.viewAvailable) {
|
212
203
|
return this.noTheaterView;
|
213
204
|
}
|
214
205
|
|
215
206
|
const slotVisibility = !this.loaded ? 'opacity: 0;' : 'opacity: 1;';
|
216
207
|
return html`
|
217
|
-
<div slot="
|
208
|
+
<div slot="main" style=${slotVisibility}>
|
218
209
|
<slot
|
219
|
-
name="
|
220
|
-
style=${this.readerHeightStyle}
|
210
|
+
name="main"
|
221
211
|
@slotchange=${(e: Event) => this.slotChange(e, 'main')}
|
222
212
|
></slot>
|
223
213
|
</div>
|
@@ -348,7 +338,9 @@ export class ItemNavigator
|
|
348
338
|
|
349
339
|
/** Misc Render */
|
350
340
|
get menuClass(): string {
|
351
|
-
const
|
341
|
+
const hasMenuOrShortcuts =
|
342
|
+
this.menuContents?.length || this.menuShortcuts?.length;
|
343
|
+
const drawerState = this.menuOpened && hasMenuOrShortcuts ? 'open' : '';
|
352
344
|
const fullscreenState = this.viewportInFullscreen ? 'fullscreen' : '';
|
353
345
|
return `${drawerState} ${fullscreenState} ${this.openMenuState}`;
|
354
346
|
}
|
@@ -364,8 +356,6 @@ export class ItemNavigator
|
|
364
356
|
:host,
|
365
357
|
#frame,
|
366
358
|
.menu-and-reader {
|
367
|
-
min-height: inherit;
|
368
|
-
height: inherit;
|
369
359
|
position: relative;
|
370
360
|
overflow: hidden;
|
371
361
|
display: block;
|
@@ -373,7 +363,6 @@ export class ItemNavigator
|
|
373
363
|
|
374
364
|
:host,
|
375
365
|
#frame,
|
376
|
-
.menu-and-reader,
|
377
366
|
.loading-area,
|
378
367
|
.loading-view {
|
379
368
|
min-height: inherit;
|
@@ -382,7 +371,6 @@ export class ItemNavigator
|
|
382
371
|
|
383
372
|
slot {
|
384
373
|
display: block;
|
385
|
-
overflow: hidden;
|
386
374
|
width: 100%;
|
387
375
|
}
|
388
376
|
|
@@ -394,6 +382,8 @@ export class ItemNavigator
|
|
394
382
|
#frame {
|
395
383
|
background-color: ${theaterBg};
|
396
384
|
color-scheme: dark;
|
385
|
+
display: flex;
|
386
|
+
flex-direction: column;
|
397
387
|
}
|
398
388
|
|
399
389
|
#frame.fullscreen {
|
@@ -406,18 +396,23 @@ export class ItemNavigator
|
|
406
396
|
}
|
407
397
|
|
408
398
|
.loading-view {
|
399
|
+
height: 100%;
|
409
400
|
display: flex;
|
410
401
|
align-items: center;
|
411
402
|
justify-content: center;
|
412
403
|
}
|
413
404
|
|
405
|
+
.loading-area {
|
406
|
+
width: 100%;
|
407
|
+
}
|
408
|
+
|
414
409
|
ia-itemnav-loader {
|
415
410
|
display: block;
|
416
411
|
width: 100%;
|
417
412
|
}
|
418
413
|
|
419
414
|
.hidden {
|
420
|
-
display: none;
|
415
|
+
display: none !important;
|
421
416
|
}
|
422
417
|
|
423
418
|
button {
|
@@ -433,6 +428,8 @@ export class ItemNavigator
|
|
433
428
|
|
434
429
|
.menu-and-reader {
|
435
430
|
position: relative;
|
431
|
+
display: flex;
|
432
|
+
flex: 1;
|
436
433
|
}
|
437
434
|
|
438
435
|
nav button {
|
@@ -495,13 +492,13 @@ export class ItemNavigator
|
|
495
492
|
z-index: 1;
|
496
493
|
transform: translateX(0);
|
497
494
|
width: 100%;
|
498
|
-
|
495
|
+
display: flex;
|
499
496
|
}
|
500
497
|
|
501
498
|
#reader > * {
|
502
499
|
width: 100%;
|
503
500
|
display: flex;
|
504
|
-
|
501
|
+
flex: 1;
|
505
502
|
}
|
506
503
|
|
507
504
|
.open.overlay #reader {
|
@@ -515,8 +512,8 @@ export class ItemNavigator
|
|
515
512
|
}
|
516
513
|
|
517
514
|
.open.shift #reader {
|
518
|
-
width: calc(100% -
|
519
|
-
|
515
|
+
width: calc(100% - ${subnavWidth});
|
516
|
+
margin-left: ${subnavWidth};
|
520
517
|
transition: ${transitionEffect};
|
521
518
|
}
|
522
519
|
`;
|
@@ -4,7 +4,7 @@ import Sinon from 'sinon';
|
|
4
4
|
|
5
5
|
import { SharedResizeObserver } from '@internetarchive/shared-resize-observer';
|
6
6
|
import { ModalManager } from '@internetarchive/modal-manager';
|
7
|
-
import { ItemNavigator
|
7
|
+
import { ItemNavigator } from '../src/item-navigator';
|
8
8
|
import '../src/item-navigator';
|
9
9
|
|
10
10
|
import { ItemStub, menuProvider, shortcut } from '../test/ia-stub';
|
@@ -22,25 +22,24 @@ afterEach(() => {
|
|
22
22
|
|
23
23
|
describe('ItemNavigator', () => {
|
24
24
|
describe('Theaters', () => {
|
25
|
-
it('shows <ia-no-theater-available>
|
25
|
+
it('shows <ia-no-theater-available> if told', async () => {
|
26
26
|
const el = await fixture<ItemNavigator>(
|
27
27
|
html`<ia-item-navigator .item=${new ItemStub()}></ia-item-navigator>`
|
28
28
|
);
|
29
|
+
el.viewAvailable = false;
|
30
|
+
await el.updateComplete;
|
31
|
+
expect(el.viewAvailable).to.be.false;
|
29
32
|
expect(el.shadowRoot?.querySelector('ia-no-theater-available')).to.exist;
|
30
|
-
expect(el.itemType).to.not.equal(ItemType.OPEN);
|
31
33
|
});
|
32
|
-
it('opens main slot
|
34
|
+
it('opens main slot by default', async () => {
|
33
35
|
const el = await fixture<ItemNavigator>(
|
34
36
|
html`<ia-item-navigator .item=${new ItemStub()}></ia-item-navigator>`
|
35
37
|
);
|
36
|
-
el.itemType = ItemType.OPEN;
|
37
|
-
await el.updateComplete;
|
38
38
|
|
39
|
-
expect(el.
|
39
|
+
expect(el.viewAvailable).to.be.true;
|
40
40
|
expect(el.shadowRoot?.querySelector('ia-no-theater-available')).to.be
|
41
41
|
.null;
|
42
|
-
expect(el.shadowRoot?.querySelector('slot[name="
|
43
|
-
.exist;
|
42
|
+
expect(el.shadowRoot?.querySelector('slot[name="main"]')).to.exist;
|
44
43
|
});
|
45
44
|
});
|
46
45
|
describe('`el.loaded`', () => {
|
@@ -65,14 +64,16 @@ describe('ItemNavigator', () => {
|
|
65
64
|
html`<ia-item-navigator .item=${new ItemStub()}></ia-item-navigator>`
|
66
65
|
);
|
67
66
|
|
67
|
+
el.loaded = true;
|
68
|
+
await el.updateComplete;
|
68
69
|
const mainTheaterSection = el.shadowRoot?.querySelector('#reader');
|
69
70
|
expect(mainTheaterSection?.classList.contains('hide')).to.be.false;
|
70
71
|
expect(el.loaded).to.be.true;
|
71
72
|
// `loaded` property is reflected as DOM attribute
|
72
73
|
expect(el.hasAttribute('loaded')).to.equal(true);
|
73
|
-
expect(el.shadowRoot?.querySelector('
|
74
|
+
expect(el.shadowRoot?.querySelector('slot[name="main"]')).to.exist;
|
74
75
|
});
|
75
|
-
it('listens to `@loadingStateUpdated` to update `loaded`', async () => {
|
76
|
+
it('listens to `@loadingStateUpdated` to update `loaded` for <no-theater-available>', async () => {
|
76
77
|
const el = await fixture<ItemNavigator>(
|
77
78
|
html`<ia-item-navigator></ia-item-navigator>`
|
78
79
|
);
|
@@ -81,15 +82,12 @@ describe('ItemNavigator', () => {
|
|
81
82
|
const spy = Sinon.spy();
|
82
83
|
el.loadingStateUpdated = spy;
|
83
84
|
el.loaded = null;
|
85
|
+
el.viewAvailable = false;
|
84
86
|
await el.updateComplete;
|
85
87
|
// check base properties
|
86
88
|
expect(el.loaded).to.equal(null);
|
87
89
|
expect(el.item).to.be.undefined;
|
88
90
|
|
89
|
-
// hydrate item
|
90
|
-
el.item = new ItemStub();
|
91
|
-
await el.updateComplete;
|
92
|
-
|
93
91
|
// spy fires
|
94
92
|
expect(spy.called).to.equal(true);
|
95
93
|
expect(spy.callCount).to.equal(1);
|