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