@vkontakte/vkui 7.11.4 → 7.11.6

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "type": "module",
3
- "version": "7.11.4",
3
+ "version": "7.11.6",
4
4
  "name": "@vkontakte/vkui",
5
5
  "description": "VKUI library",
6
6
  "module": "./dist/index.js",
@@ -20,33 +20,39 @@
20
20
  }
21
21
  }
22
22
  @supports not (scrollbar-color: auto) {
23
- .scrollbarHidden::-webkit-scrollbar {
24
- display: none;
25
- }
23
+ /**
24
+ * Android WebView не поддерживает scrollbar-color, поэтому отрисовываем
25
+ * полосы прокрутки только если основное указательное устройство мышь
26
+ */
27
+ @media (--pointer-has) {
28
+ .scrollbarHidden::-webkit-scrollbar {
29
+ display: none;
30
+ }
26
31
 
27
- .host::-webkit-scrollbar {
28
- inline-size: 12px;
29
- block-size: 12px;
30
- background: 0 0;
31
- }
32
+ .host::-webkit-scrollbar {
33
+ inline-size: 12px;
34
+ block-size: 12px;
35
+ background: 0 0;
36
+ }
32
37
 
33
- .host::-webkit-scrollbar-track,
34
- .host::-webkit-scrollbar-corner {
35
- background: transparent;
36
- }
38
+ .host::-webkit-scrollbar-track,
39
+ .host::-webkit-scrollbar-corner {
40
+ background: transparent;
41
+ }
37
42
 
38
- .host::-webkit-scrollbar-thumb,
39
- .host::-webkit-scrollbar-thumb {
40
- background-color: var(--vkui--color_icon_tertiary_alpha);
41
- background-clip: padding-box, content-box;
42
- border: 3px solid transparent;
43
- border-radius: 6px;
44
- }
43
+ .host::-webkit-scrollbar-thumb,
44
+ .host::-webkit-scrollbar-thumb {
45
+ background-color: var(--vkui--color_icon_tertiary_alpha);
46
+ background-clip: padding-box, content-box;
47
+ border: 3px solid transparent;
48
+ border-radius: 6px;
49
+ }
45
50
 
46
- .host::-webkit-scrollbar-thumb:hover,
47
- .host::-webkit-scrollbar-thumb:active {
48
- background-color: var(--vkui--color_icon_tertiary_alpha--hover);
49
- border: 2px solid transparent;
51
+ .host::-webkit-scrollbar-thumb:hover,
52
+ .host::-webkit-scrollbar-thumb:active {
53
+ background-color: var(--vkui--color_icon_tertiary_alpha--hover);
54
+ border: 2px solid transparent;
55
+ }
50
56
  }
51
57
  }
52
58
 
@@ -1 +1 @@
1
- {"version":3,"sources":["./CustomScrollView.module.css"],"names":["host","scrollbarHidden","overscrollBehaviorContain","overscrollBehaviorNone","scrollBehaviorSmooth","horizontalScrollEnabled"],"mappings":"AAAA;AAAA,E,aAAAA,M,WAAA;AAAA,E,aAQEA,M,WARF;AAAA,E,aAaEC,iB,WAbF;AAAA,E,aAsBEA,iB,WAtBF;AAAA,E,aA0BED,M,WA1BF;AAAA,E,aAgCEA,M,WAhCF;AAAA,E,aAiCIA,M,WAjCJ;AAAA,E,aAqCEA,M,WArCF;AAAA,E,aAsCIA,M,WAtCJ;AAAA,E,aA6CEA,M,WA7CF;AAAA,E,aA8CIA,M,WA9CJ;AAAA,E,aAoDAE,2B,WApDA;AAAA,E,aAwDAC,wB,WAxDA;AAAA,E,aA4DAC,sB,WA5DA;AAAA,E,aAgEAC,yB,WAhEA;AAAA;AAAA","file":"CustomScrollView.module.css.d.ts","sourceRoot":""}
1
+ {"version":3,"sources":["./CustomScrollView.module.css"],"names":["host","scrollbarHidden","overscrollBehaviorContain","overscrollBehaviorNone","scrollBehaviorSmooth","horizontalScrollEnabled"],"mappings":"AAAA;AAAA,E,aAAAA,M,WAAA;AAAA,E,aAQEA,M,WARF;AAAA,E,aAaEC,iB,WAbF;AAAA,E,aA2BIA,iB,WA3BJ;AAAA,E,aA+BID,M,WA/BJ;AAAA,E,aAqCIA,M,WArCJ;AAAA,E,aAsCQA,M,WAtCR;AAAA,E,aA0CIA,M,WA1CJ;AAAA,E,aA2CQA,M,WA3CR;AAAA,E,aAkDIA,M,WAlDJ;AAAA,E,aAmDQA,M,WAnDR;AAAA,E,aA0DAE,2B,WA1DA;AAAA,E,aA8DAC,wB,WA9DA;AAAA,E,aAkEAC,sB,WAlEA;AAAA,E,aAsEAC,yB,WAtEA;AAAA;AAAA","file":"CustomScrollView.module.css.d.ts","sourceRoot":""}
@@ -8,6 +8,53 @@ import { coordX, coordY, touchEnabled, type VKUITouchEvent } from '../../lib/tou
8
8
  import { useIsomorphicLayoutEffect } from '../../lib/useIsomorphicLayoutEffect';
9
9
  import type { HasComponent, HasRootRef } from '../../types';
10
10
 
11
+ interface EventWithType {
12
+ /**
13
+ * Тип события.
14
+ */
15
+ readonly type: string;
16
+ }
17
+
18
+ function isTouchEvent(event: EventWithType) {
19
+ return event.type.startsWith('touch');
20
+ }
21
+
22
+ type CheckEvent = (event: EventWithType) => void;
23
+
24
+ type IsEventLock = (event: EventWithType) => boolean;
25
+
26
+ /**
27
+ * Телефоны после touch событий могут отправлять события мыши,
28
+ * Это может происходить при обычном нажатии.
29
+ *
30
+ * Нельзя использовать хук во время рендеринга.
31
+ */
32
+ function useMouseEventLock(): [IsEventLock, CheckEvent] {
33
+ const isMouseEventLockRef = React.useRef<boolean>(false);
34
+ const timerRef = React.useRef<ReturnType<typeof setTimeout>>(undefined);
35
+
36
+ const isEventLock: IsEventLock = React.useCallback((event: EventWithType) => {
37
+ return !isTouchEvent(event) && isMouseEventLockRef.current === true;
38
+ }, []);
39
+
40
+ const checkEvent: CheckEvent = React.useCallback((event: EventWithType) => {
41
+ if (!isTouchEvent(event)) {
42
+ return;
43
+ }
44
+
45
+ isMouseEventLockRef.current = true;
46
+
47
+ clearTimeout(timerRef.current);
48
+ timerRef.current = setTimeout(() => {
49
+ isMouseEventLockRef.current = false;
50
+ }, 1000);
51
+ }, []);
52
+
53
+ React.useEffect(() => () => clearTimeout(timerRef.current), []);
54
+
55
+ return [isEventLock, checkEvent];
56
+ }
57
+
11
58
  /**
12
59
  * Костыль для правильной работы тайпскрипта.
13
60
  */
@@ -236,6 +283,8 @@ export const Touch = ({
236
283
  const didSlide = React.useRef(false);
237
284
  const disposeTargetNativeGestureEvents = React.useRef<VoidFunction | null>(null);
238
285
 
286
+ const [isEventLock, checkEventForLock] = useMouseEventLock();
287
+
239
288
  const cleanupTargetNativeGestureEvents = () => {
240
289
  gestureRef.current = null;
241
290
  if (disposeTargetNativeGestureEvents.current) {
@@ -246,10 +295,6 @@ export const Touch = ({
246
295
 
247
296
  React.useEffect(() => cleanupTargetNativeGestureEvents, []);
248
297
 
249
- const isTouchEvent = (event: MouseEvent | TouchEvent) => {
250
- return event.type.startsWith('touch');
251
- };
252
-
253
298
  /**
254
299
  * Note: используем `useStableCallback()`, чтобы не терялась область видимости `onEnd`/`onEndX`/`onEndY`.
255
300
  */
@@ -339,6 +384,13 @@ export const Touch = ({
339
384
  const handlePointerDown = useStableCallback(
340
385
  (event: React.MouseEvent<HTMLElement> | React.TouchEvent<HTMLElement> | TouchEvent) => {
341
386
  // Если touchstart сэмулировало mousedown, то заканчиваем обработку
387
+ if (isEventLock(event)) {
388
+ return;
389
+ }
390
+
391
+ // Помечаем что произошло touch событие
392
+ checkEventForLock(event);
393
+
342
394
  if (gestureRef.current !== null) {
343
395
  return;
344
396
  }
@@ -465,11 +517,6 @@ export const Touch = ({
465
517
  // handlePointerDown(onTouchStart устанавливается отдельно через initializeNativeTouchEventStartWithPassiveFalse)
466
518
  onMouseDownCapture={useCapture ? handlePointerDown : undefined}
467
519
  onMouseDown={!useCapture ? handlePointerDown : undefined}
468
- onPointerDown={(event: PointerEvent) => {
469
- if (event.pointerType === 'touch' || event.pointerType === 'pen') {
470
- event.preventDefault();
471
- }
472
- }}
473
520
  />
474
521
  );
475
522
  };
@@ -321,9 +321,19 @@ export class BottomSheetController {
321
321
  sheetScrollEl.contains(targetEl) &&
322
322
  sheetScrollEl.scrollHeight > sheetScrollEl.clientHeight
323
323
  ) {
324
- sheetScrollEl.style.setProperty('overflow-y', 'hidden');
324
+ const scrollbarWidth = sheetScrollEl.offsetWidth - sheetScrollEl.clientWidth;
325
+
326
+ Object.assign(sheetScrollEl.style, {
327
+ paddingInlineEnd: `${scrollbarWidth}px`,
328
+ overflowY: 'hidden',
329
+ boxSizing: 'border-box',
330
+ });
325
331
  return function dispose() {
326
- sheetScrollEl.style.removeProperty('overflow-y');
332
+ Object.assign(sheetScrollEl.style, {
333
+ paddingInlineEnd: '',
334
+ overflowY: '',
335
+ boxSizing: '',
336
+ });
327
337
  };
328
338
  }
329
339
  return noop;