@getflip/swirl-components 0.8.3 → 0.8.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.
Files changed (32) hide show
  1. package/dist/cjs/flip-file-viewer_7.cjs.entry.js +155 -1
  2. package/dist/cjs/flip-lightbox.cjs.entry.js +21 -2
  3. package/dist/cjs/flip-modal.cjs.entry.js +1 -1
  4. package/dist/cjs/flip-tree-navigation-item.cjs.entry.js +1 -1
  5. package/dist/cjs/loader.cjs.js +1 -1
  6. package/dist/cjs/swirl-components.cjs.js +1 -1
  7. package/dist/collection/components/flip-file-viewer/viewers/flip-file-viewer-image/flip-file-viewer-image.js +215 -3
  8. package/dist/collection/components/flip-lightbox/flip-lightbox.js +21 -2
  9. package/dist/collection/components/flip-modal/flip-modal.css +2 -2
  10. package/dist/collection/components/flip-tree-navigation-item/flip-tree-navigation-item.css +8 -2
  11. package/dist/components/flip-file-viewer-image2.js +159 -2
  12. package/dist/components/flip-lightbox.js +21 -2
  13. package/dist/components/flip-modal.js +1 -1
  14. package/dist/components/flip-tree-navigation-item.js +1 -1
  15. package/dist/esm/flip-file-viewer_7.entry.js +155 -1
  16. package/dist/esm/flip-lightbox.entry.js +21 -2
  17. package/dist/esm/flip-modal.entry.js +1 -1
  18. package/dist/esm/flip-tree-navigation-item.entry.js +1 -1
  19. package/dist/esm/loader.js +1 -1
  20. package/dist/esm/swirl-components.js +1 -1
  21. package/dist/swirl-components/{p-08f3a8ab.entry.js → p-3a421e82.entry.js} +1 -1
  22. package/dist/swirl-components/{p-de892e4e.entry.js → p-5ba8364a.entry.js} +1 -1
  23. package/dist/swirl-components/p-9483fed0.entry.js +1 -0
  24. package/dist/swirl-components/p-9ce51761.entry.js +1 -0
  25. package/dist/swirl-components/swirl-components.esm.js +1 -1
  26. package/dist/types/components/flip-file-viewer/viewers/flip-file-viewer-image/flip-file-viewer-image.d.ts +40 -0
  27. package/dist/types/components/flip-lightbox/flip-lightbox.d.ts +1 -0
  28. package/dist/types/components.d.ts +12 -0
  29. package/package.json +1 -1
  30. package/vscode-data.json +4 -0
  31. package/dist/swirl-components/p-38cf01d0.entry.js +0 -1
  32. package/dist/swirl-components/p-5bc6cc3e.entry.js +0 -1
