@teipublisher/pb-components 1.36.1 → 1.37.0

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.
@@ -0,0 +1,154 @@
1
+ import { LitElement } from 'lit-element';
2
+ import TomSelect from "tom-select";
3
+ import { pbMixin } from './pb-mixin.js';
4
+ import { resolveURL } from './utils.js';
5
+
6
+ function importTheme(theme) {
7
+ if (document.getElementById('__pb-multi-select-css')) {
8
+ return;
9
+ }
10
+ const themes = resolveURL('../css/tom-select');
11
+ const link = document.createElement('link');
12
+ link.id = '__pb-multi-select-css';
13
+ link.href = `${themes}/tom-select.${theme}.min.css`;
14
+ link.rel = 'stylesheet';
15
+ document.head.appendChild(link);
16
+ }
17
+
18
+ const renderDefault = (data) =>
19
+ data ? `<div>${data.text}</div>` : '';
20
+
21
+ /**
22
+ * Provides a combo box, i.e. a combination of an input with a dropdown.
23
+ * Items to select from may be obtained from a remote data source.
24
+ *
25
+ * The form control to be used (either a select or input) should be passed
26
+ * in the content of the element. If no control is provided, a simple `<input>`
27
+ * will be created.
28
+ *
29
+ */
30
+ export class PbComboBox extends pbMixin(LitElement) {
31
+ static get properties() {
32
+ return {
33
+ ...super.properties,
34
+ /**
35
+ * A remote data source to use. The component will pass the text entered by the user
36
+ * in parameter `query`. It expects a JSON array of objects with each object describing
37
+ * one item:
38
+ *
39
+ * ```json
40
+ * {
41
+ * "text": "Text to show as label",
42
+ * "value": "value-to-use"
43
+ * }
44
+ * ```
45
+ */
46
+ source: {
47
+ type: String
48
+ },
49
+ /**
50
+ * Automatically close the dropdown once the user made a selection
51
+ */
52
+ closeAfterSelect: {
53
+ type: Boolean,
54
+ attribute: 'close-after-select'
55
+ },
56
+ /**
57
+ * Preload all items from the remote data source at startup
58
+ */
59
+ preload: {
60
+ type: Boolean
61
+ },
62
+ /**
63
+ * Name of the event to be emitted when the user leaves the form control
64
+ */
65
+ onBlur: {
66
+ type: String,
67
+ attribute: 'on-blur'
68
+ },
69
+ /**
70
+ * Name of the event to be emitted when the value of the form control has changed
71
+ */
72
+ onChange: {
73
+ type: String,
74
+ attribute: 'on-change'
75
+ }
76
+ };
77
+ }
78
+
79
+ /**
80
+ * Set a javascript function to be called whenever an item
81
+ * needs to be rendered. The function will be passed the data
82
+ * object of the current item as argument.
83
+ *
84
+ * @param {Function} callbackFunction
85
+ */
86
+ set renderItem(callbackFunction) {
87
+ this.renderFunction = callbackFunction;
88
+ }
89
+
90
+ constructor() {
91
+ super();
92
+ this.theme = 'default';
93
+ this.source = null;
94
+ this.closeAfterSelect = false;
95
+ this.preload = false;
96
+ this.renderFunction = renderDefault;
97
+ this.onBlur = 'pb-combo-box-blur';
98
+ this.onChange = 'pb-combo-box-change';
99
+ }
100
+
101
+ connectedCallback() {
102
+ super.connectedCallback();
103
+ }
104
+
105
+ firstUpdated() {
106
+ importTheme(this.theme);
107
+
108
+ let input = this.querySelector('select,input');
109
+
110
+ if (!input) {
111
+ // create input if none was passed
112
+ input = document.createElement('input');
113
+ this.appendChild(input);
114
+ }
115
+ input.autocomplete = false;
116
+
117
+ PbComboBox.waitOnce('pb-page-ready', () => {
118
+ const options = {};
119
+ if (this.source) {
120
+ const url = this.toAbsoluteURL(this.source);
121
+ options.labelField = 'text';
122
+ options.valueField = 'value';
123
+ options.searchField = ['text', 'value'];
124
+ options.preload = this.preload;
125
+ options.load = (query, callback) => {
126
+ fetch(`${url}?query=${encodeURIComponent(query)}`, {
127
+ method: 'GET',
128
+ mode: 'cors',
129
+ credentials: 'same-origin'
130
+ })
131
+ .then(response => response.json())
132
+ .then(json => {
133
+ callback(json);
134
+ }).catch(()=>{
135
+ callback();
136
+ });
137
+ };
138
+ options.render = {
139
+ option: this.renderFunction,
140
+ item: this.renderFunction
141
+ };
142
+ }
143
+ options.closeAfterSelect = this.closeAfterSelect;
144
+ options.onBlur = () => this.emitTo(this.onBlur);
145
+ options.onChange = () => this.emitTo(this.onChange);
146
+ this._select = new TomSelect(input, options);
147
+ });
148
+ }
149
+
150
+ createRenderRoot() {
151
+ return this;
152
+ }
153
+ }
154
+ customElements.define('pb-combo-box', PbComboBox);
@@ -59,6 +59,7 @@ import './pb-blacklab-highlight.js';
59
59
  import './pb-table-grid.js';
