@teipublisher/pb-components 2.26.1-next.2 → 3.0.0-next-4.1
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/.github/workflows/docker-cypress.yml +54 -0
- package/.github/workflows/main.yml +6 -4
- package/.github/workflows/node.js.yml +56 -21
- package/.github/workflows/release.js.yml +19 -17
- package/.releaserc.json +1 -1
- package/CHANGELOG.md +351 -9
- package/Dockerfile +78 -70
- package/README.md +112 -4
- package/css/components.css +5 -5
- package/css/gridjs/mermaid.min.css +1 -1
- package/css/leaflet/Control.Geocoder.css +1 -126
- package/css/leaflet/images/layers.png +0 -0
- package/css/tify/tify.css +6 -5
- package/css/tom-select/tom-select.bootstrap4.min.css +1 -1
- package/css/tom-select/tom-select.bootstrap5.min.css +1 -1
- package/css/tom-select/tom-select.default.min.css +1 -1
- package/css/tom-select/tom-select.default.min.css.map +1 -0
- package/css/tom-select/tom-select.min.css +1 -1
- package/cypress.config.js +84 -0
- package/dist/api.html +1 -1
- package/dist/css/design-system.css +607 -0
- package/dist/demo/bundle-test.html +4 -3
- package/dist/demo/components.css +46 -1
- package/dist/demo/design-system.html +710 -0
- package/dist/demo/dts-client.html +2 -2
- package/dist/demo/pb-autocomplete.html +23 -11
- package/dist/demo/pb-autocomplete2.html +66 -55
- package/dist/demo/pb-autocomplete3.html +17 -8
- package/dist/demo/pb-blacklab-highlight.html +28 -11
- package/dist/demo/pb-blacklab-results.html +3 -2
- package/dist/demo/pb-browse-docs.html +24 -24
- package/dist/demo/pb-browse-docs2.html +3 -3
- package/dist/demo/pb-clipboard.html +32 -28
- package/dist/demo/pb-code-editor.html +6 -6
- package/dist/demo/pb-code-highlight.html +63 -63
- package/dist/demo/pb-codepen.html +1 -1
- package/dist/demo/pb-collapse.html +1 -1
- package/dist/demo/pb-collapse2.html +2 -2
- package/dist/demo/pb-combo-box.html +135 -130
- package/dist/demo/pb-custom-form.html +64 -55
- package/dist/demo/pb-dialog.html +12 -6
- package/dist/demo/pb-document.html +1 -1
- package/dist/demo/pb-download.html +68 -59
- package/dist/demo/pb-drawer.html +67 -46
- package/dist/demo/pb-drawer2.html +65 -58
- package/dist/demo/pb-edit-app.html +2 -2
- package/dist/demo/pb-edit-xml.html +1 -1
- package/dist/demo/pb-facsimile-2.html +26 -11
- package/dist/demo/pb-facsimile-3.html +25 -10
- package/dist/demo/pb-facsimile-dedup-test-2.html +48 -0
- package/dist/demo/pb-facsimile-dedup-test.html +48 -0
- package/dist/demo/pb-facsimile.html +4 -4
- package/dist/demo/pb-formula.html +1 -1
- package/dist/demo/pb-grid.html +22 -8
- package/dist/demo/pb-highlight.html +2 -2
- package/dist/demo/pb-i18n-simple.html +1 -0
- package/dist/demo/pb-i18n.html +15 -5
- package/dist/demo/pb-image-strip-standalone.html +2 -2
- package/dist/demo/pb-image-strip-view.html +2 -2
- package/dist/demo/pb-leaflet-map.html +3 -3
- package/dist/demo/pb-leaflet-map2.html +2 -2
- package/dist/demo/pb-leaflet-map3.html +3 -3
- package/dist/demo/pb-link.html +1 -1
- package/dist/demo/pb-load.html +2 -6
- package/dist/demo/pb-login.html +1 -3
- package/dist/demo/pb-manage-odds.html +9 -4
- package/dist/demo/pb-markdown.html +1 -1
- package/dist/demo/pb-media-query.html +2 -2
- package/dist/demo/pb-mei.html +2 -2
- package/dist/demo/pb-mei2.html +2 -2
- package/dist/demo/pb-message.html +2 -3
- package/dist/demo/pb-odd-editor.html +54 -52
- package/dist/demo/pb-page-header.html +27 -0
- package/dist/demo/pb-popover.html +1 -1
- package/dist/demo/pb-print-preview.html +2 -2
- package/dist/demo/pb-progress.html +4 -4
- package/dist/demo/pb-repeat.html +32 -36
- package/dist/demo/pb-search.html +16 -5
- package/dist/demo/pb-search2.html +4 -4
- package/dist/demo/pb-search3.html +3 -3
- package/dist/demo/pb-search4.html +3 -3
- package/dist/demo/pb-select-feature.html +4 -4
- package/dist/demo/pb-select-feature2.html +4 -4
- package/dist/demo/pb-select-feature3.html +2 -2
- package/dist/demo/pb-select-i18n.html +58 -53
- package/dist/demo/pb-select-odd.html +1 -1
- package/dist/demo/pb-select.html +190 -75
- package/dist/demo/pb-select2.html +91 -37
- package/dist/demo/pb-select3.html +109 -41
- package/dist/demo/pb-svg.html +1 -1
- package/dist/demo/pb-table-grid.html +26 -15
- package/dist/demo/pb-tabs.html +15 -7
- package/dist/demo/pb-tify.html +7 -7
- package/dist/demo/pb-timeline.html +1 -1
- package/dist/demo/pb-timeline2.html +1 -1
- package/dist/demo/pb-toggle-feature.html +26 -23
- package/dist/demo/pb-toggle-feature2.html +4 -4
- package/dist/demo/pb-toggle-feature3.html +2 -2
- package/dist/demo/pb-toggle-feature4.html +56 -54
- package/dist/demo/pb-version.html +2 -2
- package/dist/demo/pb-view.html +78 -40
- package/dist/demo/pb-view2.html +69 -46
- package/dist/demo/pb-view3.html +53 -48
- package/dist/demo/pb-view4.html +70 -49
- package/dist/demo/pb-zoom.html +2 -2
- package/dist/{es-global-bridge-d8ce175d.js → es-global-bridge-D8ZcUcx_.js} +0 -4
- package/dist/focus-mixin-VCsFap6b.js +768 -0
- package/dist/images/icons.svg +217 -0
- package/dist/jinn-codemirror-DETLdm08.js +1 -0
- package/dist/lib/openseadragon.min.js +80 -0
- package/dist/lib/openseadragon.min.js.map +1 -0
- package/dist/pb-code-editor.js +25 -20
- package/dist/pb-component-docs.js +414 -3225
- package/dist/pb-components-bundle.js +3046 -4402
- package/dist/pb-dialog-tklYGWfc.js +121 -0
- package/dist/pb-edit-app.js +208 -107
- package/dist/pb-elements.json +716 -249
- package/dist/pb-facsimile.js +46 -0
- package/dist/pb-i18n-C0NDma4h.js +1 -0
- package/dist/pb-leaflet-map.js +23 -23
- package/dist/pb-mei.js +152 -134
- package/dist/pb-mixin-DHoWQheB.js +1 -0
- package/dist/pb-odd-editor.js +1671 -1231
- package/dist/pb-tify.js +1 -27
- package/dist/unsafe-html-D5VGo9Oq.js +1 -0
- package/dist/urls-BEONu_g4.js +1 -0
- package/eslint.config.mjs +92 -0
- package/gh-pages.js +5 -3
- package/i18n/common/en.json +6 -0
- package/i18n/common/pl.json +2 -2
- package/images/icons.svg +217 -0
- package/index.html +0 -5
- package/lib/leaflet-src.js.map +1 -0
- package/lib/leaflet.markercluster-src.js.map +1 -0
- package/lib/openseadragon.min.js +6 -6
- package/package.json +56 -81
- package/pb-elements.json +716 -249
- package/rollup.config.mjs +312 -0
- package/src/assets/components.css +5 -5
- package/src/assets/design-system.css +607 -0
- package/src/authority/airtable.js +20 -21
- package/src/authority/anton.js +129 -129
- package/src/authority/custom.js +70 -27
- package/src/authority/geonames.js +38 -32
- package/src/authority/gnd.js +50 -42
- package/src/authority/kbga.js +136 -134
- package/src/authority/metagrid.js +44 -46
- package/src/authority/reconciliation.js +66 -68
- package/src/authority/registry.js +4 -4
- package/src/docs/demo-utils.js +91 -0
- package/src/docs/pb-component-docs.js +287 -147
- package/src/docs/pb-component-view.js +380 -273
- package/src/docs/pb-components-list.js +115 -51
- package/src/docs/pb-demo-snippet.js +199 -174
- package/src/dts-client.js +306 -303
- package/src/dts-select-endpoint.js +125 -85
- package/src/parse-date-service.js +184 -135
- package/src/pb-ajax.js +175 -173
- package/src/pb-authority-lookup.js +198 -158
- package/src/pb-autocomplete.js +731 -313
- package/src/pb-blacklab-highlight.js +266 -260
- package/src/pb-blacklab-results.js +230 -225
- package/src/pb-browse-docs.js +601 -484
- package/src/pb-browse.js +68 -65
- package/src/pb-clipboard.js +97 -76
- package/src/pb-code-editor.js +111 -103
- package/src/pb-code-highlight.js +234 -204
- package/src/pb-codepen.js +81 -73
- package/src/pb-collapse.js +265 -152
- package/src/pb-combo-box.js +191 -191
- package/src/pb-components-bundle.js +1 -7
- package/src/pb-components.js +2 -6
- package/src/pb-custom-form.js +230 -141
- package/src/pb-dialog.js +99 -63
- package/src/pb-document.js +118 -91
- package/src/pb-download.js +214 -198
- package/src/pb-drawer.js +146 -149
- package/src/pb-edit-app.js +471 -240
- package/src/pb-edit-xml.js +101 -98
- package/src/pb-events.js +126 -107
- package/src/pb-facs-link.js +130 -101
- package/src/pb-facsimile.js +494 -410
- package/src/pb-fetch.js +389 -0
- package/src/pb-formula.js +152 -154
- package/src/pb-geolocation.js +130 -132
- package/src/pb-grid-action.js +59 -56
- package/src/pb-grid.js +388 -228
- package/src/pb-highlight.js +142 -142
- package/src/pb-hotkeys.js +40 -42
- package/src/pb-i18n.js +115 -127
- package/src/pb-icon-button.js +108 -0
- package/src/pb-icon.js +283 -0
- package/src/pb-image-strip.js +85 -79
- package/src/pb-lang.js +142 -57
- package/src/pb-leaflet-map.js +551 -483
- package/src/pb-link.js +132 -126
- package/src/pb-load.js +495 -428
- package/src/pb-login.js +303 -248
- package/src/pb-manage-odds.js +384 -338
- package/src/pb-map-icon.js +90 -90
- package/src/pb-map-layer.js +86 -86
- package/src/pb-markdown.js +107 -110
- package/src/pb-media-query.js +75 -73
- package/src/pb-mei.js +523 -303
- package/src/pb-message.js +144 -98
- package/src/pb-mixin.js +268 -265
- package/src/pb-navigation.js +83 -96
- package/src/pb-observable.js +39 -39
- package/src/pb-odd-editor.js +1209 -948
- package/src/pb-odd-elementspec-editor.js +375 -310
- package/src/pb-odd-model-editor.js +1189 -941
- package/src/pb-odd-parameter-editor.js +269 -170
- package/src/pb-odd-rendition-editor.js +184 -131
- package/src/pb-page.js +451 -422
- package/src/pb-paginate.js +260 -178
- package/src/pb-panel.js +217 -183
- package/src/pb-popover-themes.js +16 -9
- package/src/pb-popover.js +297 -288
- package/src/pb-print-preview.js +128 -128
- package/src/pb-progress.js +52 -52
- package/src/pb-repeat.js +141 -108
- package/src/pb-restricted.js +85 -78
- package/src/pb-search.js +258 -230
- package/src/pb-select-feature.js +210 -126
- package/src/pb-select-odd.js +184 -118
- package/src/pb-select-template.js +113 -78
- package/src/pb-select.js +330 -229
- package/src/pb-split-list.js +181 -176
- package/src/pb-svg.js +81 -80
- package/src/pb-table-column.js +55 -55
- package/src/pb-table-grid.js +334 -205
- package/src/pb-tabs.js +238 -61
- package/src/pb-tify.js +3331 -126
- package/src/pb-timeline.js +394 -255
- package/src/pb-toggle-feature.js +196 -188
- package/src/pb-upload.js +201 -176
- package/src/pb-version.js +22 -34
- package/src/pb-view-annotate.js +138 -102
- package/src/pb-view.js +1722 -1272
- package/src/pb-zoom.js +144 -46
- package/src/search-result-service.js +256 -223
- package/src/seed-element.js +14 -22
- package/src/settings.js +4 -4
- package/src/theming.js +98 -91
- package/src/urls.js +403 -289
- package/src/utils.js +53 -51
- package/vite.config.js +86 -0
- package/css/pb-styles.css +0 -51
- package/dist/iron-form-3b8dcaa7.js +0 -210
- package/dist/jinn-codemirror-da0e2d1f.js +0 -1
- package/dist/paper-checkbox-515a5284.js +0 -1597
- package/dist/paper-icon-button-b1d31571.js +0 -398
- package/dist/paper-listbox-a3b7175c.js +0 -1265
- package/dist/pb-i18n-0611135a.js +0 -1
- package/dist/pb-mixin-b1caa22e.js +0 -158
- package/dist/polymer-hack.js +0 -1
- package/dist/vaadin-element-mixin-6e4cee3a.js +0 -527
- package/lib/Control.Geocoder.min.js +0 -2
- package/lib/Control.Geocoder.min.js.map +0 -1
- package/src/assets/pb-styles.css +0 -51
- package/src/pb-light-dom.js +0 -40
- package/src/polymer-hack.js +0 -6
package/src/pb-custom-form.js
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
import { html, css } from 'lit
|
|
2
|
-
import '
|
|
3
|
-
import '@polymer/iron-ajax';
|
|
4
|
-
import '@polymer/paper-dialog';
|
|
5
|
-
import '@polymer/paper-dialog-scrollable';
|
|
1
|
+
import { html, css } from 'lit';
|
|
2
|
+
import './pb-fetch.js';
|
|
6
3
|
import { PbLoad } from './pb-load.js';
|
|
4
|
+
import './pb-dialog.js';
|
|
7
5
|
|
|
8
6
|
/**
|
|
9
7
|
* A custom form element which loads the actual form from a server-side script using AJAX.
|
|
@@ -19,159 +17,250 @@ import { PbLoad } from './pb-load.js';
|
|
|
19
17
|
* @fires pb-submit - Fired when the form is submitted
|
|
20
18
|
*/
|
|
21
19
|
export class PbCustomForm extends PbLoad {
|
|
20
|
+
constructor() {
|
|
21
|
+
super();
|
|
22
|
+
this._autoSubmitTargets = new WeakSet();
|
|
23
|
+
}
|
|
22
24
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
this.
|
|
29
|
-
|
|
30
|
-
this.submit();
|
|
31
|
-
}
|
|
32
|
-
if (e.target.slot === 'searchButtonBottom'){
|
|
33
|
-
this.submit();
|
|
34
|
-
}
|
|
35
|
-
if (e.target.slot === 'resetButton'){
|
|
36
|
-
this._reset();
|
|
37
|
-
}
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
this._submissionHandlers();
|
|
25
|
+
firstUpdated() {
|
|
26
|
+
const form = this.shadowRoot && this.shadowRoot.getElementById('form');
|
|
27
|
+
if (form) {
|
|
28
|
+
form.addEventListener('submit', ev => {
|
|
29
|
+
ev.preventDefault();
|
|
30
|
+
this._submit();
|
|
31
|
+
});
|
|
41
32
|
}
|
|
33
|
+
this.addEventListener('click', e => {
|
|
34
|
+
if (e.target.slot === 'searchButtonTop') {
|
|
35
|
+
this.submit();
|
|
36
|
+
}
|
|
37
|
+
if (e.target.slot === 'searchButtonBottom') {
|
|
38
|
+
this.submit();
|
|
39
|
+
}
|
|
40
|
+
if (e.target.slot === 'resetButton') {
|
|
41
|
+
this._reset();
|
|
42
|
+
}
|
|
43
|
+
});
|
|
42
44
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
<iron-form id="ironform">
|
|
46
|
-
<form action="" accept="text/html" method="GET">
|
|
47
|
-
<slot name="searchButtonTop"></slot>
|
|
48
|
-
<slot></slot>
|
|
49
|
-
<slot name="searchButtonBottom"></slot>
|
|
50
|
-
<slot name="resetButton"></slot>
|
|
51
|
-
</form>
|
|
52
|
-
</iron-form>
|
|
53
|
-
|
|
54
|
-
<iron-ajax
|
|
55
|
-
id="loadContent"
|
|
56
|
-
verbose
|
|
57
|
-
handle-as="text"
|
|
58
|
-
method="get"
|
|
59
|
-
with-credentials
|
|
60
|
-
@response="${this._handleContent}"
|
|
61
|
-
@error="${this._handleError}"></iron-ajax>
|
|
62
|
-
<paper-dialog id="errorDialog">
|
|
63
|
-
<h2>Error</h2>
|
|
64
|
-
<paper-dialog-scrollable></paper-dialog-scrollable>
|
|
65
|
-
<div class="buttons">
|
|
66
|
-
<paper-button dialog-confirm="dialog-confirm" autofocus="autofocus">
|
|
67
|
-
Close
|
|
68
|
-
</paper-button>
|
|
69
|
-
</div>
|
|
70
|
-
</paper-dialog>
|
|
71
|
-
`;
|
|
72
|
-
}
|
|
45
|
+
this._submissionHandlers();
|
|
46
|
+
}
|
|
73
47
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
48
|
+
render() {
|
|
49
|
+
return html`
|
|
50
|
+
<form id="form" action="" accept="text/html" method="GET" novalidate>
|
|
51
|
+
<slot name="searchButtonTop"></slot>
|
|
52
|
+
<slot></slot>
|
|
53
|
+
<slot name="searchButtonBottom"></slot>
|
|
54
|
+
<slot name="resetButton"></slot>
|
|
55
|
+
</form>
|
|
81
56
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
57
|
+
<pb-fetch
|
|
58
|
+
id="loadContent"
|
|
59
|
+
verbose
|
|
60
|
+
handle-as="text"
|
|
61
|
+
method="get"
|
|
62
|
+
with-credentials
|
|
63
|
+
@response="${this._handleContent}"
|
|
64
|
+
@error="${this._handleError}"
|
|
65
|
+
></pb-fetch>
|
|
66
|
+
<pb-dialog id="errorDialog" title="Error">
|
|
67
|
+
<p id="errorMessage"></p>
|
|
68
|
+
<div slot="footer">
|
|
69
|
+
<button rel="prev" type="button">Close</button>
|
|
70
|
+
</div>
|
|
71
|
+
</pb-dialog>
|
|
72
|
+
`;
|
|
73
|
+
}
|
|
85
74
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
75
|
+
static get styles() {
|
|
76
|
+
return css`
|
|
77
|
+
:host {
|
|
78
|
+
display: block;
|
|
79
|
+
}
|
|
80
|
+
`;
|
|
81
|
+
}
|
|
91
82
|
|
|
92
|
-
|
|
93
|
-
|
|
83
|
+
submit() {
|
|
84
|
+
const form = this.shadowRoot && this.shadowRoot.getElementById('form');
|
|
85
|
+
if (!form) {
|
|
86
|
+
return;
|
|
94
87
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
* as null while disabled elements will still be omitted
|
|
100
|
-
* this allows url parameters to be reset in the URL
|
|
101
|
-
* as IronForm.serializeform will omit names without a value
|
|
102
|
-
* @returns {Object} name value pairs
|
|
103
|
-
*/
|
|
104
|
-
serializeForm() {
|
|
105
|
-
const elements = this.shadowRoot.getElementById('ironform')._getSubmittableElements()
|
|
106
|
-
const initial = {}
|
|
107
|
-
for (const element of elements) {
|
|
108
|
-
initial[element.name] = null;
|
|
109
|
-
}
|
|
110
|
-
return Object.assign(
|
|
111
|
-
initial,
|
|
112
|
-
this.shadowRoot.getElementById('ironform').serializeForm()
|
|
113
|
-
);
|
|
88
|
+
if (form.requestSubmit) {
|
|
89
|
+
form.requestSubmit();
|
|
90
|
+
} else if (typeof form.submit === 'function') {
|
|
91
|
+
form.submit();
|
|
114
92
|
}
|
|
93
|
+
}
|
|
115
94
|
|
|
116
|
-
|
|
117
|
-
|
|
95
|
+
_submit() {
|
|
96
|
+
const json = this.serializeForm();
|
|
97
|
+
this.emitTo('pb-search-resubmit', { params: json });
|
|
98
|
+
this.emitTo('pb-submit', { params: json });
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
_reset() {
|
|
102
|
+
const form = this.shadowRoot && this.shadowRoot.getElementById('form');
|
|
103
|
+
if (form && typeof form.reset === 'function') {
|
|
104
|
+
form.reset();
|
|
118
105
|
}
|
|
106
|
+
}
|
|
119
107
|
|
|
120
|
-
|
|
121
|
-
|
|
108
|
+
/**
|
|
109
|
+
* serialize custom form to object with name value pairs
|
|
110
|
+
* empty, unselected and undifined inputs will be returned
|
|
111
|
+
* as null while disabled elements will still be omitted
|
|
112
|
+
* this allows url parameters to be reset in the URL
|
|
113
|
+
* as IronForm.serializeform will omit names without a value
|
|
114
|
+
* @returns {Object} name value pairs
|
|
115
|
+
*/
|
|
116
|
+
serializeForm() {
|
|
117
|
+
const form = this.shadowRoot && this.shadowRoot.getElementById('form');
|
|
118
|
+
if (!form) return {};
|
|
122
119
|
|
|
123
|
-
|
|
124
|
-
|
|
120
|
+
// Get elements from both form.elements AND slotted/light DOM content
|
|
121
|
+
// form.elements doesn't include slotted content in all browsers
|
|
122
|
+
const formElements = Array.from(form.elements || []);
|
|
123
|
+
const slottedElements = Array.from(this.querySelectorAll('input, select, textarea'));
|
|
124
|
+
const allElements = [...new Set([...formElements, ...slottedElements])];
|
|
125
125
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
126
|
+
const elements = allElements.filter(
|
|
127
|
+
el => el.name && !el.disabled && !el.closest('[disabled]'),
|
|
128
|
+
);
|
|
129
|
+
const initial = {};
|
|
130
|
+
elements.forEach(element => {
|
|
131
|
+
if (!(element.name in initial)) {
|
|
132
|
+
initial[element.name] = null;
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
// Build form data manually to include slotted content
|
|
137
|
+
const data = {};
|
|
138
|
+
elements.forEach(el => {
|
|
139
|
+
if (el.type === 'checkbox' || el.type === 'radio') {
|
|
140
|
+
if (el.checked) {
|
|
141
|
+
if (data[el.name] == null) {
|
|
142
|
+
data[el.name] = el.value;
|
|
143
|
+
} else if (Array.isArray(data[el.name])) {
|
|
144
|
+
data[el.name].push(el.value);
|
|
145
|
+
} else {
|
|
146
|
+
data[el.name] = [data[el.name], el.value];
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
} else if (el.type === 'select-multiple') {
|
|
150
|
+
const values = Array.from(el.selectedOptions).map(opt => opt.value);
|
|
151
|
+
if (values.length > 0) {
|
|
152
|
+
data[el.name] = values.length === 1 ? values[0] : values;
|
|
129
153
|
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
154
|
+
} else {
|
|
155
|
+
data[el.name] = el.value;
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
// Merge with initial (to preserve null for unset values)
|
|
160
|
+
Object.keys(data).forEach(key => {
|
|
161
|
+
if (data[key] != null) {
|
|
162
|
+
initial[key] = data[key];
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
return initial;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
_parseHeaders(xhr) {
|
|
170
|
+
// overwrite to avoid `pb-results-received` event being sent
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
_onLoad(content) {
|
|
174
|
+
super._onLoad(content);
|
|
175
|
+
|
|
176
|
+
this.dispatchEvent(new CustomEvent('pb-custom-form-loaded', { detail: content }));
|
|
177
|
+
this._submissionHandlers();
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
_handleError() {
|
|
181
|
+
this.emitTo('pb-end-update');
|
|
182
|
+
const loader = this.shadowRoot.getElementById('loadContent');
|
|
183
|
+
const { response } = loader.lastError;
|
|
184
|
+
if (this.silent) {
|
|
185
|
+
console.error('Request failed: %s', response ? response.description : '');
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
let message;
|
|
189
|
+
if (response) {
|
|
190
|
+
message = response.description;
|
|
191
|
+
} else {
|
|
192
|
+
message = 'Server error occurred';
|
|
145
193
|
}
|
|
194
|
+
const dialog = this.shadowRoot.getElementById('errorDialog');
|
|
195
|
+
const messageElement = this.shadowRoot.getElementById('errorMessage');
|
|
196
|
+
messageElement.textContent = `Server error: ${message}`;
|
|
197
|
+
dialog.openDialog();
|
|
198
|
+
}
|
|
146
199
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
* Register event handlers on all descendant elements matching the given CSS selector and submit the form
|
|
151
|
-
* automatically if any of those changes. For button-like controls,
|
|
152
|
-
* a submit is triggered on click, for text input on keyUp, and for
|
|
153
|
-
* all other form components on change.
|
|
154
|
-
*/
|
|
155
|
-
autoSubmit: {
|
|
156
|
-
type: String,
|
|
157
|
-
attribute: 'auto-submit'
|
|
158
|
-
},
|
|
159
|
-
...super.properties
|
|
160
|
-
};
|
|
200
|
+
_submissionHandlers() {
|
|
201
|
+
if (!this.autoSubmit) {
|
|
202
|
+
return;
|
|
161
203
|
}
|
|
204
|
+
this.querySelectorAll(this.autoSubmit).forEach(control => {
|
|
205
|
+
if (this._autoSubmitTargets.has(control)) {
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
this._autoSubmitTargets.add(control);
|
|
209
|
+
const name = (control.nodeName || '').toLowerCase();
|
|
210
|
+
let event = 'change';
|
|
211
|
+
if (
|
|
212
|
+
control instanceof HTMLButtonElement ||
|
|
213
|
+
name === 'pb-icon-button' ||
|
|
214
|
+
name === 'paper-button' ||
|
|
215
|
+
name === 'button' ||
|
|
216
|
+
(name === 'input' &&
|
|
217
|
+
(control.type === 'button' || control.type === 'submit' || control.type === 'reset'))
|
|
218
|
+
) {
|
|
219
|
+
event = 'click';
|
|
220
|
+
} else if (
|
|
221
|
+
name === 'paper-input' ||
|
|
222
|
+
(control instanceof HTMLInputElement &&
|
|
223
|
+
(control.type === 'text' || control.type === 'search'))
|
|
224
|
+
) {
|
|
225
|
+
event = 'keyup';
|
|
226
|
+
} else if (name === 'paper-dropdown-menu') {
|
|
227
|
+
event = 'value-changed';
|
|
228
|
+
}
|
|
229
|
+
if (control instanceof HTMLSelectElement) {
|
|
230
|
+
event = 'change';
|
|
231
|
+
}
|
|
232
|
+
control.addEventListener(event, this._submit.bind(this));
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
static get properties() {
|
|
237
|
+
return {
|
|
238
|
+
/**
|
|
239
|
+
* Register event handlers on all descendant elements matching the given CSS selector and submit the form
|
|
240
|
+
* automatically if any of those changes. For button-like controls,
|
|
241
|
+
* a submit is triggered on click, for text input on keyUp, and for
|
|
242
|
+
* all other form components on change.
|
|
243
|
+
*/
|
|
244
|
+
autoSubmit: {
|
|
245
|
+
type: String,
|
|
246
|
+
attribute: 'auto-submit',
|
|
247
|
+
},
|
|
248
|
+
...super.properties,
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Fired before the element updates its content
|
|
254
|
+
*
|
|
255
|
+
* @event pb-custom-form-loaded
|
|
256
|
+
* @param {string} the loaded content
|
|
257
|
+
*/
|
|
162
258
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
/**
|
|
171
|
-
* Fired when form is submitted
|
|
172
|
-
*
|
|
173
|
-
* @event pb-search-resubmit
|
|
174
|
-
* @param {object} params: serialized form parameters as json object
|
|
175
|
-
*/
|
|
259
|
+
/**
|
|
260
|
+
* Fired when form is submitted
|
|
261
|
+
*
|
|
262
|
+
* @event pb-search-resubmit
|
|
263
|
+
* @param {object} params: serialized form parameters as json object
|
|
264
|
+
*/
|
|
176
265
|
}
|
|
177
|
-
customElements.define('pb-custom-form', PbCustomForm);
|
|
266
|
+
customElements.define('pb-custom-form', PbCustomForm);
|
package/src/pb-dialog.js
CHANGED
|
@@ -1,83 +1,119 @@
|
|
|
1
|
-
import { LitElement, html } from 'lit
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import { LitElement, html, css } from 'lit';
|
|
2
|
+
import { unsafeHTML } from 'lit/directives/unsafe-html.js';
|
|
3
|
+
import { pbMixin } from './pb-mixin.js';
|
|
4
|
+
import { themableMixin } from './theming.js';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
* A simple dialog component using the HTML5 <dialog> element
|
|
7
|
+
* A simple dialog component using the HTML5 <dialog> element.
|
|
8
|
+
*
|
|
9
|
+
* Any button with the attribute `rel="prev"` will close the dialog when clicked.
|
|
8
10
|
*
|
|
9
11
|
* @slot - Content of the dialog
|
|
10
12
|
* @slot title - Title of the dialog
|
|
11
13
|
* @fires pb-dialog-opened - Fired when the dialog is opened
|
|
12
14
|
* @fires pb-dialog-closed - Fired when the dialog is closed
|
|
13
15
|
*/
|
|
14
|
-
export class PbDialog extends
|
|
16
|
+
export class PbDialog extends themableMixin(pbMixin(LitElement)) {
|
|
17
|
+
static get properties() {
|
|
18
|
+
return {
|
|
19
|
+
...super.properties,
|
|
20
|
+
open: { type: Boolean, reflect: true },
|
|
21
|
+
modal: { type: Boolean, reflect: true },
|
|
22
|
+
title: { type: String, reflect: true },
|
|
23
|
+
message: { type: String, reflect: true },
|
|
24
|
+
};
|
|
25
|
+
}
|
|
15
26
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}
|
|
27
|
+
constructor() {
|
|
28
|
+
super();
|
|
29
|
+
this.open = false;
|
|
30
|
+
this.modal = true;
|
|
31
|
+
this._escListener = this._onEsc.bind(this);
|
|
32
|
+
this.title = null;
|
|
33
|
+
this.message = null;
|
|
34
|
+
}
|
|
25
35
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
this.modal = true;
|
|
30
|
-
this._escListener = this._onEsc.bind(this);
|
|
31
|
-
this.title = null;
|
|
32
|
-
this.message = null;
|
|
36
|
+
_onEsc(e) {
|
|
37
|
+
if (e.key === 'Escape' && this.open) {
|
|
38
|
+
this.closeDialog();
|
|
33
39
|
}
|
|
40
|
+
}
|
|
34
41
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
42
|
+
openDialog() {
|
|
43
|
+
if (!this.open) {
|
|
44
|
+
if (this.modal) {
|
|
45
|
+
this._dialog.showModal();
|
|
46
|
+
} else {
|
|
47
|
+
this._dialog.show();
|
|
48
|
+
}
|
|
49
|
+
this.dispatchEvent(new CustomEvent('pb-dialog-opened', { bubbles: true, composed: true }));
|
|
50
|
+
this.open = true;
|
|
39
51
|
}
|
|
52
|
+
}
|
|
40
53
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
this._dialog.show();
|
|
47
|
-
}
|
|
48
|
-
this.dispatchEvent(new CustomEvent('pb-dialog-opened', { bubbles: true, composed: true }));
|
|
49
|
-
this.open = true;
|
|
50
|
-
}
|
|
54
|
+
closeDialog() {
|
|
55
|
+
if (this.open) {
|
|
56
|
+
this._dialog.close();
|
|
57
|
+
this.dispatchEvent(new CustomEvent('pb-dialog-closed', { bubbles: true, composed: true }));
|
|
58
|
+
this.open = false;
|
|
51
59
|
}
|
|
60
|
+
}
|
|
52
61
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
<
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
${ this.message ? unsafeHTML(this.message) : this.fillSlot() }
|
|
70
|
-
<footer>
|
|
71
|
-
${ this.fillSlot('footer') }
|
|
72
|
-
</footer>
|
|
73
|
-
</article>
|
|
74
|
-
</dialog>
|
|
75
|
-
`;
|
|
76
|
-
}
|
|
62
|
+
render() {
|
|
63
|
+
return html`
|
|
64
|
+
<dialog @click="${e => e.target === this._dialog && this.modal && this.closeDialog()}">
|
|
65
|
+
<article>
|
|
66
|
+
<header>
|
|
67
|
+
${this.title ? unsafeHTML(this.title) : html`<slot name="title"></slot>`}
|
|
68
|
+
<button rel="prev" aria-label="Close" type="button"></button>
|
|
69
|
+
</header>
|
|
70
|
+
${this.message ? unsafeHTML(this.message) : html`<slot></slot>`}
|
|
71
|
+
<footer>
|
|
72
|
+
<slot name="footer"></slot>
|
|
73
|
+
</footer>
|
|
74
|
+
</article>
|
|
75
|
+
</dialog>
|
|
76
|
+
`;
|
|
77
|
+
}
|
|
77
78
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
79
|
+
firstUpdated() {
|
|
80
|
+
this._dialog = this.renderRoot.querySelector('dialog');
|
|
81
|
+
// Add click listeners to close buttons in both shadow and light DOM
|
|
82
|
+
[
|
|
83
|
+
...this._dialog.querySelectorAll('button[rel="prev"]'),
|
|
84
|
+
...this.querySelectorAll('button[rel="prev"]'),
|
|
85
|
+
].forEach(button => button.addEventListener('click', this.closeDialog.bind(this)));
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
static get styles() {
|
|
89
|
+
return css`
|
|
90
|
+
header {
|
|
91
|
+
display: flex;
|
|
92
|
+
justify-content: space-between;
|
|
93
|
+
align-items: center;
|
|
94
|
+
}
|
|
95
|
+
button[rel='prev'] {
|
|
96
|
+
display: block;
|
|
97
|
+
height: 1rem;
|
|
98
|
+
width: 1rem;
|
|
99
|
+
background-image: var(
|
|
100
|
+
--pb-dialog-background-image,
|
|
101
|
+
url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(136, 145, 164)' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cline x1='18' y1='6' x2='6' y2='18'%3E%3C/line%3E%3Cline x1='6' y1='6' x2='18' y2='18'%3E%3C/line%3E%3C/svg%3E")
|
|
102
|
+
);
|
|
103
|
+
background-position: center;
|
|
104
|
+
background-size: auto 1rem;
|
|
105
|
+
background-repeat: no-repeat;
|
|
106
|
+
background-color: transparent;
|
|
107
|
+
border: none;
|
|
108
|
+
}
|
|
109
|
+
footer {
|
|
110
|
+
display: flex;
|
|
111
|
+
justify-content: flex-end;
|
|
112
|
+
align-items: center;
|
|
113
|
+
margin-top: 16px;
|
|
114
|
+
}
|
|
115
|
+
`;
|
|
116
|
+
}
|
|
81
117
|
}
|
|
82
118
|
|
|
83
119
|
customElements.define('pb-dialog', PbDialog);
|