@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.
@@ -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,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="theater-header"
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" style=${this.readerHeightStyle}>
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.item) {
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="theater-main" style=${slotVisibility}>
208
+ <div slot="main" style=${slotVisibility}>
218
209
  <slot
219
- name="theater-main"
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 drawerState = this.menuOpened ? 'open' : '';
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
- height: 100%;
495
+ display: flex;
499
496
  }
500
497
 
501
498
  #reader > * {
502
499
  width: 100%;
503
500
  display: flex;
504
- height: 100%;
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% - var(--menuWidth));
519
- float: right;
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, ItemType } from '../src/item-navigator';
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> by default', async () => {
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 when itemType = open', async () => {
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.itemType).to.equal(ItemType.OPEN);
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="theater-main"]')).to
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('ia-no-theater-available')).to.exist;
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);