60
60
  import './pb-split-list.js';
61
61
  import './pb-timeline.js';
62
+ import './pb-combo-box.js';
62
63
 
63
64
  import '@polymer/iron-icons/editor-icons';
64
65
  import '@polymer/iron-icons/social-icons';
@@ -85,6 +85,21 @@ export class PbFacsimile extends pbMixin(LitElement) {
85
85
  type: Number,
86
86
  attribute: 'visibility-ratio'
87
87
  },
88
+ /**
89
+ * If set, thumbnails of all images are shown in a reference strip at the
90
+ * bottom of the viewer.
91
+ */
92
+ referenceStrip: {
93
+ type: Boolean,
94
+ attribute: 'reference-strip'
95
+ },
96
+ /**
97
+ * Size ratio for the reference strip thumbnails. 0.2 by default.
98
+ */
99
+ referenceStripSizeRatio: {
100
+ type: Number,
101
+ attribute: 'reference-strip-size-ratio'
102
+ },
88
103
  /**
89
104
  * Type of the source of the image to display: either 'iiif' or 'image'
90
105
  * (for simple image links not served via IIIF).
@@ -134,6 +149,8 @@ export class PbFacsimile extends pbMixin(LitElement) {
134
149
  this.showFullPageControl = false;
135
150
  this.showRotationControl = false;
136
151
  this.constrainDuringPan = false;
152
+ this.referenceStrip = false;
153
+ this.referenceStripSizeRatio = 0.2;
137
154
  this.src = '';
138
155
  this.prefixUrl = '../images/openseadragon/';
139
156
  this.loaded = false;
@@ -197,7 +214,7 @@ export class PbFacsimile extends pbMixin(LitElement) {
197
214
  // Init openseadragon
198
215
  _initOpenSeadragon() {
199
216
  const prefixUrl = resolveURL(this.prefixUrl + (this.prefixUrl.endsWith("/") ? "" : "/"));
200
- this.viewer = OpenSeadragon({
217
+ const options = {
201
218
  element: this.shadowRoot.getElementById('viewer'),
202
219
  prefixUrl,
203
220
  preserveViewport: true,
@@ -213,7 +230,12 @@ export class PbFacsimile extends pbMixin(LitElement) {
213
230
  minZoomLevel: 1,
214
231
  defaultZoomLevel: this.defaultZoomLevel,
215
232
  constrainDuringPan: true
216
- });
233
+ };
234
+ if (this.referenceStrip) {
235
+ options.showReferenceStrip = true;
236
+ options.referenceStripSizeRatio = this.referenceStripSizeRatio;
237
+ }
238
+ this.viewer = OpenSeadragon(options);
217
239
 
218
240
  this.viewer.addHandler('open', () => {
219
241
  this.resetZoom();
package/src/pb-page.js CHANGED
@@ -229,6 +229,15 @@ class PbPage extends pbMixin(LitElement) {
229
229
  return;
230
230
  }
231
231
 
232
+ const slot = this.shadowRoot.querySelector('slot');
233
+ slot.addEventListener('slotchange', () => {
234
+ const ev = new CustomEvent('pb-page-loaded', {
235
+ bubbles: true,
236
+ composed: true
237
+ });
238
+ this.dispatchEvent(ev);
239
+ }, { once: true });
240
+
232
241
  const defaultLocales = resolveURL('../i18n/') + '{{ns}}/{{lng}}.json';
233
242
  console.log('<pb-page> Loading locales. common: %s; additional: %s; namespaces: %o',
234
243
  defaultLocales, this.locales, this._localeFallbacks);
package/src/pb-popover.js CHANGED
@@ -74,7 +74,7 @@ export function loadTippyStyles(root, theme) {
74
74
  * unless defined otherwise; clicking anywhere on the page will close the popup.
75
75
  * @prop {"click" | "mouseenter" | "focus" | "focusin"} trigger - Defines one or more actions (space separated) which should cause
76
76
  * the popover to show. If property `persistent` is set, `trigger` will by default be set to `click`.
77
- * @prop {String} poupClass - Additional class names which will be added to the popup element.
77
+ * @prop {String} popupClass - Additional class names which will be added to the popup element.
78
78
  * Use this to apply a specific style to certain popovers, but not others.
79
79
  * @prop {String} remote - An optional URL to asynchronously load the popover's content from. Content will
80
80
  * be loaded after the popover is displayed. The downloaded HTML content will replace the text set via the alternate slot.
@@ -282,6 +282,10 @@ export class PbTimeline extends pbMixin(LitElement) {
282
282
  scopes: {
283
283
  type: Array
284
284
  },
285
+ maxInterval: {
286
+ type: Number,
287
+ attribute: 'max-interval'
288
+ },
285
289
  /**
286
290
  * Endpoint to load timeline data from. Expects response to be an
287
291
  * object with key value pairs for (date, hits).
@@ -315,6 +319,7 @@ export class PbTimeline extends pbMixin(LitElement) {
315
319
  this.endDate = '';
316
320
  this.scope = '';
317
321
  this.scopes = ["D", "W", "M", "Y", "5Y", "10Y"];
322
+ this.maxInterval = 60;
318
323
  this.url = '';
319
324
  this.auto = false;
320
325
  this.resettable = false;
@@ -516,10 +521,18 @@ export class PbTimeline extends pbMixin(LitElement) {
516
521
  endDateStr: this.searchResult.getEndOfRangeDate(this.dataObj.scope, endDateStr),
517
522
  scope: this.dataObj.scope,
518
523
  categories,
519
- count: itemCount
524
+ count: itemCount,
525
+ label: this.label
520
526
  });
521
527
  } else {
522
- this.emitTo('pb-timeline-date-changed', { startDateStr, endDateStr: null, scope: this.dataObj.scope, categories, count: itemCount });
528
+ this.emitTo('pb-timeline-date-changed', {
529
+ startDateStr,
530
+ endDateStr: null,
531
+ scope: this.dataObj.scope,
532
+ categories,
533
+ count: itemCount,
534
+ label: this.label
535
+ });
523
536
  }
524
537
  } else {
525
538
  this.emitTo('pb-timeline-daterange-changed', {
@@ -527,7 +540,8 @@ export class PbTimeline extends pbMixin(LitElement) {
527
540
  endDateStr,
528
541
  categories,
529
542
  scope: this.dataObj.scope,
530
- count: itemCount
543
+ count: itemCount,
544
+ label: this.label
531
545
  });
532
546
  }
533
547
  }
@@ -732,15 +746,12 @@ export class PbTimeline extends pbMixin(LitElement) {
732
746
  } else {
733
747
  newJsonData = data;
734
748
  }
735
- this.searchResult = new SearchResultService(newJsonData, 60, this.scopes);
749
+ this.searchResult = new SearchResultService(newJsonData, this.maxInterval, this.scopes);
736
750
  this.setData(this.searchResult.export(this.scope));
737
- this.dispatchEvent(new CustomEvent('pb-timeline-loaded', {
738
- detail: {
739
- value: true
740
- },
741
- composed: true,
742
- bubbles: true
743
- }));
751
+ this.emitTo('pb-timeline-loaded', {
752
+ value: true,
753
+ label: this.label
754
+ });
744
755
  }
745
756
 
746
757
  }