From 777ff14a1cb4e59b9018b8610bfbac95ff06786c Mon Sep 17 00:00:00 2001 From: "e.muhamethanov" Date: Thu, 3 Oct 2024 16:48:16 +0300 Subject: [PATCH 1/8] feat(CustomScrollView): refactor CustomScrollView to the native approach --- .../components/ChipsSelect/ChipsSelect.tsx | 5 +- .../CustomScrollView.e2e-playground.tsx | 18 +- .../CustomScrollView.module.css | 185 ++-------- .../CustomScrollView.test.tsx | 337 +----------------- .../CustomScrollView/CustomScrollView.tsx | 104 +----- .../src/components/CustomScrollView/Readme.md | 79 +--- .../components/CustomScrollView/ScrollX.tsx | 54 --- .../components/CustomScrollView/ScrollY.tsx | 54 --- .../src/components/CustomScrollView/types.ts | 23 -- .../useCustomScrollViewResize.ts | 32 -- .../useDetectScrollDirection.ts | 21 -- .../CustomScrollView/useDragAndDrop.tsx | 55 --- .../useHorizontalScrollController.tsx | 122 ------- .../useTrackerVisibility.test.ts | 81 ----- .../CustomScrollView/useTrackerVisibility.ts | 126 ------- .../useVerticalScrollController.tsx | 124 ------- .../components/CustomSelect/CustomSelect.tsx | 11 +- .../CustomSelectDropdown.tsx | 13 +- .../vkui/src/components/Select/Select.tsx | 2 - 19 files changed, 54 insertions(+), 1392 deletions(-) delete mode 100644 packages/vkui/src/components/CustomScrollView/ScrollX.tsx delete mode 100644 packages/vkui/src/components/CustomScrollView/ScrollY.tsx delete mode 100644 packages/vkui/src/components/CustomScrollView/types.ts delete mode 100644 packages/vkui/src/components/CustomScrollView/useCustomScrollViewResize.ts delete mode 100644 packages/vkui/src/components/CustomScrollView/useDetectScrollDirection.ts delete mode 100644 packages/vkui/src/components/CustomScrollView/useDragAndDrop.tsx delete mode 100644 packages/vkui/src/components/CustomScrollView/useHorizontalScrollController.tsx delete mode 100644 packages/vkui/src/components/CustomScrollView/useTrackerVisibility.test.ts delete mode 100644 packages/vkui/src/components/CustomScrollView/useTrackerVisibility.ts delete mode 100644 packages/vkui/src/components/CustomScrollView/useVerticalScrollController.tsx diff --git a/packages/vkui/src/components/ChipsSelect/ChipsSelect.tsx b/packages/vkui/src/components/ChipsSelect/ChipsSelect.tsx index f7dc0fee2a..022f3a0c9a 100644 --- a/packages/vkui/src/components/ChipsSelect/ChipsSelect.tsx +++ b/packages/vkui/src/components/ChipsSelect/ChipsSelect.tsx @@ -74,10 +74,7 @@ export interface ChipsSelectProps extends ChipsInputBaseProps, UseChipsSelectProps, Pick, - Pick< - CustomSelectDropdownProps, - 'overscrollBehavior' | 'autoHideScrollbar' | 'autoHideScrollbarDelay' - > { + Pick { placement?: 'top' | 'bottom'; /** * Отрисовка Spinner вместо списка опций в выпадающем списке diff --git a/packages/vkui/src/components/CustomScrollView/CustomScrollView.e2e-playground.tsx b/packages/vkui/src/components/CustomScrollView/CustomScrollView.e2e-playground.tsx index 5ab2d5c94d..65c7dab213 100644 --- a/packages/vkui/src/components/CustomScrollView/CustomScrollView.e2e-playground.tsx +++ b/packages/vkui/src/components/CustomScrollView/CustomScrollView.e2e-playground.tsx @@ -7,14 +7,7 @@ import { CustomScrollView, type CustomScrollViewProps } from './CustomScrollView export const CustomScrollViewWithVerticalPlayground = (props: ComponentPlaygroundProps) => { return ( - + {(props: CustomScrollViewProps) => ( @@ -32,14 +25,7 @@ export const CustomScrollViewWithVerticalPlayground = (props: ComponentPlaygroun export const CustomScrollViewWithBothScrollsPlayground = (props: ComponentPlaygroundProps) => { return ( - + {(props: CustomScrollViewProps) => (
{ - const match = value.match(/translate\((.+),(.+)\)/); - if (!match) { - return [0, 0]; - } - const x = match[1]; - const y = match[2]; - return [parseFloat(x), parseFloat(y)]; -}; - -const checkSize = (value: string | number, size: number) => { - expect(Math.floor(typeof value === 'string' ? parseInt(value) : value)).toBe(size); -}; - -const checkTransformX = (value: string, x: number) => { - const [xValue] = parseTransform(value); - expect(Math.floor(xValue)).toBe(x); -}; - -const checkTransformY = (value: string, y: number) => { - const [, yValue] = parseTransform(value); - expect(Math.floor(yValue)).toBe(y); -}; - -const simulateDrag = ({ - element, - position = {}, - checkAfterDragStart = noop, - checkAfterDragEnd = noop, -}: { - element: HTMLElement; - position: { startY?: number; endY?: number; startX?: number; endX?: number }; - checkAfterDragStart: VoidFunction; - checkAfterDragEnd: VoidFunction; -}) => { - const { startY = 0, startX = 0, endY = 0, endX = 0 } = position; - fireEvent.mouseDown(element, { - clientY: startY, - clientX: startX, - }); - checkAfterDragStart(); - - fireEvent.mouseMove(document, { - clientY: endY, - clientX: endX, - }); - - fireEvent.mouseUp(document, { - clientY: endY, - clientX: endX, - }); - checkAfterDragEnd(); - - fireEvent.resize(window); -}; - -const setup = ({ - container, - clientHeight, - scrollWidth, - scrollHeight, - clientWidth, -}: { - container: HTMLElement; - clientHeight: number; - scrollHeight: number; - clientWidth: number; - scrollWidth: number; -}) => { - const box = container.getElementsByClassName(styles.box)[0] as HTMLElement; - - const barY = container.getElementsByClassName(styles.barY)[0] as HTMLElement; - const trackerY = container.getElementsByClassName(styles.trackerY)[0] as HTMLElement; - - const barX = container.getElementsByClassName(styles.barX)[0] as HTMLElement; - const trackerX = container.getElementsByClassName(styles.trackerX)[0] as HTMLElement; - - jest.spyOn(box, 'clientHeight', 'get').mockReturnValue(clientHeight); - jest.spyOn(box, 'scrollHeight', 'get').mockReturnValue(scrollHeight); - jest.spyOn(box, 'clientWidth', 'get').mockReturnValue(clientWidth); - jest.spyOn(box, 'scrollWidth', 'get').mockReturnValue(scrollWidth); - - // https://drafts.csswg.org/cssom-view/#dom-window-scroll - Object.defineProperty(box, 'scroll', { - value: (arg1: number | ScrollToOptions, arg2: number | undefined) => { - const scrollTo = (options: ScrollToOptions) => { - if (options.left) { - box.scrollLeft = normalizeNonFiniteScroll(options.left); - } - if (options.top) { - box.scrollTop = normalizeNonFiniteScroll(options.top); - } - }; - - if (typeof arg1 === 'number') { - scrollTo({ - left: arg1, - top: arg2, - }); - } else { - scrollTo(arg1); - } - }, - writable: false, - }); - - let trackerYHeight = ''; - jest - .spyOn(trackerY.style, 'height', 'set') - .mockImplementation((newHeight) => (trackerYHeight = newHeight)); - - let trackerXWidth = ''; - jest - .spyOn(trackerX.style, 'width', 'set') - .mockImplementation((newWidth) => (trackerXWidth = newWidth)); - - let trackerYDisplay = ''; - jest - .spyOn(barY.style, 'display', 'set') - .mockImplementation((newDisplay) => (trackerYDisplay = newDisplay)); - - let trackerXDisplay = ''; - jest - .spyOn(barX.style, 'display', 'set') - .mockImplementation((newDisplay) => (trackerXDisplay = newDisplay)); - - let trackerYTransform = ''; - jest - .spyOn(trackerY.style, 'transform', 'set') - .mockImplementation((newTransform) => (trackerYTransform = newTransform)); - - let trackerXTransform = ''; - jest - .spyOn(trackerX.style, 'transform', 'set') - .mockImplementation((newTransform) => (trackerXTransform = newTransform)); - - return { - box, - barY, - barX, - trackerX, - trackerY, - set scrollTop(newValue: number) { - box.scrollTop = newValue; - }, - get scrollTop() { - return box.scrollTop; - }, - get scrollLeft() { - return box.scrollLeft; - }, - set scrollLeft(newValue: number) { - box.scrollLeft = newValue; - }, - get trackerYHeight() { - return trackerYHeight; - }, - get trackerXWidth() { - return trackerXWidth; - }, - get trackerYDisplay() { - return trackerYDisplay; - }, - get trackerXDisplay() { - return trackerXDisplay; - }, - get trackerYTransform() { - return trackerYTransform; - }, - get trackerXTransform() { - return trackerXTransform; - }, - }; -}; - describe(CustomScrollView, () => { baselineComponent(CustomScrollView); - it('should have specific className with hasPointer = false', () => { - render( - - - content - - , - ); - expect(screen.getByTestId('scroll-view')).toHaveClass(styles.hasPointerFalse); - }); - it('should have overscroll specific className', () => { const getBoxElement = () => screen.getByTestId('scroll-view').firstElementChild as HTMLElement; @@ -234,141 +36,4 @@ describe(CustomScrollView, () => { expect(getBoxElement()).not.toHaveClass(styles.boxOverscrollBehaviorContain); expect(getBoxElement()).toHaveClass(styles.boxOverscrollBehaviorNone); }); - - it('bars should have display none when scroll doesnt need', () => { - const { container } = render( - - content - , - ); - const mockedData = setup({ - container, - clientHeight: 300, - scrollHeight: 300, - clientWidth: 900, - scrollWidth: 900, - }); - - // форсим перерисовку и пересчет размеров уже с замоканными значениями - fireEvent.resize(window); - - expect(mockedData.trackerXDisplay).toBe('none'); - expect(mockedData.trackerYDisplay).toBe('none'); - }); - - it('check scroll by dragging horizontal and vertical tracker', () => { - jest.useFakeTimers(); - const { container } = render( - - content - , - ); - const mockedData = setup({ - container, - clientHeight: 300, - scrollHeight: 480, - clientWidth: 993, - scrollWidth: 1464, - }); - - // форсим перерисовку и пересчет размеров уже с замоканными значениями - fireEvent.resize(window); - - checkSize(mockedData.trackerYHeight, 187); - checkSize(mockedData.trackerXWidth, 673); - expect(mockedData.trackerXDisplay).toBe(''); - expect(mockedData.trackerYDisplay).toBe(''); - expect(mockedData.trackerY).toHaveClass(styles.trackerYHidden); - expect(mockedData.trackerX).toHaveClass(styles.trackerXHidden); - - checkTransformX(mockedData.trackerXTransform, 0); - checkTransformY(mockedData.trackerYTransform, 0); - - simulateDrag({ - element: mockedData.trackerY, - position: { endY: 100 }, - checkAfterDragStart: () => { - expect(mockedData.trackerY).not.toHaveClass(styles.trackerYHidden); - }, - checkAfterDragEnd: () => { - React.act(jest.runAllTimers); - expect(mockedData.trackerY).toHaveClass(styles.trackerYHidden); - }, - }); - - checkSize(mockedData.scrollTop, 160); - checkTransformY(mockedData.trackerYTransform, 100); - - simulateDrag({ - element: mockedData.trackerX, - position: { endX: 100 }, - checkAfterDragStart: () => expect(mockedData.trackerX).not.toHaveClass(styles.trackerXHidden), - checkAfterDragEnd: () => { - React.act(jest.runAllTimers); - expect(mockedData.trackerX).toHaveClass(styles.trackerXHidden); - }, - }); - - checkSize(mockedData.scrollLeft, 147); - checkTransformX(mockedData.trackerXTransform, 100); - }); - - it('check scroll by scroll event', () => { - const onScroll = jest.fn(); - const { container } = render( - - content - , - ); - const mockedData = setup({ - container, - clientHeight: 300, - scrollHeight: 480, - clientWidth: 993, - scrollWidth: 1464, - }); - - // форсим перерисовку и пересчет размеров уже с замоканными значениями - fireEvent.resize(window); - - checkSize(mockedData.trackerYHeight, 187); - checkSize(mockedData.trackerXWidth, 673); - expect(mockedData.trackerXDisplay).toBe(''); - expect(mockedData.trackerYDisplay).toBe(''); - expect(mockedData.trackerY).toHaveClass(styles.trackerYHidden); - expect(mockedData.trackerX).toHaveClass(styles.trackerXHidden); - - checkTransformX(mockedData.trackerXTransform, 0); - checkTransformY(mockedData.trackerYTransform, 0); - - mockedData.scrollTop = 100; - fireEvent.scroll(mockedData.box); - - checkSize(mockedData.scrollTop, 100); - checkTransformY(mockedData.trackerYTransform, 62); - expect(onScroll).toHaveBeenCalledTimes(1); - - mockedData.scrollLeft = 100; - fireEvent.scroll(mockedData.box); - - checkSize(mockedData.scrollLeft, 100); - checkTransformX(mockedData.trackerXTransform, 67); - expect(onScroll).toHaveBeenCalledTimes(2); - }); }); diff --git a/packages/vkui/src/components/CustomScrollView/CustomScrollView.tsx b/packages/vkui/src/components/CustomScrollView/CustomScrollView.tsx index deb7399e19..9fa9cbc21a 100644 --- a/packages/vkui/src/components/CustomScrollView/CustomScrollView.tsx +++ b/packages/vkui/src/components/CustomScrollView/CustomScrollView.tsx @@ -1,28 +1,8 @@ import * as React from 'react'; import { classNames } from '@vkontakte/vkjs'; -import { useAdaptivity } from '../../hooks/useAdaptivity'; -import { useExternRef } from '../../hooks/useExternRef'; import type { HasRootRef } from '../../types'; -import { ScrollX } from './ScrollX'; -import { ScrollY } from './ScrollY'; -import { type BarHandlers } from './types'; -import { useCustomScrollViewResize } from './useCustomScrollViewResize'; -import { useDetectScrollDirection } from './useDetectScrollDirection'; -import { type TrackerOptionsProps } from './useTrackerVisibility'; import styles from './CustomScrollView.module.css'; -function hasPointerClassName(hasPointer: boolean | undefined) { - switch (hasPointer) { - case true: - return styles.hasPointerTrue; - case false: - return styles.hasPointerFalse; - case undefined: - default: - return styles.hasPointerNone; - } -} - const overscrollBehaviorClassNames = { auto: undefined, contain: styles.boxOverscrollBehaviorContain, @@ -31,10 +11,7 @@ const overscrollBehaviorClassNames = { export interface CustomScrollViewProps extends React.AllHTMLAttributes, - HasRootRef, - TrackerOptionsProps { - windowResize?: boolean; - boxRef?: React.Ref; + HasRootRef { className?: HTMLDivElement['className']; onScroll?: (event: React.UIEvent) => void; children: React.ReactNode; @@ -43,9 +20,7 @@ export interface CustomScrollViewProps */ overscrollBehavior?: 'auto' | 'contain' | 'none'; /** - * Включение замены горизонтального скролла - * - * > ⚠️ Важно: На версиях Firefox ниже 64 могут возникнуть проблемы при использовании этого флага, будьте осторожны + * Включение отображения горизонтального скролла */ enableHorizontalScroll?: boolean; } @@ -56,82 +31,25 @@ export interface CustomScrollViewProps export const CustomScrollView = ({ className, children, - boxRef: externalBoxRef, - windowResize, - autoHideScrollbar = false, - autoHideScrollbarDelay, enableHorizontalScroll = false, - onScroll: onScrollProp, + onScroll, getRootRef, overscrollBehavior = 'auto', ...restProps }: CustomScrollViewProps): React.ReactNode => { - const { hasPointer } = useAdaptivity(); - - const boxRef = useExternRef(externalBoxRef); - const boxContentRef = React.useRef(null); - - const detectScrollDirection = useDetectScrollDirection(); - - const barYHandlers = React.useRef(null); - const barXHandlers = React.useRef(null); - - useCustomScrollViewResize({ - windowResize, - boxContentRef, - onResize: () => { - barYHandlers.current?.resize(); - barXHandlers.current?.resize(); - }, - }); - - const onScroll = (event: React.UIEvent) => { - const scrollDirection = detectScrollDirection(event); - switch (scrollDirection) { - case 'horizontal': - barXHandlers.current?.scroll(); - break; - case 'vertical': - barYHandlers.current?.scroll(); - break; - } - onScrollProp?.(event); - }; - return (
-
-
- {children} -
-
- - {enableHorizontalScroll && ( - - )} + {children}
); }; diff --git a/packages/vkui/src/components/CustomScrollView/Readme.md b/packages/vkui/src/components/CustomScrollView/Readme.md index 1fc85ae983..fe954a08d3 100644 --- a/packages/vkui/src/components/CustomScrollView/Readme.md +++ b/packages/vkui/src/components/CustomScrollView/Readme.md @@ -1,10 +1,9 @@ -Компонент, заменяющий браузерную полосу прокрутки на кастомную +Компонент, который кастомизирует браузерную полосу прокрутки ```jsx const WithVerticalScroll = () => { return ( { const WithHorizontalScroll = () => { const [recentFriends] = useState(getRandomUsers(20)); return ( - +
{ ); }; -const WithBothScrollAndAutoHide = () => { - return ( - -
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed a sollicitudin lectus, a - commodo sapien. Vivamus a urna leo. Integer iaculis dignissim urna, sit amet vestibulum diam - bibendum a. Donec eu arcu ut augue porttitor faucibus. Vestibulum nec pretium tortor, sit - amet congue nunc. Aenean ullamcorper ex sem, sed interdum quam consequat et. Vestibulum a ex - non diam fringilla feugiat. Nunc eu tellus sed leo elementum cursus. Mauris blandit porta - egestas. Curabitur eget justo elementum, malesuada lacus ut, congue mauris. Integer orci - nisi, convallis vitae dapibus sit amet, molestie a risus. Aenean ultricies lacus eros, sit - amet condimentum urna malesuada et. Sed quis dolor tempus orci fringilla volutpat in sed - velit. Aenean aliquet bibendum pretium. -
-
- Cras pulvinar lobortis purus. Donec placerat suscipit leo vitae sodales. Phasellus convallis - lorem vitae arcu finibus pellentesque. In imperdiet vel leo a euismod. Nam sed odio a neque - venenatis suscipit a placerat magna. Mauris magna nisl, consequat nec augue vitae, ultricies - scelerisque ante. Phasellus pharetra risus eget imperdiet sodales. Integer dignissim auctor - semper. Nulla odio odio, euismod ut interdum in, bibendum sed massa. Proin rutrum molestie - massa in ultrices. Donec eu euismod turpis, eget lobortis lorem. Nulla facilisi. Nam lacinia - posuere turpis, sed laoreet turpis auctor nec. -
-
- Curabitur eu fermentum mauris. Phasellus malesuada consectetur mollis. Pellentesque pulvinar - mauris turpis. Integer neque dolor, semper quis neque et, gravida commodo eros. Duis - efficitur ex a turpis blandit tincidunt. Mauris sem mi, imperdiet quis ligula sit amet, - fermentum vulputate felis. Phasellus eu ullamcorper dolor, porttitor pulvinar diam. Aliquam - euismod, mauris nec varius lacinia, ligula libero vulputate leo, ut tristique massa nisi - vitae tortor. Phasellus purus elit, gravida sit amet neque id, aliquam rutrum dui. Maecenas - luctus sem vitae molestie porttitor. Cras viverra mauris risus, at sollicitudin ipsum - interdum eu. Sed sit amet tempor enim. -
-
- In hac habitasse platea dictumst. Etiam luctus erat metus, quis efficitur quam vulputate - quis. Duis ultricies non mauris condimentum molestie. Maecenas sollicitudin ex sem, quis - ultrices libero blandit eu. Vivamus in turpis pulvinar, malesuada enim at, hendrerit magna. - Proin eu nulla eget arcu pretium pharetra. Sed ullamcorper pulvinar est eu dapibus. Cras at - varius justo. In ex odio, condimentum id pellentesque a, sodales ut diam. -
-
- Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nam - aliquet tempor laoreet. Maecenas eu pulvinar diam. Pellentesque habitant morbi tristique - senectus et netus et malesuada fames ac turpis egestas. Maecenas et elit eros. Quisque - ullamcorper sodales nisi, eleifend aliquet metus venenatis in. Aliquam ornare a lacus in - tincidunt. Cras vel tristique metus. Sed vitae nisl at nisl imperdiet sollicitudin. Sed sit - amet enim in lectus imperdiet interdum condimentum et diam. Proin venenatis sit amet diam ac - vulputate. Donec mauris orci, semper volutpat nunc ut, efficitur condimentum dolor. Vivamus - in quam eget quam lacinia pharetra. Phasellus ipsum magna, aliquet id elit eget, cursus - tincidunt ex. In rhoncus turpis turpis, et viverra ex malesuada vel. Donec nisi tellus, - mollis et posuere vel, dictum eget neque. -
-
- ); -}; - const Example = () => { return ( @@ -119,15 +53,6 @@ const Example = () => { Горизонтальный скролл}> - - Вертикальный и горизонтальный скролл с автоматическим скрытием скроллбара - - } - > - - ); diff --git a/packages/vkui/src/components/CustomScrollView/ScrollX.tsx b/packages/vkui/src/components/CustomScrollView/ScrollX.tsx deleted file mode 100644 index b229a8c351..0000000000 --- a/packages/vkui/src/components/CustomScrollView/ScrollX.tsx +++ /dev/null @@ -1,54 +0,0 @@ -import * as React from 'react'; -import { classNames } from '@vkontakte/vkjs'; -import { stopPropagation } from '../../lib/utils'; -import type { ScrollProps } from './types'; -import { useDragAndDrop } from './useDragAndDrop'; -import { useHorizontalScrollController } from './useHorizontalScrollController'; -import styles from './CustomScrollView.module.css'; - -export const ScrollX = ({ - barHandlers, - boxRef, - autoHideScrollbar, - autoHideScrollbarDelay, -}: ScrollProps) => { - const { - barRef: barX, - trackerVisible: horizontalTrackerVisible, - trackerRef: trackerX, - resize: horizontalScrollResize, - scroll: horizontalScroll, - dragStart: onHorizontalDragStart, - dragging: onHorizontalDragging, - dragEnd: onHorizontalDragEnd, - trackerMouseEnter: onHorizontalTrackerMouseEnter, - trackerMouseLeave: onHorizontalTrackerMouseLeave, - } = useHorizontalScrollController(boxRef, autoHideScrollbar, autoHideScrollbarDelay); - - const { onDragStart: onMouseDown } = useDragAndDrop( - onHorizontalDragStart, - onHorizontalDragging, - onHorizontalDragEnd, - ); - - React.useImperativeHandle( - barHandlers, - () => ({ - resize: horizontalScrollResize, - scroll: horizontalScroll, - }), - [horizontalScrollResize, horizontalScroll], - ); - - return ( -
-
-
- ); -}; diff --git a/packages/vkui/src/components/CustomScrollView/ScrollY.tsx b/packages/vkui/src/components/CustomScrollView/ScrollY.tsx deleted file mode 100644 index e78e0be8bb..0000000000 --- a/packages/vkui/src/components/CustomScrollView/ScrollY.tsx +++ /dev/null @@ -1,54 +0,0 @@ -import * as React from 'react'; -import { classNames } from '@vkontakte/vkjs'; -import { stopPropagation } from '../../lib/utils'; -import type { ScrollProps } from './types'; -import { useDragAndDrop } from './useDragAndDrop'; -import { useVerticalScrollController } from './useVerticalScrollController'; -import styles from './CustomScrollView.module.css'; - -export const ScrollY = ({ - barHandlers, - boxRef, - autoHideScrollbar, - autoHideScrollbarDelay, -}: ScrollProps) => { - const { - barRef: barY, - trackerVisible: verticalTrackerVisible, - trackerRef: trackerY, - resize: verticalScrollResize, - scroll: verticalScroll, - dragStart: onVerticalDragStart, - dragging: onVerticalDragging, - dragEnd: onVerticalDragEnd, - trackerMouseEnter: onVerticalTrackerMouseEnter, - trackerMouseLeave: onVerticalTrackerMouseLeave, - } = useVerticalScrollController(boxRef, autoHideScrollbar, autoHideScrollbarDelay); - - const { onDragStart: onMouseDown } = useDragAndDrop( - onVerticalDragStart, - onVerticalDragging, - onVerticalDragEnd, - ); - - React.useImperativeHandle( - barHandlers, - () => ({ - resize: verticalScrollResize, - scroll: verticalScroll, - }), - [verticalScrollResize, verticalScroll], - ); - - return ( -
-
-
- ); -}; diff --git a/packages/vkui/src/components/CustomScrollView/types.ts b/packages/vkui/src/components/CustomScrollView/types.ts deleted file mode 100644 index ea4565ba8f..0000000000 --- a/packages/vkui/src/components/CustomScrollView/types.ts +++ /dev/null @@ -1,23 +0,0 @@ -import type * as React from 'react'; - -export type CustomScrollBarController = { - barRef: React.RefObject; - trackerRef: React.RefObject; - trackerVisible: boolean; - resize: () => void; - dragging: (e: React.MouseEvent) => void; - dragEnd: () => void; - scroll: () => void; - dragStart: (e: React.MouseEvent) => void; - trackerMouseEnter: () => void; - trackerMouseLeave: () => void; -}; - -export type BarHandlers = Pick; - -export type ScrollProps = { - barHandlers: React.MutableRefObject; - boxRef: React.MutableRefObject; - autoHideScrollbar: boolean; - autoHideScrollbarDelay?: number; -}; diff --git a/packages/vkui/src/components/CustomScrollView/useCustomScrollViewResize.ts b/packages/vkui/src/components/CustomScrollView/useCustomScrollViewResize.ts deleted file mode 100644 index 77140a09bd..0000000000 --- a/packages/vkui/src/components/CustomScrollView/useCustomScrollViewResize.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { useEventListener } from '../../hooks/useEventListener'; -import { useResizeObserver } from '../../hooks/useResizeObserver'; -import { useStableCallback } from '../../hooks/useStableCallback'; -import { useDOM } from '../../lib/dom'; -import { useIsomorphicLayoutEffect } from '../../lib/useIsomorphicLayoutEffect'; - -interface UseCustomScrollViewResizeProps { - windowResize?: boolean; - onResize: () => void; - boxContentRef: React.RefObject; -} - -export const useCustomScrollViewResize = ({ - windowResize, - onResize, - boxContentRef, -}: UseCustomScrollViewResizeProps) => { - const { window } = useDOM(); - const resizeCb = useStableCallback(onResize); - - const resizeHandler = useEventListener('resize', resizeCb); - - useIsomorphicLayoutEffect(() => { - if (windowResize && window) { - resizeHandler.add(window); - } - }, [windowResize, window]); - - useResizeObserver(boxContentRef, resizeCb); - - useIsomorphicLayoutEffect(resizeCb, []); -}; diff --git a/packages/vkui/src/components/CustomScrollView/useDetectScrollDirection.ts b/packages/vkui/src/components/CustomScrollView/useDetectScrollDirection.ts deleted file mode 100644 index 6db58a6abe..0000000000 --- a/packages/vkui/src/components/CustomScrollView/useDetectScrollDirection.ts +++ /dev/null @@ -1,21 +0,0 @@ -import * as React from 'react'; - -/** - * Хук определяет в каком измерении происходит скролл(в горизонтальном или вертикальном) - */ -export const useDetectScrollDirection = () => { - const lastScrollLeft = React.useRef(0); - const lastScrollTop = React.useRef(0); - - return React.useCallback((event: React.UIEvent) => { - const { scrollTop, scrollLeft } = event.currentTarget; - if (scrollTop !== lastScrollTop.current) { - lastScrollTop.current = scrollTop; - return 'vertical'; - } else if (scrollLeft !== lastScrollLeft.current) { - lastScrollLeft.current = scrollLeft; - return 'horizontal'; - } - return null; - }, []); -}; diff --git a/packages/vkui/src/components/CustomScrollView/useDragAndDrop.tsx b/packages/vkui/src/components/CustomScrollView/useDragAndDrop.tsx deleted file mode 100644 index b2b1d650f7..0000000000 --- a/packages/vkui/src/components/CustomScrollView/useDragAndDrop.tsx +++ /dev/null @@ -1,55 +0,0 @@ -import * as React from 'react'; -import { useEventListener } from '../../hooks/useEventListener'; -import { useDOM } from '../../lib/dom'; - -export const useDragAndDrop = ( - onDragStart: (e: React.MouseEvent) => void, - onDragMove: (e: React.MouseEvent) => void, - onDragEnd: (e: React.MouseEvent) => void, -) => { - const { document } = useDOM(); - const [isPressed, setIsPressed] = React.useState(false); - - const onDragEndImpl = (e: React.MouseEvent) => { - if (!isPressed) { - return; - } - e.preventDefault(); - onDragEnd(e); - unsubscribe(); - }; - - const onDragMoveImpl = (e: React.MouseEvent) => { - if (!isPressed) { - return; - } - e.preventDefault(); - onDragMove(e); - }; - - const listeners = [ - // @ts-expect-error: TS2769 ругается на тип event - useEventListener('mousemove', onDragMoveImpl), - // @ts-expect-error: TS2769 ругается на тип event - useEventListener('mouseup', onDragEndImpl), - ]; - - function subscribe(el: Document | undefined) { - if (el) { - listeners.forEach((l) => l.add(el)); - } - } - - function unsubscribe() { - listeners.forEach((l) => l.remove()); - } - - return { - onDragStart: (e: React.MouseEvent) => { - e.preventDefault(); - setIsPressed(true); - onDragStart(e); - subscribe(document); - }, - }; -}; diff --git a/packages/vkui/src/components/CustomScrollView/useHorizontalScrollController.tsx b/packages/vkui/src/components/CustomScrollView/useHorizontalScrollController.tsx deleted file mode 100644 index d5d3e87ee6..0000000000 --- a/packages/vkui/src/components/CustomScrollView/useHorizontalScrollController.tsx +++ /dev/null @@ -1,122 +0,0 @@ -import * as React from 'react'; -import type { CustomScrollBarController } from './types'; -import { useTrackerVisibility } from './useTrackerVisibility'; - -export const useHorizontalScrollController = ( - boxRef: React.RefObject, - autoHideScrollbar: boolean, - autoHideScrollbarDelay?: number, -): CustomScrollBarController => { - const barX = React.useRef(null); - - const horizontalRatio = React.useRef(NaN); - const lastTrackerLeft = React.useRef(0); - const clientWidth = React.useRef(0); - const trackerWidth = React.useRef(0); - const scrollWidth = React.useRef(0); - const startX = React.useRef(0); - const trackerLeft = React.useRef(0); - - const trackerX = React.useRef(null); - - const { - trackerVisible, - onTargetScroll, - onTrackerDragStart, - onTrackerDragStop, - onTrackerMouseEnter, - onTrackerMouseLeave, - } = useTrackerVisibility(autoHideScrollbar, autoHideScrollbarDelay); - - const setHorizontalTrackerPosition = (scrollLeft: number) => { - lastTrackerLeft.current = scrollLeft; - if (trackerX.current !== null) { - trackerX.current.style.transform = `translate(${scrollLeft}px, 0)`; - } - }; - - const setTrackerPositionFromScroll = (scrollLeft: number) => { - const progress = scrollLeft / (scrollWidth.current - clientWidth.current); - setHorizontalTrackerPosition((clientWidth.current - trackerWidth.current) * progress); - }; - - const resize = () => { - if (!boxRef.current || !barX.current || !trackerX.current) { - return; - } - const localClientWidth = boxRef.current.clientWidth; - const localScrollWidth = boxRef.current.scrollWidth; - const localVerticalRatio = localClientWidth / localScrollWidth; - const localTrackerWidth = Math.max(localClientWidth * localVerticalRatio, 40); - - horizontalRatio.current = localVerticalRatio; - clientWidth.current = localClientWidth; - scrollWidth.current = localScrollWidth; - trackerWidth.current = localTrackerWidth; - const currentScrollLeft = boxRef.current.scrollLeft; - - if (localVerticalRatio >= 1) { - barX.current.style.display = 'none'; - } else { - barX.current.style.display = ''; - trackerX.current.style.width = `${localTrackerWidth}px`; - setTrackerPositionFromScroll(currentScrollLeft); - } - }; - - const setScrollPositionFromTracker = (trackerLeft: number) => { - const progress = trackerLeft / (clientWidth.current - trackerWidth.current); - if (boxRef.current !== null) { - boxRef.current.scroll({ - left: (scrollWidth.current - clientWidth.current) * progress, - }); - } - }; - - const dragging = (e: React.MouseEvent) => { - const diff = e.clientX - startX.current; - const position = Math.min( - Math.max(trackerLeft.current + diff, 0), - clientWidth.current - trackerWidth.current, - ); - setScrollPositionFromTracker(position); - }; - - const dragEnd = () => { - if (autoHideScrollbar) { - onTrackerDragStop(); - } - }; - - const scroll = () => { - if (!boxRef.current) { - return; - } - if (autoHideScrollbar) { - onTargetScroll(); - } - setTrackerPositionFromScroll(boxRef.current.scrollLeft); - }; - - const dragStart = (e: React.MouseEvent) => { - startX.current = e.clientX; - trackerLeft.current = lastTrackerLeft.current; - - if (autoHideScrollbar) { - onTrackerDragStart(); - } - }; - - return { - barRef: barX, - trackerVisible, - trackerRef: trackerX, - resize, - dragging, - dragEnd, - scroll, - dragStart, - trackerMouseEnter: onTrackerMouseEnter, - trackerMouseLeave: onTrackerMouseLeave, - }; -}; diff --git a/packages/vkui/src/components/CustomScrollView/useTrackerVisibility.test.ts b/packages/vkui/src/components/CustomScrollView/useTrackerVisibility.test.ts deleted file mode 100644 index 85d059d239..0000000000 --- a/packages/vkui/src/components/CustomScrollView/useTrackerVisibility.test.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { act } from 'react'; -import { renderHook } from '@testing-library/react'; -import { fakeTimers } from '../../testing/utils'; -import { useTrackerVisibility } from './useTrackerVisibility'; - -describe(useTrackerVisibility, () => { - fakeTimers(); - - describe('autoHideScrollbar', () => { - it.each([true, false])('%s', (autoHideScrollbar) => { - const { result } = renderHook(() => useTrackerVisibility(autoHideScrollbar)); - expect(result.current.trackerVisible).toBe(!autoHideScrollbar); - }); - }); - - describe('drag events', () => { - it('should change visibility by drag events', () => { - const { result } = renderHook(() => useTrackerVisibility()); - - act(result.current.onTrackerDragStart); - expect(result.current.trackerVisible).toBeTruthy(); - - act(result.current.onTrackerDragStop); - act(jest.runOnlyPendingTimers); - expect(result.current.trackerVisible).toBeFalsy(); - }); - - it('should prevent hide onTrackerDragStop if mouse is over', () => { - const { result } = renderHook(() => useTrackerVisibility()); - - act(result.current.onTrackerDragStart); - expect(result.current.trackerVisible).toBeTruthy(); - - act(result.current.onTrackerMouseEnter); - - act(result.current.onTrackerDragStop); - act(jest.runOnlyPendingTimers); - expect(result.current.trackerVisible).toBeTruthy(); - }); - }); - - describe('mouse events', () => { - it('should change visibility by mouse events', () => { - const { result } = renderHook(() => useTrackerVisibility()); - act(result.current.onTrackerMouseEnter); - expect(result.current.trackerVisible).toBeTruthy(); - - act(result.current.onTrackerMouseLeave); - act(jest.runOnlyPendingTimers); - expect(result.current.trackerVisible).toBeFalsy(); - }); - }); - - describe('scroll event', () => { - it('should change visibility by scroll event', () => { - const { result } = renderHook(() => useTrackerVisibility()); - - act(result.current.onTargetScroll); - act(jest.runOnlyPendingTimers); - expect(result.current.trackerVisible).toBeFalsy(); - }); - - it('should prevent hide after onTargetScroll if mouse is over', () => { - const { result } = renderHook(() => useTrackerVisibility()); - - act(result.current.onTrackerDragStart); - act(result.current.onTargetScroll); - act(jest.runOnlyPendingTimers); - expect(result.current.trackerVisible).toBeTruthy(); - - act(result.current.onTrackerDragStop); - act(jest.runOnlyPendingTimers); - expect(result.current.trackerVisible).toBeFalsy(); - - act(result.current.onTargetScroll); - act(result.current.onTrackerDragStart); - act(jest.runOnlyPendingTimers); - expect(result.current.trackerVisible).toBeTruthy(); - }); - }); -}); diff --git a/packages/vkui/src/components/CustomScrollView/useTrackerVisibility.ts b/packages/vkui/src/components/CustomScrollView/useTrackerVisibility.ts deleted file mode 100644 index 9579ae3036..0000000000 --- a/packages/vkui/src/components/CustomScrollView/useTrackerVisibility.ts +++ /dev/null @@ -1,126 +0,0 @@ -import * as React from 'react'; -import type { TimeoutId } from '../../types'; - -/** - * 'temporary-visible' – "планирует" скрытие ползунка через N миллисекунд. Если тайм-аут не успеет - * сработать, то каждый последующий вызов функции будет откладывать скрытие ползунка. - */ -type VisibilityState = 'visible' | 'hidden' | 'temporary-visible'; - -/** - * Хук, который позволяет управлять видимостью ползунка скроллбара. - * @param autoHideScrollbar - скрывать ли ползунок скроллбара - * @param autoHideScrollbarDelay - через какое кол-во миллисекунд ползунок скроллбара скрывается - * @returns Объект, содержащий параметры, которые позволяют управлять видимостью ползунка - */ -export const useTrackerVisibility = ( - autoHideScrollbar = false, - autoHideScrollbarDelay = 500, -): TrackerVisibilityProps => { - const [visibility, setVisibility] = React.useState( - autoHideScrollbar ? 'hidden' : 'visible', - ); - const isMouseOver = React.useRef(false); - const isTrackerDragging = React.useRef(false); - - React.useEffect(() => { - setVisibility(autoHideScrollbar ? 'hidden' : 'visible'); - }, [autoHideScrollbar]); - - const onTrackerDragStart = React.useCallback(() => { - isTrackerDragging.current = true; - setVisibility('visible'); - }, []); - - const onTrackerDragStop = React.useCallback(() => { - isTrackerDragging.current = false; - if (!isMouseOver.current) { - setVisibility('temporary-visible'); - } - }, []); - - const onTrackerMouseEnter = React.useCallback(() => { - isMouseOver.current = true; - setVisibility('visible'); - }, []); - - const onTrackerMouseLeave = React.useCallback(() => { - isMouseOver.current = false; - if (!isTrackerDragging.current) { - setVisibility('temporary-visible'); - } - }, []); - - const onTargetScroll = React.useCallback(() => { - if (isMouseOver.current || isTrackerDragging.current) { - return; - } - setVisibility('temporary-visible'); - }, []); - - React.useEffect( - function hideAfterDelay() { - let timeoutId: TimeoutId = null; - - if (visibility === 'temporary-visible') { - timeoutId = setTimeout(() => { - setVisibility('hidden'); - }, autoHideScrollbarDelay); - } - - return function clearHideAfterDelay() { - if (timeoutId) { - clearTimeout(timeoutId); - } - }; - }, - [visibility, autoHideScrollbarDelay], - ); - - return { - trackerVisible: visibility !== 'hidden', - onTrackerDragStart, - onTrackerDragStop, - onTrackerMouseEnter, - onTrackerMouseLeave, - onTargetScroll, - }; -}; - -export interface TrackerOptionsProps { - /** - * Скрывать ли ползунок скроллбара - */ - autoHideScrollbar?: boolean; - /** - * Через какое кол-во миллисекунд ползунок скроллбара скрывается - */ - autoHideScrollbarDelay?: number; -} - -export interface TrackerVisibilityProps { - /** - * Отвечает за видимость ползунка - */ - trackerVisible: boolean; - /** - * Функция для обработки события у блока со скроллом - */ - onTargetScroll: (this: void) => void; - /** - * Функция для обработки начала drag event ползунка - */ - onTrackerDragStart: (this: void) => void; - /** - * Функция для обработки окончания drag event ползунка - */ - onTrackerDragStop: (this: void) => void; - /** - * Функция для обработки mouseLeave event ползунка - */ - onTrackerMouseEnter: (this: void) => void; - /** - * Функция для обработки mouseEnter event ползунка - */ - onTrackerMouseLeave: (this: void) => void; -} diff --git a/packages/vkui/src/components/CustomScrollView/useVerticalScrollController.tsx b/packages/vkui/src/components/CustomScrollView/useVerticalScrollController.tsx deleted file mode 100644 index 319a8e94d2..0000000000 --- a/packages/vkui/src/components/CustomScrollView/useVerticalScrollController.tsx +++ /dev/null @@ -1,124 +0,0 @@ -import * as React from 'react'; -import type { CustomScrollBarController } from './types'; -import { useTrackerVisibility } from './useTrackerVisibility'; - -export const useVerticalScrollController = ( - boxRef: React.RefObject, - autoHideScrollbar: boolean, - autoHideScrollbarDelay?: number, -): CustomScrollBarController => { - const barY = React.useRef(null); - - const verticalRatio = React.useRef(NaN); - const lastTrackerTop = React.useRef(0); - const clientHeight = React.useRef(0); - const trackerHeight = React.useRef(0); - const scrollHeight = React.useRef(0); - const startY = React.useRef(0); - const trackerTop = React.useRef(0); - - const trackerY = React.useRef(null); - - const { - trackerVisible, - onTargetScroll, - onTrackerDragStart, - onTrackerDragStop, - onTrackerMouseEnter, - onTrackerMouseLeave, - } = useTrackerVisibility(autoHideScrollbar, autoHideScrollbarDelay); - - const setVerticalTrackerPosition = (scrollTop: number) => { - lastTrackerTop.current = scrollTop; - if (trackerY.current !== null) { - trackerY.current.style.transform = `translate(0, ${scrollTop}px)`; - } - }; - - const setTrackerPositionFromScroll = (scrollTop: number) => { - const progress = scrollTop / (scrollHeight.current - clientHeight.current); - setVerticalTrackerPosition((clientHeight.current - trackerHeight.current) * progress); - }; - - const resize = () => { - if (!boxRef.current || !barY.current || !trackerY.current) { - return; - } - const localClientHeight = boxRef.current.clientHeight; - const localScrollHeight = boxRef.current.scrollHeight; - const localVerticalRatio = localClientHeight / localScrollHeight; - const localTrackerHeight = Math.max(localClientHeight * localVerticalRatio, 40); - - verticalRatio.current = localVerticalRatio; - clientHeight.current = localClientHeight; - scrollHeight.current = localScrollHeight; - trackerHeight.current = localTrackerHeight; - - const currentScrollTop = boxRef.current.scrollTop; - - if (localVerticalRatio >= 1) { - barY.current.style.display = 'none'; - } else { - barY.current.style.display = ''; - trackerY.current.style.height = `${localTrackerHeight}px`; - setTrackerPositionFromScroll(currentScrollTop); - } - }; - - const setScrollPositionFromTracker = (trackerTop: number) => { - const progress = trackerTop / (clientHeight.current - trackerHeight.current); - if (boxRef.current !== null) { - boxRef.current.scroll({ - top: (scrollHeight.current - clientHeight.current) * progress, - }); - } - }; - - const dragging = (e: React.MouseEvent) => { - const diff = e.clientY - startY.current; - const position = Math.min( - Math.max(trackerTop.current + diff, 0), - clientHeight.current - trackerHeight.current, - ); - - setScrollPositionFromTracker(position); - }; - - const dragEnd = () => { - if (autoHideScrollbar) { - onTrackerDragStop(); - } - }; - - const scroll = () => { - if (!boxRef.current) { - return; - } - if (autoHideScrollbar) { - onTargetScroll(); - } - setTrackerPositionFromScroll(boxRef.current.scrollTop); - }; - - const dragStart = (e: React.MouseEvent) => { - startY.current = e.clientY; - trackerTop.current = lastTrackerTop.current; - - if (autoHideScrollbar) { - onTrackerDragStart(); - } - }; - - return { - barRef: barY, - trackerVisible, - trackerRef: trackerY, - resize, - dragging, - dragEnd, - scroll, - dragStart, - trackerMouseEnter: onTrackerMouseEnter, - trackerMouseLeave: onTrackerMouseLeave, - }; -}; diff --git a/packages/vkui/src/components/CustomSelect/CustomSelect.tsx b/packages/vkui/src/components/CustomSelect/CustomSelect.tsx index 7e31225feb..c6087cfc2f 100644 --- a/packages/vkui/src/components/CustomSelect/CustomSelect.tsx +++ b/packages/vkui/src/components/CustomSelect/CustomSelect.tsx @@ -8,7 +8,6 @@ import type { Placement } from '../../lib/floating'; import { defaultFilterFn, type FilterFn } from '../../lib/select'; import { useIsomorphicLayoutEffect } from '../../lib/useIsomorphicLayoutEffect'; import { warnOnce } from '../../lib/warnOnce'; -import type { TrackerOptionsProps } from '../CustomScrollView/useTrackerVisibility'; import { CustomSelectDropdown, type CustomSelectDropdownProps, @@ -129,11 +128,7 @@ export interface SelectProps< OptionInterfaceT extends CustomSelectOptionInterface = CustomSelectOptionInterface, > extends NativeSelectProps, Omit, - TrackerOptionsProps, - Pick< - CustomSelectDropdownProps, - 'overscrollBehavior' | 'autoHideScrollbar' | 'autoHideScrollbarDelay' - >, + Pick, Pick { /** * ref на внутрений компонент input @@ -247,8 +242,6 @@ export function CustomSelect, - Pick< - CustomScrollViewProps, - 'overscrollBehavior' | 'autoHideScrollbar' | 'autoHideScrollbarDelay' - >, - TrackerOptionsProps, + Pick, HasDataAttribute { targetRef: React.RefObject; placement?: Placement; @@ -42,8 +37,6 @@ export const CustomSelectDropdown = ({ offsetDistance = 0, autoWidth = false, forcePortal = true, - autoHideScrollbar, - autoHideScrollbarDelay, className, noMaxHeight = false, // CustomScrollView @@ -68,10 +61,8 @@ export const CustomSelectDropdown = ({ {...restProps} > {fetching ? ( diff --git a/packages/vkui/src/components/Select/Select.tsx b/packages/vkui/src/components/Select/Select.tsx index 3f2bb617b1..4facb24da7 100644 --- a/packages/vkui/src/components/Select/Select.tsx +++ b/packages/vkui/src/components/Select/Select.tsx @@ -38,8 +38,6 @@ export const Select = ({ dropdownAutoWidth, forceDropdownPortal, noMaxHeight, - autoHideScrollbar, - autoHideScrollbarDelay, labelTextTestId, nativeSelectTestId, after, From 6ce952ca56213ff2681c5eaff609e6eff6325605 Mon Sep 17 00:00:00 2001 From: "e.muhamethanov" Date: Thu, 3 Oct 2024 17:16:59 +0300 Subject: [PATCH 2/8] test(CustomScrollView): fix tests --- .../src/components/CustomScrollView/CustomScrollView.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vkui/src/components/CustomScrollView/CustomScrollView.test.tsx b/packages/vkui/src/components/CustomScrollView/CustomScrollView.test.tsx index 38529cbce8..a6d9cfcb61 100644 --- a/packages/vkui/src/components/CustomScrollView/CustomScrollView.test.tsx +++ b/packages/vkui/src/components/CustomScrollView/CustomScrollView.test.tsx @@ -7,7 +7,7 @@ describe(CustomScrollView, () => { baselineComponent(CustomScrollView); it('should have overscroll specific className', () => { - const getBoxElement = () => screen.getByTestId('scroll-view').firstElementChild as HTMLElement; + const getBoxElement = () => screen.getByTestId('scroll-view') as HTMLElement; const { rerender } = render( From cdc692179b5dfb6dec076a12128e9f6d9e2d24b7 Mon Sep 17 00:00:00 2001 From: "e.muhamethanov" Date: Thu, 3 Oct 2024 17:31:14 +0300 Subject: [PATCH 3/8] fix(CustomScrollView): fix stories example --- .../components/CustomScrollView/CustomScrollView.stories.tsx | 5 ++++- .../components/CustomScrollView/CustomScrollView.test.tsx | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/vkui/src/components/CustomScrollView/CustomScrollView.stories.tsx b/packages/vkui/src/components/CustomScrollView/CustomScrollView.stories.tsx index 3acdc078ff..3c2888a626 100644 --- a/packages/vkui/src/components/CustomScrollView/CustomScrollView.stories.tsx +++ b/packages/vkui/src/components/CustomScrollView/CustomScrollView.stories.tsx @@ -9,6 +9,10 @@ const Wrapper = (Story: PartialStoryFn) => ( style={{ borderRadius: 10, border: '1px solid #000', + height: '100%', + width: '100%', + maxWidth: '600px', + maxHeight: '300px', }} > @@ -27,7 +31,6 @@ type Story = StoryObj; export const Playground: Story = { args: { - style: { height: 300, width: 600 }, enableHorizontalScroll: true, children: (
{ baselineComponent(CustomScrollView); it('should have overscroll specific className', () => { - const getBoxElement = () => screen.getByTestId('scroll-view') as HTMLElement; + const getBoxElement = () => screen.getByTestId('scroll-view'); const { rerender } = render( From d6446880456f6d6dbeb7e7dca63b6353709da9ed Mon Sep 17 00:00:00 2001 From: "e.muhamethanov" Date: Thu, 3 Oct 2024 17:33:43 +0300 Subject: [PATCH 4/8] test(CustomScrollView): fix test --- .../vkui/src/components/CustomSelect/CustomSelect.test.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/vkui/src/components/CustomSelect/CustomSelect.test.tsx b/packages/vkui/src/components/CustomSelect/CustomSelect.test.tsx index 928953e806..bbb5c39268 100644 --- a/packages/vkui/src/components/CustomSelect/CustomSelect.test.tsx +++ b/packages/vkui/src/components/CustomSelect/CustomSelect.test.tsx @@ -65,8 +65,7 @@ const triggerKeydownEvent = async (input: HTMLElement, key: string, code: string const mockPropertiesToScroll = (defaultScrollTop = 0) => { const setScrollTopStub = jest.fn(); - const dropdownScroll = screen.getByRole('listbox').firstElementChild - ?.firstElementChild as HTMLElement; + const dropdownScroll = screen.getByRole('listbox').firstElementChild as HTMLElement; jest.spyOn(dropdownScroll, 'offsetHeight', 'get').mockImplementation(() => 200); jest.spyOn(dropdownScroll, 'scrollTop', 'get').mockImplementation(() => defaultScrollTop); jest.spyOn(dropdownScroll, 'scrollTop', 'set').mockImplementation(setScrollTopStub); From 381d393646366f87af28b2e02e035e5a9c9dbf38 Mon Sep 17 00:00:00 2001 From: "e.muhamethanov" Date: Mon, 14 Oct 2024 18:24:16 +0300 Subject: [PATCH 5/8] feat: add codemods --- packages/codemods/src/codemod-helpers.ts | 42 +++++++++++++++++++ .../chips-select/basic.input.tsx | 30 +++++++++++++ .../custom-scroll-view/basic.input.tsx | 30 +++++++++++++ .../custom-select/basic.input.tsx | 34 +++++++++++++++ .../__testfixtures__/select/basic.input.tsx | 34 +++++++++++++++ .../__snapshots__/chips-select.ts.snap | 31 ++++++++++++++ .../__snapshots__/custom-scroll-view.ts.snap | 28 +++++++++++++ .../__snapshots__/custom-select.ts.snap | 35 ++++++++++++++++ .../v7/__tests__/__snapshots__/select.ts.snap | 35 ++++++++++++++++ .../transforms/v7/__tests__/chips-select.ts | 12 ++++++ .../v7/__tests__/custom-scroll-view.ts | 12 ++++++ .../transforms/v7/__tests__/custom-select.ts | 12 ++++++ .../src/transforms/v7/__tests__/select.ts | 12 ++++++ .../src/transforms/v7/chips-select.ts | 24 +++++++++++ .../src/transforms/v7/custom-scroll-view.ts | 26 ++++++++++++ .../src/transforms/v7/custom-select.ts | 24 +++++++++++ packages/codemods/src/transforms/v7/select.ts | 24 +++++++++++ .../CustomScrollView.module.css | 12 ++++++ .../CustomScrollView/CustomScrollView.tsx | 8 ++++ 19 files changed, 465 insertions(+) create mode 100644 packages/codemods/src/transforms/v7/__testfixtures__/chips-select/basic.input.tsx create mode 100644 packages/codemods/src/transforms/v7/__testfixtures__/custom-scroll-view/basic.input.tsx create mode 100644 packages/codemods/src/transforms/v7/__testfixtures__/custom-select/basic.input.tsx create mode 100644 packages/codemods/src/transforms/v7/__testfixtures__/select/basic.input.tsx create mode 100644 packages/codemods/src/transforms/v7/__tests__/__snapshots__/chips-select.ts.snap create mode 100644 packages/codemods/src/transforms/v7/__tests__/__snapshots__/custom-scroll-view.ts.snap create mode 100644 packages/codemods/src/transforms/v7/__tests__/__snapshots__/custom-select.ts.snap create mode 100644 packages/codemods/src/transforms/v7/__tests__/__snapshots__/select.ts.snap create mode 100644 packages/codemods/src/transforms/v7/__tests__/chips-select.ts create mode 100644 packages/codemods/src/transforms/v7/__tests__/custom-scroll-view.ts create mode 100644 packages/codemods/src/transforms/v7/__tests__/custom-select.ts create mode 100644 packages/codemods/src/transforms/v7/__tests__/select.ts create mode 100644 packages/codemods/src/transforms/v7/chips-select.ts create mode 100644 packages/codemods/src/transforms/v7/custom-scroll-view.ts create mode 100644 packages/codemods/src/transforms/v7/custom-select.ts create mode 100644 packages/codemods/src/transforms/v7/select.ts diff --git a/packages/codemods/src/codemod-helpers.ts b/packages/codemods/src/codemod-helpers.ts index 7bb059ca89..e036b0b8d8 100644 --- a/packages/codemods/src/codemod-helpers.ts +++ b/packages/codemods/src/codemod-helpers.ts @@ -139,6 +139,48 @@ export function swapBooleanValue( }); } +export const removeProps = ( + j: JSCodeshift, + api: API, + source: Collection, + componentName: string, + propsNames: string[], + createReportMessage: () => string = () => '', +) => { + let needToShowReport = false; + source + .find(j.JSXElement, { + openingElement: { + name: { + name: componentName, + }, + }, + }) + .forEach((path) => { + const attributes = path.node.openingElement.attributes; + const newAttributes = attributes?.filter((attr) => { + if (attr.type === 'JSXAttribute') { + const attrName = attr.name ? attr.name.name : null; + if (typeof attrName === 'string') { + return !propsNames.includes(attrName); + } + } + if (attr.type === 'JSXSpreadAttribute') { + needToShowReport = true; + } + return false; + }); + path.node.openingElement.attributes = newAttributes; + }); + + if (needToShowReport) { + report( + api, + `: ${componentName} has been changed. Manual changes required: ${createReportMessage()}`, + ); + } +}; + export const removeAttribute = ( attributes: Array | undefined, attribute: JSXAttribute, diff --git a/packages/codemods/src/transforms/v7/__testfixtures__/chips-select/basic.input.tsx b/packages/codemods/src/transforms/v7/__testfixtures__/chips-select/basic.input.tsx new file mode 100644 index 0000000000..af0344f7dd --- /dev/null +++ b/packages/codemods/src/transforms/v7/__testfixtures__/chips-select/basic.input.tsx @@ -0,0 +1,30 @@ +import { ChipsSelect } from '@vkontakte/vkui'; +import React from 'react'; + +const App = () => { + const colors = React.useMemo( + () => [ + { value: 'red', label: 'Красный' }, + { value: 'blue', label: 'Синий' }, + { value: 'navarin', label: 'Наваринского пламени с дымом' }, + ], + [], + ); + const [selectedColors, setSelectedColors] = React.useState(() => colors.slice(0, 2)); + + return ( + + + + ); +}; diff --git a/packages/codemods/src/transforms/v7/__testfixtures__/custom-scroll-view/basic.input.tsx b/packages/codemods/src/transforms/v7/__testfixtures__/custom-scroll-view/basic.input.tsx new file mode 100644 index 0000000000..b278ec56d9 --- /dev/null +++ b/packages/codemods/src/transforms/v7/__testfixtures__/custom-scroll-view/basic.input.tsx @@ -0,0 +1,30 @@ +import { CustomScrollView, Div, Flex } from '@vkontakte/vkui'; +import React, {useRef} from 'react'; + +const App = () => { + const ref = useRef(); + return ( + + {/* Проверяем удаление старый пропов */} + + +
+ + + {/* Заменяем boxRef на getRootRef */} + + +
+ + + + ); +}; diff --git a/packages/codemods/src/transforms/v7/__testfixtures__/custom-select/basic.input.tsx b/packages/codemods/src/transforms/v7/__testfixtures__/custom-select/basic.input.tsx new file mode 100644 index 0000000000..21efad8d42 --- /dev/null +++ b/packages/codemods/src/transforms/v7/__testfixtures__/custom-select/basic.input.tsx @@ -0,0 +1,34 @@ +import { CustomSelect } from '@vkontakte/vkui'; +import React from 'react'; + +const App = () => { + const [selectType, setSelectType] = React.useState(undefined); + const selectTypes = [ + { + label: 'default', + value: 'default', + }, + { + label: 'plain', + value: 'plain', + }, + { + label: 'accent', + value: 'accent', + }, + ]; + + return ( + + setSelectType(e.target.value)} + /> + + ); +}; diff --git a/packages/codemods/src/transforms/v7/__testfixtures__/select/basic.input.tsx b/packages/codemods/src/transforms/v7/__testfixtures__/select/basic.input.tsx new file mode 100644 index 0000000000..4827ca98da --- /dev/null +++ b/packages/codemods/src/transforms/v7/__testfixtures__/select/basic.input.tsx @@ -0,0 +1,34 @@ +import { Select } from '@vkontakte/vkui'; +import React from 'react'; + +const App = () => { + const [selectType, setSelectType] = React.useState(undefined); + const selectTypes = [ + { + label: 'default', + value: 'default', + }, + { + label: 'plain', + value: 'plain', + }, + { + label: 'accent', + value: 'accent', + }, + ]; + + return ( + + setSelectType(e.target.value)} /> + ) + ); +};" +`; diff --git a/packages/codemods/src/transforms/v7/__tests__/chips-select.ts b/packages/codemods/src/transforms/v7/__tests__/chips-select.ts new file mode 100644 index 0000000000..bb303f743a --- /dev/null +++ b/packages/codemods/src/transforms/v7/__tests__/chips-select.ts @@ -0,0 +1,12 @@ +jest.autoMockOff(); + +import { defineSnapshotTestFromFixture } from '../../../testHelpers/testHelper'; + +const name = 'chips-select'; +const fixtures = ['basic'] as const; + +describe(name, () => { + fixtures.forEach((test) => + defineSnapshotTestFromFixture(__dirname, name, global.TRANSFORM_OPTIONS, `${name}/${test}`), + ); +}); diff --git a/packages/codemods/src/transforms/v7/__tests__/custom-scroll-view.ts b/packages/codemods/src/transforms/v7/__tests__/custom-scroll-view.ts new file mode 100644 index 0000000000..af9efea898 --- /dev/null +++ b/packages/codemods/src/transforms/v7/__tests__/custom-scroll-view.ts @@ -0,0 +1,12 @@ +jest.autoMockOff(); + +import { defineSnapshotTestFromFixture } from '../../../testHelpers/testHelper'; + +const name = 'custom-scroll-view'; +const fixtures = ['basic'] as const; + +describe(name, () => { + fixtures.forEach((test) => + defineSnapshotTestFromFixture(__dirname, name, global.TRANSFORM_OPTIONS, `${name}/${test}`), + ); +}); diff --git a/packages/codemods/src/transforms/v7/__tests__/custom-select.ts b/packages/codemods/src/transforms/v7/__tests__/custom-select.ts new file mode 100644 index 0000000000..7bad5184f7 --- /dev/null +++ b/packages/codemods/src/transforms/v7/__tests__/custom-select.ts @@ -0,0 +1,12 @@ +jest.autoMockOff(); + +import { defineSnapshotTestFromFixture } from '../../../testHelpers/testHelper'; + +const name = 'custom-select'; +const fixtures = ['basic'] as const; + +describe(name, () => { + fixtures.forEach((test) => + defineSnapshotTestFromFixture(__dirname, name, global.TRANSFORM_OPTIONS, `${name}/${test}`), + ); +}); diff --git a/packages/codemods/src/transforms/v7/__tests__/select.ts b/packages/codemods/src/transforms/v7/__tests__/select.ts new file mode 100644 index 0000000000..5e4bdc6e64 --- /dev/null +++ b/packages/codemods/src/transforms/v7/__tests__/select.ts @@ -0,0 +1,12 @@ +jest.autoMockOff(); + +import { defineSnapshotTestFromFixture } from '../../../testHelpers/testHelper'; + +const name = 'select'; +const fixtures = ['basic'] as const; + +describe(name, () => { + fixtures.forEach((test) => + defineSnapshotTestFromFixture(__dirname, name, global.TRANSFORM_OPTIONS, `${name}/${test}`), + ); +}); diff --git a/packages/codemods/src/transforms/v7/chips-select.ts b/packages/codemods/src/transforms/v7/chips-select.ts new file mode 100644 index 0000000000..919114d194 --- /dev/null +++ b/packages/codemods/src/transforms/v7/chips-select.ts @@ -0,0 +1,24 @@ +import { API, FileInfo } from 'jscodeshift'; +import { getImportInfo, removeProps, renameProp } from '../../codemod-helpers'; +import { JSCodeShiftOptions } from '../../types'; + +export const parser = 'tsx'; + +const PROPS_TO_REMOVE = ['autoHideScrollbar', 'autoHideScrollbarDelay']; + +export default function transformer(file: FileInfo, api: API, options: JSCodeShiftOptions) { + const { alias } = options; + const j = api.jscodeshift; + const source = j(file.source); + const { localName } = getImportInfo(j, file, 'ChipsSelect', alias); + + if (!localName) { + return source.toSource(); + } + + removeProps(j, api, source, localName, PROPS_TO_REMOVE, () => { + return `need to remove props ${PROPS_TO_REMOVE.join(', ')}`; + }); + + return source.toSource(); +} diff --git a/packages/codemods/src/transforms/v7/custom-scroll-view.ts b/packages/codemods/src/transforms/v7/custom-scroll-view.ts new file mode 100644 index 0000000000..a88eb93a29 --- /dev/null +++ b/packages/codemods/src/transforms/v7/custom-scroll-view.ts @@ -0,0 +1,26 @@ +import { API, FileInfo } from 'jscodeshift'; +import { getImportInfo, removeProps, renameProp } from '../../codemod-helpers'; +import { JSCodeShiftOptions } from '../../types'; + +export const parser = 'tsx'; + +const PROPS_TO_REMOVE = ['windowResize', 'autoHideScrollbar', 'autoHideScrollbarDelay']; + +export default function transformer(file: FileInfo, api: API, options: JSCodeShiftOptions) { + const { alias } = options; + const j = api.jscodeshift; + const source = j(file.source); + const { localName } = getImportInfo(j, file, 'CustomScrollView', alias); + + if (!localName) { + return source.toSource(); + } + + removeProps(j, api, source, localName, PROPS_TO_REMOVE, () => { + return `need to remove props ${PROPS_TO_REMOVE.join(', ')}`; + }); + + renameProp(j, source, localName, { boxRef: 'getRootRef' }); + + return source.toSource(); +} diff --git a/packages/codemods/src/transforms/v7/custom-select.ts b/packages/codemods/src/transforms/v7/custom-select.ts new file mode 100644 index 0000000000..fc07386f7b --- /dev/null +++ b/packages/codemods/src/transforms/v7/custom-select.ts @@ -0,0 +1,24 @@ +import { API, FileInfo } from 'jscodeshift'; +import { getImportInfo, removeProps, renameProp } from '../../codemod-helpers'; +import { JSCodeShiftOptions } from '../../types'; + +export const parser = 'tsx'; + +const PROPS_TO_REMOVE = ['autoHideScrollbar', 'autoHideScrollbarDelay']; + +export default function transformer(file: FileInfo, api: API, options: JSCodeShiftOptions) { + const { alias } = options; + const j = api.jscodeshift; + const source = j(file.source); + const { localName } = getImportInfo(j, file, 'CustomSelect', alias); + + if (!localName) { + return source.toSource(); + } + + removeProps(j, api, source, localName, PROPS_TO_REMOVE, () => { + return `need to remove props ${PROPS_TO_REMOVE.join(', ')}`; + }); + + return source.toSource(); +} diff --git a/packages/codemods/src/transforms/v7/select.ts b/packages/codemods/src/transforms/v7/select.ts new file mode 100644 index 0000000000..a9a29e7920 --- /dev/null +++ b/packages/codemods/src/transforms/v7/select.ts @@ -0,0 +1,24 @@ +import { API, FileInfo } from 'jscodeshift'; +import { getImportInfo, removeProps, renameProp } from '../../codemod-helpers'; +import { JSCodeShiftOptions } from '../../types'; + +export const parser = 'tsx'; + +const PROPS_TO_REMOVE = ['autoHideScrollbar', 'autoHideScrollbarDelay']; + +export default function transformer(file: FileInfo, api: API, options: JSCodeShiftOptions) { + const { alias } = options; + const j = api.jscodeshift; + const source = j(file.source); + const { localName } = getImportInfo(j, file, 'Select', alias); + + if (!localName) { + return source.toSource(); + } + + removeProps(j, api, source, localName, PROPS_TO_REMOVE, () => { + return `need to remove props ${PROPS_TO_REMOVE.join(', ')}`; + }); + + return source.toSource(); +} diff --git a/packages/vkui/src/components/CustomScrollView/CustomScrollView.module.css b/packages/vkui/src/components/CustomScrollView/CustomScrollView.module.css index d07f01565c..016bf1f0ed 100644 --- a/packages/vkui/src/components/CustomScrollView/CustomScrollView.module.css +++ b/packages/vkui/src/components/CustomScrollView/CustomScrollView.module.css @@ -10,8 +10,20 @@ scrollbar-color: var(--vkui--color_icon_medium_alpha) transparent; scrollbar-width: thin; } + + .scrollbarHidden { + /** + * Для удаление скролла в Firefox. + * В версии ниже 64 будет виден скролл, но это не ломает функциональность. + */ + scrollbar-width: none; + } } @supports not (scrollbar-color: auto) { + .scrollbarHidden::-webkit-scrollbar { + display: none; + } + .host::-webkit-scrollbar { inline-size: 12px; block-size: 12px; diff --git a/packages/vkui/src/components/CustomScrollView/CustomScrollView.tsx b/packages/vkui/src/components/CustomScrollView/CustomScrollView.tsx index 557812fa38..c3fd4b58c4 100644 --- a/packages/vkui/src/components/CustomScrollView/CustomScrollView.tsx +++ b/packages/vkui/src/components/CustomScrollView/CustomScrollView.tsx @@ -25,6 +25,12 @@ export interface CustomScrollViewProps * Включение отображения горизонтального скролла */ enableHorizontalScroll?: boolean; + /** + * Скрытие скроллбара + * + * > В версии ниже Firefox 64 будет виден скролл + */ + scrollbarHidden?: boolean; } /** @@ -37,6 +43,7 @@ export const CustomScrollView = ({ onScroll, getRootRef, overscrollBehavior = 'auto', + scrollbarHidden = false, ...restProps }: CustomScrollViewProps): React.ReactNode => { return ( @@ -46,6 +53,7 @@ export const CustomScrollView = ({ styles.host, enableHorizontalScroll && styles.horizontalScrollEnabled, overscrollBehaviorClassNames[overscrollBehavior], + scrollbarHidden && styles.scrollbarHidden, )} ref={getRootRef} onScroll={onScroll} From e9167cc4d8c8fc4ad5abcdf6bbfda3e72c449cd2 Mon Sep 17 00:00:00 2001 From: "e.muhamethanov" Date: Tue, 15 Oct 2024 11:22:40 +0300 Subject: [PATCH 6/8] test(CustomScrollView): update screenshots --- .../CustomScrollView.e2e-playground.tsx | 30 +++++-------------- .../CustomScrollView/CustomScrollView.e2e.tsx | 14 +-------- .../CustomScrollView.module.css | 6 ++-- ...ntal-scroll-vkcom-chromium-dark-1-snap.png | 4 +-- ...tal-scroll-vkcom-chromium-light-1-snap.png | 4 +-- ...ontal-scroll-vkcom-firefox-dark-1-snap.png | 4 +-- ...ntal-scroll-vkcom-firefox-light-1-snap.png | 4 +-- ...zontal-scroll-vkcom-webkit-dark-1-snap.png | 4 +-- ...ontal-scroll-vkcom-webkit-light-1-snap.png | 4 +-- ...ical-scroll-vkcom-chromium-dark-1-snap.png | 3 -- ...cal-scroll-vkcom-chromium-light-1-snap.png | 3 -- ...tical-scroll-vkcom-firefox-dark-1-snap.png | 3 -- ...ical-scroll-vkcom-firefox-light-1-snap.png | 3 -- ...rtical-scroll-vkcom-webkit-dark-1-snap.png | 3 -- ...tical-scroll-vkcom-webkit-light-1-snap.png | 3 -- 15 files changed, 24 insertions(+), 68 deletions(-) delete mode 100644 packages/vkui/src/components/CustomScrollView/__image_snapshots__/customscrollview-with-vertical-scroll-vkcom-chromium-dark-1-snap.png delete mode 100644 packages/vkui/src/components/CustomScrollView/__image_snapshots__/customscrollview-with-vertical-scroll-vkcom-chromium-light-1-snap.png delete mode 100644 packages/vkui/src/components/CustomScrollView/__image_snapshots__/customscrollview-with-vertical-scroll-vkcom-firefox-dark-1-snap.png delete mode 100644 packages/vkui/src/components/CustomScrollView/__image_snapshots__/customscrollview-with-vertical-scroll-vkcom-firefox-light-1-snap.png delete mode 100644 packages/vkui/src/components/CustomScrollView/__image_snapshots__/customscrollview-with-vertical-scroll-vkcom-webkit-dark-1-snap.png delete mode 100644 packages/vkui/src/components/CustomScrollView/__image_snapshots__/customscrollview-with-vertical-scroll-vkcom-webkit-light-1-snap.png diff --git a/packages/vkui/src/components/CustomScrollView/CustomScrollView.e2e-playground.tsx b/packages/vkui/src/components/CustomScrollView/CustomScrollView.e2e-playground.tsx index 65c7dab213..ff8a2e8362 100644 --- a/packages/vkui/src/components/CustomScrollView/CustomScrollView.e2e-playground.tsx +++ b/packages/vkui/src/components/CustomScrollView/CustomScrollView.e2e-playground.tsx @@ -1,31 +1,17 @@ import { ComponentPlayground, type ComponentPlaygroundProps } from '@vkui-e2e/playground-helpers'; -import { Avatar } from '../Avatar/Avatar'; -import { Cell } from '../Cell/Cell'; import { Div } from '../Div/Div'; -import { List } from '../List/List'; import { CustomScrollView, type CustomScrollViewProps } from './CustomScrollView'; -export const CustomScrollViewWithVerticalPlayground = (props: ComponentPlaygroundProps) => { - return ( - - {(props: CustomScrollViewProps) => ( - - - {['Say', 'Hello', 'To', 'My', 'Little', 'Friend'].map((item) => ( - }> - {item} - - ))} - - - )} - - ); -}; - export const CustomScrollViewWithBothScrollsPlayground = (props: ComponentPlaygroundProps) => { return ( - + {(props: CustomScrollViewProps) => (
{ test.use({ onlyForPlatforms: ['vkcom'] }); - test('with vertical scroll', async ({ - mount, - expectScreenshotClippedToContent, - componentPlaygroundProps, - }) => { - await mount(); - await expectScreenshotClippedToContent(); - }); - test('with vertical and horizontal scroll', async ({ mount, expectScreenshotClippedToContent, diff --git a/packages/vkui/src/components/CustomScrollView/CustomScrollView.module.css b/packages/vkui/src/components/CustomScrollView/CustomScrollView.module.css index 016bf1f0ed..953dc90c84 100644 --- a/packages/vkui/src/components/CustomScrollView/CustomScrollView.module.css +++ b/packages/vkui/src/components/CustomScrollView/CustomScrollView.module.css @@ -7,7 +7,7 @@ @supports (scrollbar-color: auto) { .host { - scrollbar-color: var(--vkui--color_icon_medium_alpha) transparent; + scrollbar-color: var(--vkui--color_icon_tertiary_alpha) transparent; scrollbar-width: thin; } @@ -37,7 +37,7 @@ .host::-webkit-scrollbar-thumb, .host::-webkit-scrollbar-thumb { - background-color: var(--vkui--color_icon_medium_alpha); + background-color: var(--vkui--color_icon_tertiary_alpha); border: 3px solid transparent; border-radius: 6px; background-clip: padding-box, content-box; @@ -45,7 +45,7 @@ .host::-webkit-scrollbar-thumb:hover, .host::-webkit-scrollbar-thumb:active { - background-color: var(--vkui--color_icon_medium_alpha--hover); + background-color: var(--vkui--color_icon_tertiary_alpha--hover); border: 2px solid transparent; } } diff --git a/packages/vkui/src/components/CustomScrollView/__image_snapshots__/customscrollview-with-vertical-and-horizontal-scroll-vkcom-chromium-dark-1-snap.png b/packages/vkui/src/components/CustomScrollView/__image_snapshots__/customscrollview-with-vertical-and-horizontal-scroll-vkcom-chromium-dark-1-snap.png index cc1b62e8e2..0458cad1fc 100644 --- a/packages/vkui/src/components/CustomScrollView/__image_snapshots__/customscrollview-with-vertical-and-horizontal-scroll-vkcom-chromium-dark-1-snap.png +++ b/packages/vkui/src/components/CustomScrollView/__image_snapshots__/customscrollview-with-vertical-and-horizontal-scroll-vkcom-chromium-dark-1-snap.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0a889467e9a7e15354776657d1e865756844ec05f53ed4cd7ca6b0674c9ccb3f -size 45556 +oid sha256:bba338578e010ae5abafb141d080b1877e006f04585b968daf00c11701d6b200 +size 86722 diff --git a/packages/vkui/src/components/CustomScrollView/__image_snapshots__/customscrollview-with-vertical-and-horizontal-scroll-vkcom-chromium-light-1-snap.png b/packages/vkui/src/components/CustomScrollView/__image_snapshots__/customscrollview-with-vertical-and-horizontal-scroll-vkcom-chromium-light-1-snap.png index 0c42fef796..d01bc44d91 100644 --- a/packages/vkui/src/components/CustomScrollView/__image_snapshots__/customscrollview-with-vertical-and-horizontal-scroll-vkcom-chromium-light-1-snap.png +++ b/packages/vkui/src/components/CustomScrollView/__image_snapshots__/customscrollview-with-vertical-and-horizontal-scroll-vkcom-chromium-light-1-snap.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ba096b3d4001c094961f72fd4edb54cf1bbb753534671ae193d1a4d8e9fa9139 -size 44762 +oid sha256:05d8f58eeaaa2fc35b71616297244e615792045e494b500aef31020b21fe8a44 +size 85393 diff --git a/packages/vkui/src/components/CustomScrollView/__image_snapshots__/customscrollview-with-vertical-and-horizontal-scroll-vkcom-firefox-dark-1-snap.png b/packages/vkui/src/components/CustomScrollView/__image_snapshots__/customscrollview-with-vertical-and-horizontal-scroll-vkcom-firefox-dark-1-snap.png index 5329eb8511..b5689ea1fa 100644 --- a/packages/vkui/src/components/CustomScrollView/__image_snapshots__/customscrollview-with-vertical-and-horizontal-scroll-vkcom-firefox-dark-1-snap.png +++ b/packages/vkui/src/components/CustomScrollView/__image_snapshots__/customscrollview-with-vertical-and-horizontal-scroll-vkcom-firefox-dark-1-snap.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:65374f061a65da67527157a18bb7e9b03cf338e730153f841d0e34a24abb22bf -size 85121 +oid sha256:186e8c144725347c5ae84a96d4bb86bc4b0febebc5c54571c929707ac55f62ab +size 168438 diff --git a/packages/vkui/src/components/CustomScrollView/__image_snapshots__/customscrollview-with-vertical-and-horizontal-scroll-vkcom-firefox-light-1-snap.png b/packages/vkui/src/components/CustomScrollView/__image_snapshots__/customscrollview-with-vertical-and-horizontal-scroll-vkcom-firefox-light-1-snap.png index ddd02c3ffd..bfee153ab6 100644 --- a/packages/vkui/src/components/CustomScrollView/__image_snapshots__/customscrollview-with-vertical-and-horizontal-scroll-vkcom-firefox-light-1-snap.png +++ b/packages/vkui/src/components/CustomScrollView/__image_snapshots__/customscrollview-with-vertical-and-horizontal-scroll-vkcom-firefox-light-1-snap.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:91aa66dc5d6a7e3c540f7a9d6fe07e093f58b68ddfac30a6e2ec741eda8721e4 -size 68270 +oid sha256:5092931b4ba1ae1957292b0e874dad3a953d143a433c481f7beacc29d8d36e04 +size 134812 diff --git a/packages/vkui/src/components/CustomScrollView/__image_snapshots__/customscrollview-with-vertical-and-horizontal-scroll-vkcom-webkit-dark-1-snap.png b/packages/vkui/src/components/CustomScrollView/__image_snapshots__/customscrollview-with-vertical-and-horizontal-scroll-vkcom-webkit-dark-1-snap.png index 3502afdd15..b5c700e24c 100644 --- a/packages/vkui/src/components/CustomScrollView/__image_snapshots__/customscrollview-with-vertical-and-horizontal-scroll-vkcom-webkit-dark-1-snap.png +++ b/packages/vkui/src/components/CustomScrollView/__image_snapshots__/customscrollview-with-vertical-and-horizontal-scroll-vkcom-webkit-dark-1-snap.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:aa0470b042aaaba22eb06c9f744721df3af15d9667282e1aff3335a7d7b51424 -size 46141 +oid sha256:b14db85e4be0c40f221c269322282ecf85a2389dae61dc41b1e3f8c69f20f858 +size 86728 diff --git a/packages/vkui/src/components/CustomScrollView/__image_snapshots__/customscrollview-with-vertical-and-horizontal-scroll-vkcom-webkit-light-1-snap.png b/packages/vkui/src/components/CustomScrollView/__image_snapshots__/customscrollview-with-vertical-and-horizontal-scroll-vkcom-webkit-light-1-snap.png index d3e07b8797..3973cde571 100644 --- a/packages/vkui/src/components/CustomScrollView/__image_snapshots__/customscrollview-with-vertical-and-horizontal-scroll-vkcom-webkit-light-1-snap.png +++ b/packages/vkui/src/components/CustomScrollView/__image_snapshots__/customscrollview-with-vertical-and-horizontal-scroll-vkcom-webkit-light-1-snap.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:caf37a0d4a2499526184c23fd4f56fc2c129c083ee4f1e7207d19dd95cf13d83 -size 45736 +oid sha256:88387e1c668de309d75850c300487edb12c9078e74cf07e92d0ebccb0f704e2d +size 86116 diff --git a/packages/vkui/src/components/CustomScrollView/__image_snapshots__/customscrollview-with-vertical-scroll-vkcom-chromium-dark-1-snap.png b/packages/vkui/src/components/CustomScrollView/__image_snapshots__/customscrollview-with-vertical-scroll-vkcom-chromium-dark-1-snap.png deleted file mode 100644 index 22a9ec6916..0000000000 --- a/packages/vkui/src/components/CustomScrollView/__image_snapshots__/customscrollview-with-vertical-scroll-vkcom-chromium-dark-1-snap.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ea6f323624d871ea7779ce102a9b6870215b5f82ae0089e55d11bbd28961ac9f -size 16566 diff --git a/packages/vkui/src/components/CustomScrollView/__image_snapshots__/customscrollview-with-vertical-scroll-vkcom-chromium-light-1-snap.png b/packages/vkui/src/components/CustomScrollView/__image_snapshots__/customscrollview-with-vertical-scroll-vkcom-chromium-light-1-snap.png deleted file mode 100644 index fd0d1e61af..0000000000 --- a/packages/vkui/src/components/CustomScrollView/__image_snapshots__/customscrollview-with-vertical-scroll-vkcom-chromium-light-1-snap.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c569f0085dfafb3af9a733e213906b00e18e26b4a5c5c155c44cd3576f9982dd -size 16567 diff --git a/packages/vkui/src/components/CustomScrollView/__image_snapshots__/customscrollview-with-vertical-scroll-vkcom-firefox-dark-1-snap.png b/packages/vkui/src/components/CustomScrollView/__image_snapshots__/customscrollview-with-vertical-scroll-vkcom-firefox-dark-1-snap.png deleted file mode 100644 index 082adaf086..0000000000 --- a/packages/vkui/src/components/CustomScrollView/__image_snapshots__/customscrollview-with-vertical-scroll-vkcom-firefox-dark-1-snap.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:848926d10d0669c6ae61afd8a57064daeb70c69108fdcb0fb3f97e38382d4588 -size 19395 diff --git a/packages/vkui/src/components/CustomScrollView/__image_snapshots__/customscrollview-with-vertical-scroll-vkcom-firefox-light-1-snap.png b/packages/vkui/src/components/CustomScrollView/__image_snapshots__/customscrollview-with-vertical-scroll-vkcom-firefox-light-1-snap.png deleted file mode 100644 index 9bf688fae2..0000000000 --- a/packages/vkui/src/components/CustomScrollView/__image_snapshots__/customscrollview-with-vertical-scroll-vkcom-firefox-light-1-snap.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:58a9894f420e09f216603da1ff9d9503a6526a5da41f127dc46545e13bb666db -size 19892 diff --git a/packages/vkui/src/components/CustomScrollView/__image_snapshots__/customscrollview-with-vertical-scroll-vkcom-webkit-dark-1-snap.png b/packages/vkui/src/components/CustomScrollView/__image_snapshots__/customscrollview-with-vertical-scroll-vkcom-webkit-dark-1-snap.png deleted file mode 100644 index 3ca202623f..0000000000 --- a/packages/vkui/src/components/CustomScrollView/__image_snapshots__/customscrollview-with-vertical-scroll-vkcom-webkit-dark-1-snap.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b49e673126a6eb082fb01e7b85b2474bc4f8b3724a3b5897eacb1469d9a68aa4 -size 17015 diff --git a/packages/vkui/src/components/CustomScrollView/__image_snapshots__/customscrollview-with-vertical-scroll-vkcom-webkit-light-1-snap.png b/packages/vkui/src/components/CustomScrollView/__image_snapshots__/customscrollview-with-vertical-scroll-vkcom-webkit-light-1-snap.png deleted file mode 100644 index bb6f2ada84..0000000000 --- a/packages/vkui/src/components/CustomScrollView/__image_snapshots__/customscrollview-with-vertical-scroll-vkcom-webkit-light-1-snap.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ac33525a11ff3317c093a97a0e1c9416dfa6e1c4cf91d62a8392758a9b14fbff -size 16850 From d44fef60a272cd2ce12bba0971131198124943e7 Mon Sep 17 00:00:00 2001 From: "e.muhamethanov" Date: Tue, 15 Oct 2024 11:24:46 +0300 Subject: [PATCH 7/8] fix: remove imports --- packages/codemods/src/transforms/v7/chips-select.ts | 2 +- packages/codemods/src/transforms/v7/custom-select.ts | 2 +- packages/codemods/src/transforms/v7/select.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/codemods/src/transforms/v7/chips-select.ts b/packages/codemods/src/transforms/v7/chips-select.ts index 919114d194..6d5d6261de 100644 --- a/packages/codemods/src/transforms/v7/chips-select.ts +++ b/packages/codemods/src/transforms/v7/chips-select.ts @@ -1,5 +1,5 @@ import { API, FileInfo } from 'jscodeshift'; -import { getImportInfo, removeProps, renameProp } from '../../codemod-helpers'; +import { getImportInfo, removeProps } from '../../codemod-helpers'; import { JSCodeShiftOptions } from '../../types'; export const parser = 'tsx'; diff --git a/packages/codemods/src/transforms/v7/custom-select.ts b/packages/codemods/src/transforms/v7/custom-select.ts index fc07386f7b..6a34a10823 100644 --- a/packages/codemods/src/transforms/v7/custom-select.ts +++ b/packages/codemods/src/transforms/v7/custom-select.ts @@ -1,5 +1,5 @@ import { API, FileInfo } from 'jscodeshift'; -import { getImportInfo, removeProps, renameProp } from '../../codemod-helpers'; +import { getImportInfo, removeProps } from '../../codemod-helpers'; import { JSCodeShiftOptions } from '../../types'; export const parser = 'tsx'; diff --git a/packages/codemods/src/transforms/v7/select.ts b/packages/codemods/src/transforms/v7/select.ts index a9a29e7920..de1d59af25 100644 --- a/packages/codemods/src/transforms/v7/select.ts +++ b/packages/codemods/src/transforms/v7/select.ts @@ -1,5 +1,5 @@ import { API, FileInfo } from 'jscodeshift'; -import { getImportInfo, removeProps, renameProp } from '../../codemod-helpers'; +import { getImportInfo, removeProps } from '../../codemod-helpers'; import { JSCodeShiftOptions } from '../../types'; export const parser = 'tsx'; From f76618e73649bf670531d425242079ef14af67be Mon Sep 17 00:00:00 2001 From: "e.muhamethanov" Date: Tue, 15 Oct 2024 11:49:21 +0300 Subject: [PATCH 8/8] feat: add comment to documentation --- packages/vkui/src/components/CustomScrollView/Readme.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/vkui/src/components/CustomScrollView/Readme.md b/packages/vkui/src/components/CustomScrollView/Readme.md index fe954a08d3..d6044024bf 100644 --- a/packages/vkui/src/components/CustomScrollView/Readme.md +++ b/packages/vkui/src/components/CustomScrollView/Readme.md @@ -1,5 +1,8 @@ Компонент, который кастомизирует браузерную полосу прокрутки +> Начиная с версии `7.0.0` по умолчанию используется нативная кастомизация скроллбара. +> Важно, что данная реализация не работает для браузера `Firefox` меньше `64` версии. + ```jsx const WithVerticalScroll = () => { return (