@phosart/common 0.4.46 → 0.4.48

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.
@@ -53,9 +53,15 @@
53
53
  }
54
54
 
55
55
  function scrollDown() {
56
- if (!isComic) return;
56
+ if (!isComic || !bounded) return;
57
57
 
58
- bounded?.scrollBy({ behavior: 'smooth', top: containerHeight });
58
+ bounded.scrollBy({
59
+ behavior: 'smooth',
60
+ top: Math.min(
61
+ bounded.scrollHeight - bounded.clientHeight - bounded.scrollTop,
62
+ (containerHeight * 2) / 3
63
+ )
64
+ });
59
65
  }
60
66
 
61
67
  let w = $derived(width(piece.image));
@@ -64,6 +70,53 @@
64
70
  let config = useLibraryConfig();
65
71
 
66
72
  let nameInHeader = $derived(!config.modal?.hideNames && w > 500);
73
+ let pointerStartPos: [x: number, y: number] = $state([0, 0]);
74
+ let pointerEndPos: [x: number, y: number] = $state([0, 0]);
75
+ let pointerStartTime = $state(0);
76
+
77
+ function onPointerDown(e: PointerEvent) {
78
+ e.stopPropagation();
79
+
80
+ pointerStartPos = [e.screenX, e.screenY];
81
+ pointerStartTime = Date.now();
82
+ }
83
+ function onPointerMove(e: PointerEvent) {
84
+ pointerEndPos = [e.screenX, e.screenY];
85
+ }
86
+ function onPointerUp(e: PointerEvent) {
87
+ e.stopPropagation();
88
+
89
+ if (pointerStartTime === 0) {
90
+ return;
91
+ }
92
+
93
+ const [sx, sy] = pointerStartPos;
94
+ const [ex, ey] = [e.screenX || pointerEndPos[0], e.screenY || pointerEndPos[1]];
95
+ const [dx, dy] = [ex - sx, ey - sy];
96
+
97
+ const isCancel = e.screenX === 0 && e.screenY === 0;
98
+
99
+ const pointerDownTime = Date.now() - pointerStartTime;
100
+ pointerStartTime = 0;
101
+ // pixels per second
102
+ const velocity = (dx / pointerDownTime) * 1000;
103
+
104
+ if (Math.abs(velocity) < 50) {
105
+ if (!isCancel) {
106
+ scrollDown();
107
+ }
108
+ return;
109
+ }
110
+ if (Math.abs(dy) > 50 || Math.abs(dx) < window.screenLeft / 5 || Math.abs(velocity) < 200) {
111
+ return;
112
+ }
113
+
114
+ if (velocity > 0) {
115
+ onprev();
116
+ } else {
117
+ onnext();
118
+ }
119
+ }
67
120
  </script>
68
121
 
69
122
  <div class="image-section">
@@ -78,9 +131,17 @@
78
131
  ></div>
79
132
  </div>
80
133
 
81
- <div class="main-container" style={isComic ? 'overflow: visible' : ''}>
134
+ <!-- svelte-ignore a11y_no_static_element_interactions -->
135
+ <div
136
+ class="main-container overscroll-contain"
137
+ ondragstartcapture={(e) => e.preventDefault()}
138
+ onpointerdown={onPointerDown}
139
+ onpointerup={onPointerUp}
140
+ onpointercancel={onPointerUp}
141
+ onpointermove={onPointerMove}
142
+ >
82
143
  <div
83
- class="bounding-div"
144
+ class="bounding-div overscroll-contain"
84
145
  style={isComic ? 'overflow-y: scroll; align-items: flex-start; z-index: 100' : ''}
85
146
  bind:clientHeight={containerHeight}
86
147
  bind:clientWidth={containerWidth}
@@ -89,13 +150,12 @@
89
150
  <div class="flex flex-col">
90
151
  <div
91
152
  class="bounded-div"