@@ -1,9 +1,13 @@
1
- import { Component, Element, Event, h, Host, Prop, State, Watch, } from "@stencil/core";
1
+ import { Component, Element, Event, h, Host, Method, Prop, State, Watch, } from "@stencil/core";
2
2
  export class FlipFileViewerImage {
3
3
  constructor() {
4
4
  this.description = "";
5
5
  this.errorMessage = "File could not be loaded.";
6
+ this.maxZoom = 3;
6
7
  this.loading = true;
8
+ this.panX = 0;
9
+ this.panY = 0;
10
+ this.zoom = 1;
7
11
  this.onError = () => {
8
12
  this.error = true;
9
13
  this.loading = false;
@@ -12,6 +16,142 @@ export class FlipFileViewerImage {
12
16
  this.error = false;
13
17
  this.loading = false;
14
18
  };
19
+ this.onDblClick = (event) => {
20
+ this.clickToZoom(event);
21
+ };
22
+ this.onWheel = (event) => {
23
+ event.preventDefault();
24
+ const zoom = Math.min(Math.max(1, this.zoom + (-1 * event.deltaY) / 100), this.maxZoom);
25
+ if (zoom === this.zoom) {
26
+ return;
27
+ }
28
+ const centerX = event.offsetX;
29
+ const centerY = event.offsetY;
30
+ this.updateTransformOrigin(centerX, centerY);
31
+ this.updateZoomAndPan(zoom, 0, 0);
32
+ };
33
+ this.onPointerDown = (event) => {
34
+ this.startPan(event);
35
+ };
36
+ this.onPointerMove = (event) => {
37
+ this.pan(event);
38
+ };
39
+ this.onPointerUp = () => {
40
+ this.endPan();
41
+ };
42
+ this.onTouchStart = (event) => {
43
+ event.preventDefault();
44
+ if (event.touches.length === 2) {
45
+ this.startPinchToZoom(event);
46
+ }
47
+ };
48
+ this.onTouchMove = (event) => {
49
+ event.preventDefault();
50
+ if (this.pinching) {
51
+ this.pinchToZoom(event);
52
+ }
53
+ };
54
+ this.onTouchEnd = (event) => {
55
+ event.preventDefault();
56
+ if (this.pinching) {
57
+ this.endPinchToZoom();
58
+ }
59
+ };
60
+ this.startPinchToZoom = (event) => {
61
+ if (!Boolean(this.imageEl)) {
62
+ return;
63
+ }
64
+ this.pinchDistance = this.getPinchDistance(event);
65
+ this.pinching = true;
66
+ };
67
+ this.pinchToZoom = (event) => {
68
+ const distance = this.getPinchDistance(event) - this.pinchDistance;
69
+ const zoom = Math.min(Math.max(1, this.zoom + distance / 100), this.maxZoom);
70
+ if (this.zoom === zoom) {
71
+ return;
72
+ }
73
+ this.pinchDistance = this.getPinchDistance(event);
74
+ this.updateZoomAndPan(zoom);
75
+ };
76
+ this.endPinchToZoom = () => {
77
+ this.pinching = false;
78
+ if (Math.abs(this.zoom - 1) < 0.2) {
79
+ this.zoom = 1;
80
+ this.imageEl.style.transform = "";
81
+ }
82
+ };
83
+ this.getPinchDistance = (event) => {
84
+ return Math.hypot(event.touches[0].pageX - event.touches[1].pageX, event.touches[0].pageY - event.touches[1].pageY);
85
+ };
86
+ this.clickToZoom = (event) => {
87
+ const supportsMultiTouch = navigator.maxTouchPoints > 1;
88
+ if (supportsMultiTouch) {
89
+ return;
90
+ }
91
+ if (this.zoom === 1) {
92
+ const centerX = event.pageX - this.el.getBoundingClientRect().x;
93
+ const centerY = event.pageY - this.el.getBoundingClientRect().y;
94
+ this.updateTransformOrigin(centerX, centerY);
95
+ this.updateZoomAndPan(2);
96
+ }
97
+ else {
98
+ this.updateZoomAndPan(1);
99
+ }
100
+ };
101
+ this.updateZoomAndPan = (zoom, panX, panY) => {
102
+ const newZoom = zoom === undefined ? this.zoom : zoom;
103
+ const zoomDiff = newZoom - this.zoom;
104
+ const newPanX = panX === undefined ? this.panX + this.panX * zoomDiff : panX;
105
+ const newPanY = panX === undefined ? this.panY + this.panY * zoomDiff : panY;
106
+ const previousPanX = this.panX;
107
+ const previousPanY = this.panY;
108
+ this.zoom = newZoom;
109
+ this.panX = newPanX;
110
+ this.panY = newPanY;
111
+ const parentRect = (this.el.parentElement || this.el).getBoundingClientRect();
112
+ const imageRect = this.imageEl.getBoundingClientRect();
113
+ const outOfBoundsX = (imageRect.right < parentRect.right && newPanX < previousPanX) ||
114
+ (imageRect.left > parentRect.left && newPanX > previousPanX);
115
+ const outOfBoundsY = (imageRect.bottom < parentRect.bottom && newPanY < previousPanY) ||
116
+ (imageRect.top > parentRect.top && newPanY > previousPanY);
117
+ if (outOfBoundsX) {
118
+ this.panX = previousPanX;
119
+ }
120
+ if (outOfBoundsY) {
121
+ this.panY = previousPanY;
122
+ }
123
+ if (this.zoom === 1) {
124
+ this.panX = 0;
125
+ this.panY = 0;
126
+ }
127
+ this.imageEl.style.transform = `matrix(${this.zoom}, 0, 0, ${this.zoom}, ${this.panX}, ${this.panY})`;
128
+ };
129
+ this.updateTransformOrigin = (x, y) => {
130
+ this.transformOriginX = x;
131
+ this.transformOriginY = y;
132
+ this.imageEl.style.transformOrigin = `${this.transformOriginX}px ${this.transformOriginY}px`;
133
+ };
134
+ this.startPan = (event) => {
135
+ this.panning = true;
136
+ this.previousScreenX = event.screenX;
137
+ this.previousScreenY = event.screenY;
138
+ };
139
+ this.pan = (event) => {
140
+ const previousScreenX = this.previousScreenX || 0;
141
+ const previousScreenY = this.previousScreenY || 0;
142
+ this.previousScreenX = event.screenX;
143
+ this.previousScreenY = event.screenY;
144
+ if (!this.panning || this.pinching) {
145
+ return;
146
+ }
147
+ event.preventDefault();
148
+ const panX = this.panX + event.screenX - previousScreenX;
149
+ const panY = this.panY + event.screenY - previousScreenY;
150
+ this.updateZoomAndPan(this.zoom, panX, panY);
151
+ };
152
+ this.endPan = () => {
153
+ this.panning = false;
154
+ };
15
155
  }
16
156
  componentDidLoad() {
17
157
  this.activate.emit(this.el);
@@ -20,10 +160,24 @@ export class FlipFileViewerImage {
20
160
  this.error = false;
21
161
  this.loading = true;
22
162
  }
163
+ /**
164
+ * Get the current zoom.
165
+ * @returns
166
+ */
167
+ async getZoom() {
168
+ return this.zoom;
169
+ }
170
+ /**
171
+ * Resets the zoom.
172
+ * @returns
173
+ */
174
+ async resetZoom() {
175
+ return this.updateZoomAndPan(1);
176
+ }
23
177
  render() {
24
- return (h(Host, { class: "file-viewer-image" },
178
+ return (h(Host, { class: "file-viewer-image", onDblClick: this.onDblClick, onWheel: this.onWheel, onPointerDown: this.onPointerDown, onPointerMove: this.onPointerMove, onPointerUp: this.onPointerUp, onTouchStart: this.onTouchStart, onTouchMove: this.onTouchMove, onTouchEnd: this.onTouchEnd },
25
179
  this.error && (h("flip-inline-error", { class: "file-viewer-image__error", message: this.errorMessage })),
26
- h("img", { alt: this.description, class: "file-viewer-image__image", onError: this.onError, onLoad: this.onLoad, src: this.file }),
180
+ h("img", { alt: this.description, class: "file-viewer-image__image", onError: this.onError, onLoad: this.onLoad, ref: (el) => (this.imageEl = el), src: this.file }),
27
181
  this.loading && (h("div", { class: "file-viewer-image__spinner" },
28
182
  h("flip-spinner", null)))));
29
183
  }
@@ -88,6 +242,24 @@ export class FlipFileViewerImage {
88
242
  },
89
243
  "attribute": "file",
90
244
  "reflect": false
245
+ },
246
+ "maxZoom": {
247
+ "type": "number",
248
+ "mutable": false,
249
+ "complexType": {
250
+ "original": "number",
251
+ "resolved": "number",
252
+ "references": {}
253
+ },
254
+ "required": false,
255
+ "optional": true,
256
+ "docs": {
257
+ "tags": [],
258
+ "text": ""
259
+ },
260
+ "attribute": "max-zoom",
261
+ "reflect": false,
262
+ "defaultValue": "3"
91
263
  }
92
264
  }; }
93
265
  static get states() { return {
@@ -114,6 +286,46 @@ export class FlipFileViewerImage {
114
286
  }
115
287
  }
116
288
  }]; }
