@internetarchive/ia-item-navigator 0.0.4-3 → 0.0.5-2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
- }