92
- onclick={(e) => {
153
+ onkeypress={(e) => {
93
154
  e.stopPropagation();
94
155
  scrollDown();
95
156
  }}
96
- onkeypress={(e) => {
157
+ onclick={(e) => {
97
158
  e.stopPropagation();
98
- scrollDown();
99
159
  }}
100
160
  role="button"
101
161
  tabindex={-1}
@@ -121,7 +181,6 @@
121
181
  class="bounded-div"
122
182
  onclick={(e) => {
123
183
  e.stopPropagation();
124
- scrollDown();
125
184
  }}
126
185
  onkeypress={(e) => {
127
186
  e.stopPropagation();
@@ -167,7 +226,7 @@
167
226
  flex-direction: row;
168
227
  justify-content: center;
169
228
  align-items: center;
170
- overflow: visible;
229
+ overflow: hidden;
171
230
  max-height: calc(100% - var(--carousel-height));
172
231
  position: relative;
173
232
  height: 100%;
@@ -1 +1 @@
1
- {"version":3,"file":"ImageSection.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/ModalGallery/ImageSection.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,+CAA+C,CAAC;AAEvD,OAAO,KAAK,EAAE,QAAQ,EAAW,MAAM,gBAAgB,CAAC;AAMvD,UAAU,KAAK;IACd,KAAK,EAAE,QAAQ,CAAC;IAChB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,MAAM,EAAE,MAAM,IAAI,CAAC;CACnB;AAqHF,QAAA,MAAM,YAAY,2CAAwC,CAAC;AAC3D,KAAK,YAAY,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;AACpD,eAAe,YAAY,CAAC"}
1
+ {"version":3,"file":"ImageSection.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/ModalGallery/ImageSection.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,+CAA+C,CAAC;AAEvD,OAAO,KAAK,EAAE,QAAQ,EAAW,MAAM,gBAAgB,CAAC;AAMvD,UAAU,KAAK;IACd,KAAK,EAAE,QAAQ,CAAC;IAChB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,MAAM,EAAE,MAAM,IAAI,CAAC;CACnB;AAyKF,QAAA,MAAM,YAAY,2CAAwC,CAAC;AAC3D,KAAK,YAAY,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;AACpD,eAAe,YAAY,CAAC"}
@@ -41,6 +41,8 @@
41
41
  class="headline-container"
42
42
  onclick={(e) => e.stopPropagation()}
43
43
  onkeypress={(e) => e.stopPropagation()}
44
+ onpointerdown={(e) => e.stopPropagation()}
45
+ onpointerup={(e) => e.stopPropagation()}
44
46
  role="contentinfo"
45
47
  >
46
48
  <Headline {piece} bind:showingDescription showName={!config.modal?.hideNames && nameInHeader} />
@@ -50,6 +52,8 @@
50
52
  class="description-container"
51
53
  onclick={(e) => e.stopPropagation()}
52
54
  onkeypress={(e) => e.stopPropagation()}
55
+ onpointerdown={(e) => e.stopPropagation()}
56
+ onpointerup={(e) => e.stopPropagation()}
53
57
  role="contentinfo"
54
58
  >
55
59
  <Description
@@ -8,7 +8,16 @@
8
8
  modelGalleryOpens.push(false);
9
9
  return {
10
10
  set open(isOpen: boolean) {
11
+ const wasOpen = isAnyModelGalleryOpen();
11
12
  modelGalleryOpens[idx] = isOpen;
13
+ const nowOpen = isAnyModelGalleryOpen();
14
+ if (
15
+ wasOpen !== nowOpen &&
16
+ typeof window !== 'undefined' &&
17
+ typeof document !== 'undefined'
18
+ ) {
19
+ document.body.style.overflow = isOpen ? 'hidden' : 'auto';
20
+ }
12
21
  },
13
22
  get open() {
14
23
  return modelGalleryOpens[idx];
@@ -108,7 +117,10 @@
108
117
  </script>
109
118
 
110
119
  <Modal open={selected !== null && !!pieces[selected]} onclose={() => (selected = null)}>
111
- <div class="gallery-container" style={currentIsComic ? '--carousel-height: 25px' : ''}>
120
+ <div
121
+ class="gallery-container overscroll-contain"
122
+ style={currentIsComic ? '--carousel-height: 25px' : ''}
123
+ >
112
124
  <div
113
125
  role="button"
114
126
  tabindex={-1}
@@ -1 +1 @@
1
- {"version":3,"file":"ModalGallery.svelte.d.ts","sourceRoot":"","sources":["../src/lib/ModalGallery.svelte.ts"],"names":[],"mappings":"AAGC,OAAO,+CAA+C,CAAC;AAIvD,wBAAgB,qBAAqB;UAIlB,OAAO;EAOzB;AAED,wBAAgB,qBAAqB,YAEpC;AAGF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAQ7C,UAAU,KAAK;IACd,MAAM,EAAE,QAAQ,EAAE,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,OAAO,EAAE,OAAO,CAAC;CACjB;AA8GF,QAAA,MAAM,YAAY,uEAAwC,CAAC;AAC3D,KAAK,YAAY,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;AACpD,eAAe,YAAY,CAAC"}
1
+ {"version":3,"file":"ModalGallery.svelte.d.ts","sourceRoot":"","sources":["../src/lib/ModalGallery.svelte.ts"],"names":[],"mappings":"AAGC,OAAO,+CAA+C,CAAC;AAIvD,wBAAgB,qBAAqB;UAIlB,OAAO;EAgBzB;AAED,wBAAgB,qBAAqB,YAEpC;AAGF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAQ7C,UAAU,KAAK;IACd,MAAM,EAAE,QAAQ,EAAE,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,OAAO,EAAE,OAAO,CAAC;CACjB;AA8GF,QAAA,MAAM,YAAY,uEAAwC,CAAC;AAC3D,KAAK,YAAY,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;AACpD,eAAe,YAAY,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@phosart/common",
3
- "version": "0.4.46",
3
+ "version": "0.4.48",
4
4
  "files": [
5
5
  "dist",
6
6
  "!dist/**/*.test.*",
@@ -53,9 +53,15 @@
53
53
  }
54
54
 
55
55
  function scrollDown() {
56
- if (!isComic) return;
56
+ if (!isComic || !bounded) return;
57
57
 
58
- bounded?.scrollBy({ behavior: 'smooth', top: containerHeight });
58
+ bounded.scrollBy({
59
+ behavior: 'smooth',
60
+ top: Math.min(
61
+ bounded.scrollHeight - bounded.clientHeight - bounded.scrollTop,
62
+ (containerHeight * 2) / 3
63
+ )
64
+ });
59
65
  }
60
66
 
61
67
  let w = $derived(width(piece.image));
@@ -64,6 +70,53 @@
64
70
  let config = useLibraryConfig();
65
71
 
66
72
  let nameInHeader = $derived(!config.modal?.hideNames && w > 500);
73
+ let pointerStartPos: [x: number, y: number] = $state([0, 0]);
74
+ let pointerEndPos: [x: number, y: number] = $state([0, 0]);
75
+ let pointerStartTime = $state(0);
76
+
77
+ function onPointerDown(e: PointerEvent) {
78
+ e.stopPropagation();
79
+
80
+ pointerStartPos = [e.screenX, e.screenY];
81
+ pointerStartTime = Date.now();
82
+ }
83
+ function onPointerMove(e: PointerEvent) {
84
+ pointerEndPos = [e.screenX, e.screenY];
85
+ }
86
+ function onPointerUp(e: PointerEvent) {
87
+ e.stopPropagation();
88
+
89
+ if (pointerStartTime === 0) {
90
+ return;
91
+ }
92
+
93
+ const [sx, sy] = pointerStartPos;
94
+ const [ex, ey] = [e.screenX || pointerEndPos[0], e.screenY || pointerEndPos[1]];
95
+ const [dx, dy] = [ex - sx, ey - sy];
96
+
97
+ const isCancel = e.screenX === 0 && e.screenY === 0;
98
+
99
+ const pointerDownTime = Date.now() - pointerStartTime;
100
+ pointerStartTime = 0;
101
+ // pixels per second
102
+ const velocity = (dx / pointerDownTime) * 1000;
103
+
104
+ if (Math.abs(velocity) < 50) {
105
+ if (!isCancel) {
106
+ scrollDown();
107
+ }
108
+ return;
109
+ }
110
+ if (Math.abs(dy) > 50 || Math.abs(dx) < window.screenLeft / 5 || Math.abs(velocity) < 200) {
111
+ return;
112
+ }
113
+
114
+ if (velocity > 0) {
115
+ onprev();
116
+ } else {
117
+ onnext();
118
+ }
119
+ }
67
120
  </script>
68
121
 
69
122
  <div class="image-section">
@@ -78,9 +131,17 @@
78
131
  ></div>
79
132
  </div>
80
133
 
81
- <div class="main-container" style={isComic ? 'overflow: visible' : ''}>
134
+ <!-- svelte-ignore a11y_no_static_element_interactions -->
135
+ <div
136
+ class="main-container overscroll-contain"
137
+ ondragstartcapture={(e) => e.preventDefault()}
138
+ onpointerdown={onPointerDown}
139
+ onpointerup={onPointerUp}
140
+ onpointercancel={onPointerUp}
141
+ onpointermove={onPointerMove}
142
+ >
82
143
  <div
83
- class="bounding-div"
144
+ class="bounding-div overscroll-contain"
84
145
  style={isComic ? 'overflow-y: scroll; align-items: flex-start; z-index: 100' : ''}
85
146
  bind:clientHeight={containerHeight}
86
147
  bind:clientWidth={containerWidth}
@@ -89,13 +150,12 @@
89
150
  <div class="flex flex-col">
90
151
  <div
91
152
  class="bounded-div"
92
- onclick={(e) => {
153
+ onkeypress={(e) => {
93
154
  e.stopPropagation();
94
155
  scrollDown();
95
156
  }}
96
- onkeypress={(e) => {
157
+ onclick={(e) => {
97
158
  e.stopPropagation();
98
- scrollDown();
99
159
  }}
100
160
  role="button"
101
161
  tabindex={-1}
@@ -121,7 +181,6 @@
121
181
  class="bounded-div"
122
182
  onclick={(e) => {
123
183
  e.stopPropagation();
124
- scrollDown();
125
184
  }}
126
185
  onkeypress={(e) => {
127
186
  e.stopPropagation();
@@ -167,7 +226,7 @@
167
226
  flex-direction: row;
168
227
  justify-content: center;
169
228
  align-items: center;
170
- overflow: visible;
229
+ overflow: hidden;
171
230
  max-height: calc(100% - var(--carousel-height));
172
231
  position: relative;
173
232
  height: 100%;
@@ -41,6 +41,8 @@
41
41
  class="headline-container"
42
42
  onclick={(e) => e.stopPropagation()}
43
43
  onkeypress={(e) => e.stopPropagation()}
44
+ onpointerdown={(e) => e.stopPropagation()}
45
+ onpointerup={(e) => e.stopPropagation()}
44
46
  role="contentinfo"
45
47
  >
46
48
  <Headline {piece} bind:showingDescription showName={!config.modal?.hideNames && nameInHeader} />
@@ -50,6 +52,8 @@
50
52
  class="description-container"
51
53
  onclick={(e) => e.stopPropagation()}
52
54
  onkeypress={(e) => e.stopPropagation()}
55
+ onpointerdown={(e) => e.stopPropagation()}
56
+ onpointerup={(e) => e.stopPropagation()}
53
57
  role="contentinfo"
54
58
  >
55
59
  <Description
@@ -8,7 +8,16 @@
8
8
  modelGalleryOpens.push(false);
9
9
  return {
10
10
  set open(isOpen: boolean) {
11
+ const wasOpen = isAnyModelGalleryOpen();
11
12
  modelGalleryOpens[idx] = isOpen;
13
+ const nowOpen = isAnyModelGalleryOpen();
14
+ if (
15
+ wasOpen !== nowOpen &&
16
+ typeof window !== 'undefined' &&
17
+ typeof document !== 'undefined'
18
+ ) {
19
+ document.body.style.overflow = isOpen ? 'hidden' : 'auto';
20
+ }
12
21
  },
13
22
  get open() {
14
23
  return modelGalleryOpens[idx];
@@ -108,7 +117,10 @@
108
117
  </script>
109
118
 
110
119
  <Modal open={selected !== null && !!pieces[selected]} onclose={() => (selected = null)}>
111
- <div class="gallery-container" style={currentIsComic ? '--carousel-height: 25px' : ''}>
120
+ <div
121
+ class="gallery-container overscroll-contain"
122
+ style={currentIsComic ? '--carousel-height: 25px' : ''}
123
+ >
112
124
  <div
113
125
  role="button"
114
126
  tabindex={-1}