289
+ static get methods() { return {
290
+ "getZoom": {
291
+ "complexType": {
292
+ "signature": "() => Promise<number>",
293
+ "parameters": [],
294
+ "references": {
295
+ "Promise": {
296
+ "location": "global"
297
+ }
298
+ },
299
+ "return": "Promise<number>"
300
+ },
301
+ "docs": {
302
+ "text": "Get the current zoom.",
303
+ "tags": [{
304
+ "name": "returns",
305
+ "text": undefined
306
+ }]
307
+ }
308
+ },
309
+ "resetZoom": {
310
+ "complexType": {
311
+ "signature": "() => Promise<void>",
312
+ "parameters": [],
313
+ "references": {
314
+ "Promise": {
315
+ "location": "global"
316
+ }
317
+ },
318
+ "return": "Promise<void>"
319
+ },
320
+ "docs": {
321
+ "text": "Resets the zoom.",
322
+ "tags": [{
323
+ "name": "returns",
324
+ "text": undefined
325
+ }]
326
+ }
327
+ }
328
+ }; }
117
329
  static get elementRef() { return "el"; }
118
330
  static get watchers() { return [{
119
331
  "propName": "file",
@@ -43,7 +43,6 @@ export class FlipLightbox {
43
43
  this.updateMediaPlayers();
44
44
  };
45
45
  this.onPointerDown = (event) => {
46
- event.preventDefault();
47
46
  this.dragging = true;
48
47
  this.dragStartPosition =
49
48
  event instanceof MouseEvent ? event.clientX : event.touches[0].clientX;
@@ -51,7 +50,16 @@ export class FlipLightbox {
51
50
  slide.style.transition = "none";
52
51
  });
53
52
  };
54
- this.onPointerMove = (event) => {
53
+ this.onPointerMove = async (event) => {
54
+ var _a, _b;
55
+ const isMultiTouch = !(event instanceof MouseEvent) && event.touches.length > 1;
56
+ const imageViewer = (_b = (_a = this.slides[this.activeSlideIndex]) === null || _a === void 0 ? void 0 : _a.shadowRoot) === null || _b === void 0 ? void 0 : _b.querySelector("flip-file-viewer-image");
57
+ const showsZoomedImage = Boolean(imageViewer)
58
+ ? (await imageViewer.getZoom()) > 1
59
+ : false;
60
+ if (isMultiTouch || showsZoomedImage) {
61
+ return;
62
+ }
55
63
  if (this.dragging) {
56
64
  event.preventDefault();
57
65
  const deltaX = event instanceof MouseEvent
@@ -116,6 +124,7 @@ export class FlipLightbox {
116
124
  this.unlockBodyScroll();
117
125
  setTimeout(() => {
118
126
  this.modal.hide();
127
+ this.resetImageZoom();
119
128
  this.closing = false;
120
129
  }, 150);
121
130
  }
@@ -153,6 +162,7 @@ export class FlipLightbox {
153
162
  }, 300);
154
163
  this.stopAllMediaPlayers();
155
164
  this.updateMediaPlayers();
165
+ this.resetImageZoom();
156
166
  }
157
167
  setSlideAttributes() {
158
168
  this.slides.forEach((slide) => {
@@ -180,6 +190,15 @@ export class FlipLightbox {
180
190
  stopAllMediaPlayers() {
181
191
  this.mediaPlayers.forEach((mediaPlayer) => mediaPlayer.pause());
182
192
  }
193
+ resetImageZoom() {
194
+ this.slides.forEach((slide) => {
195
+ var _a;
196
+ const imageViewer = (_a = slide === null || slide === void 0 ? void 0 : slide.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector("flip-file-viewer-image");
197
+ if (Boolean(imageViewer)) {
198
+ imageViewer.resetZoom();
199
+ }
200
+ });
201
+ }
183
202
  render() {
184
203
  const showPagination = this.slides.length > 1;
185
204
  const className = classnames("lightbox", {
@@ -77,7 +77,7 @@
77
77
 
78
78
  @media (min-width: 768px) {
79
79
  .modal--scrolled .modal__header {
80
- border-bottom: var(--s-border-width-default) solid var(--s-border-default);
80
+ border-bottom-color: var(--s-border-default);
81
81
  }
82
82
  }
83
83
 
@@ -145,7 +145,7 @@
145
145
  padding-right: calc(var(--s-space-16) + 2.5rem + var(--s-space-8));
146
146
  padding-bottom: var(--s-space-16);
147
147
  padding-left: var(--s-space-24);
148
- border-bottom: none
148
+ border-bottom: var(--s-border-width-default) solid transparent
149
149
  }
150
150
  }
151
151
 
@@ -12,7 +12,7 @@
12
12
  font-size: var(--s-font-size-sm);
13
13
  line-height: var(--s-line-height-sm);
14
14
  cursor: pointer;
15
- gap: var(--s-space-8);
15
+ gap: calc(var(--s-space-8) - var(--s-space-2));
16
16
  }
17
17
 
18
18
  :host(:hover) {
@@ -24,10 +24,14 @@
24
24
  }
25
25
 
26
26
  :host(:focus) {
27
- background-color: var(--s-surface-hovered);
28
27
  outline: none;
29
28
  }
30
29
 
30
+ :host(:focus) .tree-navigation-item__label {
31
+ border-radius: var(--s-border-radius-xs);
32
+ box-shadow: 0 0 0 0.125rem var(--s-focus-default);
33
+ }
34
+
31
35
  :host(.tree-navigation-item--active) {
32
36
  background-color: var(--s-surface-raised-default);
33
37
  box-shadow: inset 0.25rem 0 0 0 var(--s-surface-highlight-default);
@@ -58,4 +62,6 @@
58
62
  min-width: 0;
59
63
  white-space: nowrap;
60
64
  text-overflow: ellipsis;
65
+ padding-right: var(--s-space-2);
66
+ padding-left: var(--s-space-2);
61
67
  }
@@ -14,7 +14,11 @@ const FlipFileViewerImage = /*@__PURE__*/ proxyCustomElement(class extends HTMLE
14
14
  this.activate = createEvent(this, "activate", 7);
15
15
  this.description = "";
16
16
  this.errorMessage = "File could not be loaded.";
17
+ this.maxZoom = 3;
17
18
  this.loading = true;
19
+ this.panX = 0;
20
+ this.panY = 0;
21
+ this.zoom = 1;
18
22
  this.onError = () => {
19
23
  this.error = true;
20
24
  this.loading = false;
@@ -23,6 +27,142 @@ const FlipFileViewerImage = /*@__PURE__*/ proxyCustomElement(class extends HTMLE
23
27
  this.error = false;
24
28
  this.loading = false;
25
29
  };
30
+ this.onDblClick = (event) => {
31
+ this.clickToZoom(event);
32
+ };
33
+ this.onWheel = (event) => {
34
+ event.preventDefault();
35
+ const zoom = Math.min(Math.max(1, this.zoom + (-1 * event.deltaY) / 100), this.maxZoom);
36
+ if (zoom === this.zoom) {
37
+ return;
38
+ }
39
+ const centerX = event.offsetX;
40
+ const centerY = event.offsetY;
41
+ this.updateTransformOrigin(centerX, centerY);
42
+ this.updateZoomAndPan(zoom, 0, 0);
43
+ };
44
+ this.onPointerDown = (event) => {
45
+ this.startPan(event);
46
+ };
47
+ this.onPointerMove = (event) => {
48
+ this.pan(event);
49
+ };
50
+ this.onPointerUp = () => {
51
+ this.endPan();
52
+ };
53
+ this.onTouchStart = (event) => {
54
+ event.preventDefault();
55
+ if (event.touches.length === 2) {
56
+ this.startPinchToZoom(event);
57
+ }
58
+ };
59
+ this.onTouchMove = (event) => {
60
+ event.preventDefault();
61
+ if (this.pinching) {
62
+ this.pinchToZoom(event);
63
+ }
64
+ };
65
+ this.onTouchEnd = (event) => {
66
+ event.preventDefault();
67
+ if (this.pinching) {
68
+ this.endPinchToZoom();
69
+ }
70
+ };
71
+ this.startPinchToZoom = (event) => {
72
+ if (!Boolean(this.imageEl)) {
73
+ return;
74
+ }
75
+ this.pinchDistance = this.getPinchDistance(event);
76
+ this.pinching = true;
77
+ };
78
+ this.pinchToZoom = (event) => {
79
+ const distance = this.getPinchDistance(event) - this.pinchDistance;
80
+ const zoom = Math.min(Math.max(1, this.zoom + distance / 100), this.maxZoom);
81
+ if (this.zoom === zoom) {
82
+ return;
83
+ }
84
+ this.pinchDistance = this.getPinchDistance(event);
85
+ this.updateZoomAndPan(zoom);
86
+ };
87
+ this.endPinchToZoom = () => {
88
+ this.pinching = false;
89
+ if (Math.abs(this.zoom - 1) < 0.2) {
90
+ this.zoom = 1;
91
+ this.imageEl.style.transform = "";
92
+ }
93
+ };
94
+ this.getPinchDistance = (event) => {
95
+ return Math.hypot(event.touches[0].pageX - event.touches[1].pageX, event.touches[0].pageY - event.touches[1].pageY);
96
+ };
97
+ this.clickToZoom = (event) => {
98
+ const supportsMultiTouch = navigator.maxTouchPoints > 1;
99
+ if (supportsMultiTouch) {
100
+ return;
101
+ }
102
+ if (this.zoom === 1) {
103
+ const centerX = event.pageX - this.el.getBoundingClientRect().x;
104
+ const centerY = event.pageY - this.el.getBoundingClientRect().y;
105
+ this.updateTransformOrigin(centerX, centerY);
106
+ this.updateZoomAndPan(2);
107
+ }
108
+ else {
109
+ this.updateZoomAndPan(1);
110
+ }
111
+ };
112
+ this.updateZoomAndPan = (zoom, panX, panY) => {
113
+ const newZoom = zoom === undefined ? this.zoom : zoom;
114
+ const zoomDiff = newZoom - this.zoom;
115
+ const newPanX = panX === undefined ? this.panX + this.panX * zoomDiff : panX;
116
+ const newPanY = panX === undefined ? this.panY + this.panY * zoomDiff : panY;
117
+ const previousPanX = this.panX;
118
+ const previousPanY = this.panY;
119
+ this.zoom = newZoom;
120
+ this.panX = newPanX;
121
+ this.panY = newPanY;
122
+ const parentRect = (this.el.parentElement || this.el).getBoundingClientRect();
123
+ const imageRect = this.imageEl.getBoundingClientRect();
124
+ const outOfBoundsX = (imageRect.right < parentRect.right && newPanX < previousPanX) ||
125
+ (imageRect.left > parentRect.left && newPanX > previousPanX);
126
+ const outOfBoundsY = (imageRect.bottom < parentRect.bottom && newPanY < previousPanY) ||
127
+ (imageRect.top > parentRect.top && newPanY > previousPanY);
128
+ if (outOfBoundsX) {
129
+ this.panX = previousPanX;
130
+ }
131
+ if (outOfBoundsY) {
132
+ this.panY = previousPanY;
133
+ }
134
+ if (this.zoom === 1) {
135
+ this.panX = 0;
136
+ this.panY = 0;
137
+ }
138
+ this.imageEl.style.transform = `matrix(${this.zoom}, 0, 0, ${this.zoom}, ${this.panX}, ${this.panY})`;
139
+ };
140
+ this.updateTransformOrigin = (x, y) => {
141
+ this.transformOriginX = x;
142
+ this.transformOriginY = y;
143
+ this.imageEl.style.transformOrigin = `${this.transformOriginX}px ${this.transformOriginY}px`;
144
+ };
145
+ this.startPan = (event) => {
146
+ this.panning = true;
147
+ this.previousScreenX = event.screenX;
148
+ this.previousScreenY = event.screenY;
149
+ };
150
+ this.pan = (event) => {
151
+ const previousScreenX = this.previousScreenX || 0;
152
+ const previousScreenY = this.previousScreenY || 0;
153
+ this.previousScreenX = event.screenX;
154
+ this.previousScreenY = event.screenY;
155
+ if (!this.panning || this.pinching) {
156
+ return;
157
+ }
158
+ event.preventDefault();
159
+ const panX = this.panX + event.screenX - previousScreenX;
160
+ const panY = this.panY + event.screenY - previousScreenY;
161
+ this.updateZoomAndPan(this.zoom, panX, panY);
162
+ };
163
+ this.endPan = () => {
164
+ this.panning = false;
165
+ };
26
166
  }
27
167
  componentDidLoad() {
28
168
  this.activate.emit(this.el);
@@ -31,8 +171,22 @@ const FlipFileViewerImage = /*@__PURE__*/ proxyCustomElement(class extends HTMLE
31
171
  this.error = false;
32
172
  this.loading = true;
33
173
  }
174
+ /**
175
+ * Get the current zoom.
176
+ * @returns
177
+ */
178
+ async getZoom() {
179
+ return this.zoom;
180
+ }
181
+ /**
182
+ * Resets the zoom.
183
+ * @returns
184
+ */
185
+ async resetZoom() {
186
+ return this.updateZoomAndPan(1);
187
+ }
34
188
  render() {
35
- return (h(Host, { class: "file-viewer-image" }, this.error && (h("flip-inline-error", { class: "file-viewer-image__error", message: this.errorMessage })), h("img", { alt: this.description, class: "file-viewer-image__image", onError: this.onError, onLoad: this.onLoad, src: this.file }), this.loading && (h("div", { class: "file-viewer-image__spinner" }, h("flip-spinner", null)))));
189
+ return (h(Host, { class: "file-viewer-image", onDblClick: this.onDblClick, onWheel: this.onWheel, onPointerDown: this.onPointerDown, onPointerMove: this.onPointerMove, onPointerUp: this.onPointerUp, onTouchStart: this.onTouchStart, onTouchMove: this.onTouchMove, onTouchEnd: this.onTouchEnd }, this.error && (h("flip-inline-error", { class: "file-viewer-image__error", message: this.errorMessage })), h("img", { alt: this.description, class: "file-viewer-image__image", onError: this.onError, onLoad: this.onLoad, ref: (el) => (this.imageEl = el), src: this.file }), this.loading && (h("div", { class: "file-viewer-image__spinner" }, h("flip-spinner", null)))));
36
190
  }
37
191
  get el() { return this; }
38
192
  static get watchers() { return {
@@ -43,8 +197,11 @@ const FlipFileViewerImage = /*@__PURE__*/ proxyCustomElement(class extends HTMLE
43
197
  "description": [1],
44
198
  "errorMessage": [1, "error-message"],
45
199
  "file": [1],
200
+ "maxZoom": [2, "max-zoom"],
46
201
  "error": [32],
47
- "loading": [32]
202
+ "loading": [32],
203
+ "getZoom": [64],
204
+ "resetZoom": [64]
48
205
  }]);
49
206
  function defineCustomElement() {
50
207
  if (typeof customElements === "undefined") {
@@ -53,7 +53,6 @@ const FlipLightbox$1 = /*@__PURE__*/ proxyCustomElement(class extends HTMLElemen
53
53
  this.updateMediaPlayers();
54
54
  };
55
55
  this.onPointerDown = (event) => {
56
- event.preventDefault();
57
56
  this.dragging = true;
58
57
  this.dragStartPosition =
59
58
  event instanceof MouseEvent ? event.clientX : event.touches[0].clientX;
@@ -61,7 +60,16 @@ const FlipLightbox$1 = /*@__PURE__*/ proxyCustomElement(class extends HTMLElemen
61
60
  slide.style.transition = "none";
62
61
  });
63
62
  };
64
- this.onPointerMove = (event) => {
63
+ this.onPointerMove = async (event) => {
64
+ var _a, _b;
65
+ const isMultiTouch = !(event instanceof MouseEvent) && event.touches.length > 1;
66
+ const imageViewer = (_b = (_a = this.slides[this.activeSlideIndex]) === null || _a === void 0 ? void 0 : _a.shadowRoot) === null || _b === void 0 ? void 0 : _b.querySelector("flip-file-viewer-image");
67
+ const showsZoomedImage = Boolean(imageViewer)
68
+ ? (await imageViewer.getZoom()) > 1
69
+ : false;
70
+ if (isMultiTouch || showsZoomedImage) {
71
+ return;
72
+ }
65
73
  if (this.dragging) {
66
74
  event.preventDefault();
67
75
  const deltaX = event instanceof MouseEvent
@@ -126,6 +134,7 @@ const FlipLightbox$1 = /*@__PURE__*/ proxyCustomElement(class extends HTMLElemen
126
134
  this.unlockBodyScroll();
127
135
  setTimeout(() => {
128
136
  this.modal.hide();
137
+ this.resetImageZoom();
129
138
  this.closing = false;
130
139
  }, 150);
131
140
  }
@@ -163,6 +172,7 @@ const FlipLightbox$1 = /*@__PURE__*/ proxyCustomElement(class extends HTMLElemen
163
172
  }, 300);
164
173
  this.stopAllMediaPlayers();
165
174
  this.updateMediaPlayers();
175
+ this.resetImageZoom();
166
176
  }
167
177
  setSlideAttributes() {
168
178
  this.slides.forEach((slide) => {
@@ -190,6 +200,15 @@ const FlipLightbox$1 = /*@__PURE__*/ proxyCustomElement(class extends HTMLElemen
190
200
  stopAllMediaPlayers() {
191
201
  this.mediaPlayers.forEach((mediaPlayer) => mediaPlayer.pause());
192
202
  }
203
+ resetImageZoom() {
204
+ this.slides.forEach((slide) => {
205
+ var _a;
206
+ const imageViewer = (_a = slide === null || slide === void 0 ? void 0 : slide.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector("flip-file-viewer-image");
207
+ if (Boolean(imageViewer)) {
208
+ imageViewer.resetZoom();
209
+ }
210
+ });
211
+ }
193
212
  render() {
194
213
  const showPagination = this.slides.length > 1;
195
214
  const className = classnames("lightbox", {
@@ -7,7 +7,7 @@ import { d as defineCustomElement$4 } from './flip-button-group2.js';
7
7
  import { d as defineCustomElement$3 } from './flip-heading2.js';
8
8
  import { d as defineCustomElement$2 } from './flip-stack2.js';
9
9
 
10
- const flipModalCss = ":host{--flip-ghost-button-background-default:var(--s-surface-overlay-default);--flip-ghost-button-background-hovered:var(--s-surface-overlay-hovered);--flip-ghost-button-background-pressed:var(--s-surface-overlay-pressed);display:block}:host *{box-sizing:border-box}.modal{position:fixed;z-index:var(--s-z-40);display:flex;justify-content:center;align-items:center;inset:0}.modal[aria-hidden=\"true\"]{display:none}.modal:not(.modal--closing) .modal__backdrop{-webkit-animation:0.15s modal-backdrop-fade-in;animation:0.15s modal-backdrop-fade-in}@media (prefers-reduced-motion){.modal:not(.modal--closing) .modal__backdrop{-webkit-animation:none;animation:none}}.modal:not(.modal--closing) .modal__body{-webkit-animation:0.15s modal-scale-in;animation:0.15s modal-scale-in}@media (prefers-reduced-motion){.modal:not(.modal--closing) .modal__body{-webkit-animation:none;animation:none}}.modal--closing{-webkit-animation:0.15s modal-fade-out;animation:0.15s modal-fade-out;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards}@media (prefers-reduced-motion){.modal--closing{-webkit-animation:none;animation:none}}@media (min-width: 768px){.modal--scrollable .modal__content{padding-bottom:0}}.modal--scrollable:not(.modal--scrolled-down) .modal__controls{border-top:var(--s-border-width-default) solid var(--s-border-default)}@media (min-width: 768px){.modal--scrolled .modal__header{border-bottom:var(--s-border-width-default) solid var(--s-border-default)}}.modal__backdrop{position:fixed;background-color:rgba(0, 0, 0, 0.2);inset:0}.modal__body{position:relative;z-index:var(--s-z-40);display:flex;width:100vw;height:100vh;background-color:var(--s-surface-overlay-default);flex-direction:column}@media (min-width: 768px){.modal__body{width:90vw;max-width:33.75rem;height:auto;max-height:90vh;border-radius:var(--s-border-radius-base);box-shadow:0.125rem 0.25rem 1rem rgba(0, 0, 0, 0.14)}}.modal__close-button{position:absolute;top:var(--s-space-8);left:var(--s-space-8)}@media (min-width: 768px){.modal__close-button{top:var(--s-space-16);right:var(--s-space-16);left:auto}}.modal__header{display:flex;height:3.5rem;padding-top:var(--s-space-8);padding-right:var(--s-space-16);padding-bottom:var(--s-space-8);padding-left:calc(var(--s-space-8) + 2.5rem + var(--s-space-8));flex-shrink:0;align-items:center;border-bottom:var(--s-border-width-default) solid var(--s-border-default);gap:var(--s-space-16)}@media (min-width: 768px){.modal__header{height:4.125rem;padding-top:var(--s-space-24);padding-right:calc(var(--s-space-16) + 2.5rem + var(--s-space-8));padding-bottom:var(--s-space-16);padding-left:var(--s-space-24);border-bottom:none}}.modal__heading{overflow:hidden}.modal__heading .heading{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.modal__content{overflow-x:hidden;overflow-y:auto;padding-top:var(--s-space-24);padding-right:var(--s-space-16);padding-bottom:var(--s-space-24);padding-left:var(--s-space-16);flex-grow:1;line-height:var(--s-line-height-base)}.modal__content ::slotted(*){margin:0}@media (min-width: 768px){.modal__content{padding-top:0;padding-right:var(--s-space-24);padding-bottom:var(--s-space-16);padding-left:var(--s-space-24)}}.modal__controls{display:flex;padding-top:var(--s-space-16);padding-right:var(--s-space-24);padding-bottom:var(--s-space-16);padding-left:var(--s-space-24);flex-shrink:0;justify-content:flex-end}@-webkit-keyframes modal-scale-in{from{transform:scale(0)}to{transform:scale(1)}}@keyframes modal-scale-in{from{transform:scale(0)}to{transform:scale(1)}}@-webkit-keyframes modal-backdrop-fade-in{from{opacity:0}to{opacity:1}}@keyframes modal-backdrop-fade-in{from{opacity:0}to{opacity:1}}@-webkit-keyframes modal-fade-out{from{opacity:1}to{opacity:0}}@keyframes modal-fade-out{from{opacity:1}to{opacity:0}}";
10
+ const flipModalCss = ":host{--flip-ghost-button-background-default:var(--s-surface-overlay-default);--flip-ghost-button-background-hovered:var(--s-surface-overlay-hovered);--flip-ghost-button-background-pressed:var(--s-surface-overlay-pressed);display:block}:host *{box-sizing:border-box}.modal{position:fixed;z-index:var(--s-z-40);display:flex;justify-content:center;align-items:center;inset:0}.modal[aria-hidden=\"true\"]{display:none}.modal:not(.modal--closing) .modal__backdrop{-webkit-animation:0.15s modal-backdrop-fade-in;animation:0.15s modal-backdrop-fade-in}@media (prefers-reduced-motion){.modal:not(.modal--closing) .modal__backdrop{-webkit-animation:none;animation:none}}.modal:not(.modal--closing) .modal__body{-webkit-animation:0.15s modal-scale-in;animation:0.15s modal-scale-in}@media (prefers-reduced-motion){.modal:not(.modal--closing) .modal__body{-webkit-animation:none;animation:none}}.modal--closing{-webkit-animation:0.15s modal-fade-out;animation:0.15s modal-fade-out;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards}@media (prefers-reduced-motion){.modal--closing{-webkit-animation:none;animation:none}}@media (min-width: 768px){.modal--scrollable .modal__content{padding-bottom:0}}.modal--scrollable:not(.modal--scrolled-down) .modal__controls{border-top:var(--s-border-width-default) solid var(--s-border-default)}@media (min-width: 768px){.modal--scrolled .modal__header{border-bottom-color:var(--s-border-default)}}.modal__backdrop{position:fixed;background-color:rgba(0, 0, 0, 0.2);inset:0}.modal__body{position:relative;z-index:var(--s-z-40);display:flex;width:100vw;height:100vh;background-color:var(--s-surface-overlay-default);flex-direction:column}@media (min-width: 768px){.modal__body{width:90vw;max-width:33.75rem;height:auto;max-height:90vh;border-radius:var(--s-border-radius-base);box-shadow:0.125rem 0.25rem 1rem rgba(0, 0, 0, 0.14)}}.modal__close-button{position:absolute;top:var(--s-space-8);left:var(--s-space-8)}@media (min-width: 768px){.modal__close-button{top:var(--s-space-16);right:var(--s-space-16);left:auto}}.modal__header{display:flex;height:3.5rem;padding-top:var(--s-space-8);padding-right:var(--s-space-16);padding-bottom:var(--s-space-8);padding-left:calc(var(--s-space-8) + 2.5rem + var(--s-space-8));flex-shrink:0;align-items:center;border-bottom:var(--s-border-width-default) solid var(--s-border-default);gap:var(--s-space-16)}@media (min-width: 768px){.modal__header{height:4.125rem;padding-top:var(--s-space-24);padding-right:calc(var(--s-space-16) + 2.5rem + var(--s-space-8));padding-bottom:var(--s-space-16);padding-left:var(--s-space-24);border-bottom:var(--s-border-width-default) solid transparent}}.modal__heading{overflow:hidden}.modal__heading .heading{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.modal__content{overflow-x:hidden;overflow-y:auto;padding-top:var(--s-space-24);padding-right:var(--s-space-16);padding-bottom:var(--s-space-24);padding-left:var(--s-space-16);flex-grow:1;line-height:var(--s-line-height-base)}.modal__content ::slotted(*){margin:0}@media (min-width: 768px){.modal__content{padding-top:0;padding-right:var(--s-space-24);padding-bottom:var(--s-space-16);padding-left:var(--s-space-24)}}.modal__controls{display:flex;padding-top:var(--s-space-16);padding-right:var(--s-space-24);padding-bottom:var(--s-space-16);padding-left:var(--s-space-24);flex-shrink:0;justify-content:flex-end}@-webkit-keyframes modal-scale-in{from{transform:scale(0)}to{transform:scale(1)}}@keyframes modal-scale-in{from{transform:scale(0)}to{transform:scale(1)}}@-webkit-keyframes modal-backdrop-fade-in{from{opacity:0}to{opacity:1}}@keyframes modal-backdrop-fade-in{from{opacity:0}to{opacity:1}}@-webkit-keyframes modal-fade-out{from{opacity:1}to{opacity:0}}@keyframes modal-fade-out{from{opacity:1}to{opacity:0}}";
11
11
 
12
12
  const FlipModal$1 = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
13
13
  constructor() {
@@ -1,7 +1,7 @@
1
1
  import { proxyCustomElement, HTMLElement, h, Host } from '@stencil/core/internal/client';
2
2
  import { c as classnames } from './index2.js';
3
3
 
4
- const flipTreeNavigationItemCss = ":host{display:inline-flex;width:100%;height:2.5rem;padding-right:var(--s-space-16);padding-left:calc(var(--s-space-16) + 1.5rem + var(--s-space-8));flex-shrink:0;justify-content:flex-start;align-items:center;color:var(--s-text-default);background-color:var(--s-surface-default);font-size:var(--s-font-size-sm);line-height:var(--s-line-height-sm);cursor:pointer;gap:var(--s-space-8)}:host(:hover){background-color:var(--s-surface-hovered)}:host(:active){background-color:var(--s-surface-pressed)}:host(:focus){background-color:var(--s-surface-hovered);outline:none}:host(.tree-navigation-item--active){background-color:var(--s-surface-raised-default);box-shadow:inset 0.25rem 0 0 0 var(--s-surface-highlight-default)}:host(.tree-navigation-item--active:hover){background-color:var(--s-surface-raised-hovered)}:host(.tree-navigation-item--active:active){background-color:var(--s-surface-raised-pressed)}:host(.tree-navigation-item--has-icon){padding-left:var(--s-space-16)}:host *{box-sizing:border-box}.tree-navigation-item__icon{display:inline-flex}.tree-navigation-item__label{overflow:hidden;min-width:0;white-space:nowrap;text-overflow:ellipsis}";
4
+ const flipTreeNavigationItemCss = ":host{display:inline-flex;width:100%;height:2.5rem;padding-right:var(--s-space-16);padding-left:calc(var(--s-space-16) + 1.5rem + var(--s-space-8));flex-shrink:0;justify-content:flex-start;align-items:center;color:var(--s-text-default);background-color:var(--s-surface-default);font-size:var(--s-font-size-sm);line-height:var(--s-line-height-sm);cursor:pointer;gap:calc(var(--s-space-8) - var(--s-space-2))}:host(:hover){background-color:var(--s-surface-hovered)}:host(:active){background-color:var(--s-surface-pressed)}:host(:focus){outline:none}:host(:focus) .tree-navigation-item__label{border-radius:var(--s-border-radius-xs);box-shadow:0 0 0 0.125rem var(--s-focus-default)}:host(.tree-navigation-item--active){background-color:var(--s-surface-raised-default);box-shadow:inset 0.25rem 0 0 0 var(--s-surface-highlight-default)}:host(.tree-navigation-item--active:hover){background-color:var(--s-surface-raised-hovered)}:host(.tree-navigation-item--active:active){background-color:var(--s-surface-raised-pressed)}:host(.tree-navigation-item--has-icon){padding-left:var(--s-space-16)}:host *{box-sizing:border-box}.tree-navigation-item__icon{display:inline-flex}.tree-navigation-item__label{overflow:hidden;min-width:0;white-space:nowrap;text-overflow:ellipsis;padding-right:var(--s-space-2);padding-left:var(--s-space-2)}";
5
5
 
6
6
  const FlipTreeNavigationItem$1 = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
7
7
  constructor() {