@vkontakte/vkui 7.5.1 → 7.5.3
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/dist/components/HorizontalScroll/HorizontalScroll.d.ts.map +1 -1
- package/dist/components/HorizontalScroll/HorizontalScroll.js +13 -3
- package/dist/components/HorizontalScroll/HorizontalScroll.js.map +1 -1
- package/dist/components/ImageBase/ImageBase.d.ts.map +1 -1
- package/dist/components/ImageBase/ImageBase.js +3 -4
- package/dist/components/ImageBase/ImageBase.js.map +1 -1
- package/dist/components.css +1 -1
- package/dist/components.css.map +1 -1
- package/dist/cssm/components/HorizontalScroll/HorizontalScroll.js +9 -1
- package/dist/cssm/components/HorizontalScroll/HorizontalScroll.js.map +1 -1
- package/dist/cssm/components/ImageBase/ImageBase.js +3 -4
- package/dist/cssm/components/ImageBase/ImageBase.js.map +1 -1
- package/dist/cssm/components/ImageBase/ImageBase.module.css +9 -2
- package/dist/cssm/components/ModalPage/ModalPage.module.css +9 -15
- package/dist/vkui.css +1 -1
- package/dist/vkui.css.map +1 -1
- package/package.json +1 -1
- package/src/components/HorizontalScroll/HorizontalScroll.tsx +13 -1
- package/src/components/ImageBase/ImageBase.module.css +9 -2
- package/src/components/ImageBase/ImageBase.module.css.d.ts.map +1 -1
- package/src/components/ImageBase/ImageBase.tsx +3 -4
- package/src/components/ModalPage/ModalPage.module.css +9 -14
- package/src/components/ModalPage/ModalPage.module.css.d.ts.map +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HorizontalScroll.d.ts","sourceRoot":"","sources":["../../../src/components/HorizontalScroll/HorizontalScroll.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"HorizontalScroll.d.ts","sourceRoot":"","sources":["../../../src/components/HorizontalScroll/HorizontalScroll.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAS/B,OAAO,KAAK,EAAE,MAAM,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAErE,OAAO,EAAe,KAAK,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAqBhF,MAAM,MAAM,qBAAqB,GAAG,CAAC,eAAe,EAAE,MAAM,KAAK,MAAM,CAAC;AAExE,MAAM,WAAW,qBACf,SAAQ,yBAAyB,CAAC,cAAc,CAAC,EAC/C,MAAM,CAAC,cAAc,CAAC;IACxB;;OAEG;IACH,eAAe,CAAC,EAAE,qBAAqB,CAAC;IACxC;;OAEG;IACH,gBAAgB,CAAC,EAAE,qBAAqB,CAAC;IACzC;;OAEG;IACH,SAAS,CAAC,EAAE,gBAAgB,CAAC,MAAM,CAAC,CAAC;IACrC;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC/B;;OAEG;IACH,UAAU,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;IAChC;;OAEG;IACH,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC;;;OAGG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;OAEG;IACH,uBAAuB,CAAC,EAAE,KAAK,CAAC,WAAW,CAAC;IAC5C;;OAEG;IACH,iBAAiB,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAC3C;;OAEG;IACH,uBAAuB,CAAC,EAAE,MAAM,CAAC;CAClC;AA6GD;;GAEG;AACH,eAAO,MAAM,gBAAgB,GAAI,gQAiB9B,qBAAqB,KAAG,KAAK,CAAC,SAyJhC,CAAC"}
|
|
@@ -8,6 +8,8 @@ import { classNames, noop } from "@vkontakte/vkjs";
|
|
|
8
8
|
import { useAdaptivityHasPointer } from "../../hooks/useAdaptivityHasPointer.js";
|
|
9
9
|
import { useConfigDirection } from "../../hooks/useConfigDirection.js";
|
|
10
10
|
import { useExternRef } from "../../hooks/useExternRef.js";
|
|
11
|
+
import { useFocusVisible } from "../../hooks/useFocusVisible.js";
|
|
12
|
+
import { useFocusVisibleClassName } from "../../hooks/useFocusVisibleClassName.js";
|
|
11
13
|
import { easeInOutSine } from "../../lib/fx.js";
|
|
12
14
|
import { useIsomorphicLayoutEffect } from "../../lib/useIsomorphicLayoutEffect.js";
|
|
13
15
|
import { RootComponent } from "../RootComponent/RootComponent.js";
|
|
@@ -105,6 +107,12 @@ function doScroll({ scrollElement, getScrollPosition, animationQueue, onScrollTo
|
|
|
105
107
|
]);
|
|
106
108
|
const [canScrollStart, setCanScrollStart] = React.useState(false);
|
|
107
109
|
const [canScrollEnd, setCanScrollEnd] = React.useState(false);
|
|
110
|
+
const _useFocusVisible = useFocusVisible(), { focusVisible } = _useFocusVisible, focusEvents = _object_without_properties(_useFocusVisible, [
|
|
111
|
+
"focusVisible"
|
|
112
|
+
]);
|
|
113
|
+
const focusVisibleClassNames = useFocusVisibleClassName({
|
|
114
|
+
focusVisible
|
|
115
|
+
});
|
|
108
116
|
const direction = useConfigDirection();
|
|
109
117
|
const isRtl = direction === 'rtl';
|
|
110
118
|
const isCustomScrollingRef = React.useRef(false);
|
|
@@ -227,15 +235,17 @@ function doScroll({ scrollElement, getScrollPosition, animationQueue, onScrollTo
|
|
|
227
235
|
className: classNames("vkuiHorizontalScroll__arrow", "vkuiHorizontalScroll__arrowRight"),
|
|
228
236
|
onClick: scrollToEnd
|
|
229
237
|
}),
|
|
230
|
-
/*#__PURE__*/ _jsx("div", {
|
|
231
|
-
className: "vkuiHorizontalScroll__in",
|
|
238
|
+
/*#__PURE__*/ _jsx("div", _object_spread_props(_object_spread({
|
|
239
|
+
className: classNames("vkuiHorizontalScroll__in", focusVisibleClassNames),
|
|
232
240
|
ref: scrollerRef,
|
|
241
|
+
tabIndex: 0
|
|
242
|
+
}, focusEvents), {
|
|
233
243
|
children: /*#__PURE__*/ _jsx(ContentWrapperComponent, {
|
|
234
244
|
className: classNames("vkuiHorizontalScroll__inWrapper", contentWrapperClassName),
|
|
235
245
|
ref: contentWrapperRef,
|
|
236
246
|
children: children
|
|
237
247
|
})
|
|
238
|
-
})
|
|
248
|
+
}))
|
|
239
249
|
]
|
|
240
250
|
}));
|
|
241
251
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/HorizontalScroll/HorizontalScroll.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { classNames, noop } from '@vkontakte/vkjs';\nimport { useAdaptivityHasPointer } from '../../hooks/useAdaptivityHasPointer';\nimport { useConfigDirection } from '../../hooks/useConfigDirection';\nimport { useExternRef } from '../../hooks/useExternRef';\nimport { easeInOutSine } from '../../lib/fx';\nimport { useIsomorphicLayoutEffect } from '../../lib/useIsomorphicLayoutEffect';\nimport type { HasRef, HTMLAttributesWithRootRef } from '../../types';\nimport { RootComponent } from '../RootComponent/RootComponent';\nimport { ScrollArrow, type ScrollArrowProps } from '../ScrollArrow/ScrollArrow';\nimport styles from './HorizontalScroll.module.css';\n\n/* eslint-disable jsdoc/require-jsdoc */\ninterface ScrollContext {\n scrollElement: HTMLElement | null;\n scrollAnimationDuration: number;\n animationQueue: VoidFunction[];\n getScrollPosition: (currentPosition: number) => number;\n onScrollToEndBorder: VoidFunction;\n onScrollEnd: VoidFunction;\n onScrollStart: VoidFunction;\n /**\n * Начальная ширина прокрутки.\n * В некоторых случаях может отличаться от текущей ширины прокрутки из-за transforms: translate.\n */\n initialScrollWidth: number;\n textDirection: 'ltr' | 'rtl';\n}\n/* eslint-enable jsdoc/require-jsdoc */\n\nexport type ScrollPositionHandler = (currentPosition: number) => number;\n\nexport interface HorizontalScrollProps\n extends HTMLAttributesWithRootRef<HTMLDivElement>,\n HasRef<HTMLDivElement> {\n /**\n * Функция для расчета величины прокрутки при нажатии на левую стрелку.\n */\n getScrollToLeft?: ScrollPositionHandler;\n /**\n * Функция для расчета величины прокрутки при нажатии на правую стрелку.\n */\n getScrollToRight?: ScrollPositionHandler;\n /**\n * Размер стрелок.\n */\n arrowSize?: ScrollArrowProps['size'];\n /**\n * Смещает иконки кнопок навигации по вертикали.\n */\n arrowOffsetY?: number | string;\n /**\n * Показывать ли стрелки.\n */\n showArrows?: boolean | 'always';\n /**\n * Длительность анимации скролла.\n */\n scrollAnimationDuration?: number;\n /**\n * Добавляет возможность прокручивать контент на любое колесо мыши.\n * По умолчанию прокручивается как любой горизонтальный контент через shift.\n */\n scrollOnAnyWheel?: boolean;\n /**\n * Передает атрибут `data-testid` для кнопки прокрутки горизонтального скролла в направлении предыдущего элемента.\n */\n prevButtonTestId?: string;\n /**\n * Передает атрибут `data-testid` для кнопки прокрутки горизонтального скролла в направлении следующего элемента.\n */\n nextButtonTestId?: string;\n /**\n * Позволяет поменять тег используемый для обертки над контентом, прокинутым в `children`.\n */\n ContentWrapperComponent?: React.ElementType;\n /**\n * `ref` для обертки над контентом, прокинутым в `children`.\n */\n contentWrapperRef?: React.Ref<HTMLElement>;\n /**\n * Специфичный `className` для обертки над контентом, прокинутым в `children`.\n */\n contentWrapperClassName?: string;\n}\n\n/**\n * Timing method.\n */\nfunction now() {\n return performance && performance.now ? performance.now() : Date.now();\n}\n\n/**\n * Округление к большему по модулю.\n *\n * ## Пример\n *\n * ```ts\n * import { strict as assert } from 'node:assert';\n *\n * assert.equal(roundingAwayFromZero(5.1), 6)\n * assert.equal(roundingAwayFromZero(-5.1), -6)\n * ```\n */\nfunction roundingAwayFromZero(value: number): number {\n return value > 0 ? Math.ceil(value) : Math.floor(value);\n}\n\n/**\n * Округляем el.scrollLeft\n * https://github.com/VKCOM/VKUI/pull/2445.\n */\nconst roundUpElementScrollLeft = (el: HTMLElement) => roundingAwayFromZero(el.scrollLeft);\n\n/**\n * Код анимации скрола, на основе полифила: https://github.com/iamdustan/smoothscroll\n * Константа взята из полифила (468), на дизайн-ревью уточнили до 250.\n * @var {number} SCROLL_ONE_FRAME_TIME время анимации скролла\n */\nconst SCROLL_ONE_FRAME_TIME = 250;\n\nfunction doScroll({\n scrollElement,\n getScrollPosition,\n animationQueue,\n onScrollToEndBorder,\n onScrollEnd,\n onScrollStart,\n initialScrollWidth,\n scrollAnimationDuration,\n textDirection,\n}: ScrollContext) {\n if (!scrollElement || !getScrollPosition) {\n return;\n }\n\n /**\n * Крайнее значение сдвига.\n */\n const extremeScrollLeft =\n (textDirection === 'ltr' ? 1 : -1) * (initialScrollWidth - scrollElement.offsetWidth);\n\n const startScrollLeft = roundUpElementScrollLeft(scrollElement);\n const remappedStartScrollLeft = startScrollLeft * (textDirection === 'rtl' ? -1 : 1);\n\n let endScrollLeft = getScrollPosition(remappedStartScrollLeft);\n\n const diff = endScrollLeft - remappedStartScrollLeft;\n if (textDirection === 'rtl') {\n endScrollLeft = startScrollLeft - diff;\n }\n\n onScrollStart();\n\n /**\n * Если окончание прокрутки вышло за ноль.\n */\n if (startScrollLeft * endScrollLeft < 0) {\n endScrollLeft = 0;\n }\n\n if (Math.abs(endScrollLeft) >= Math.abs(extremeScrollLeft)) {\n onScrollToEndBorder();\n endScrollLeft = extremeScrollLeft;\n }\n\n const startTime = now();\n\n (function scroll() {\n const time = now();\n const elapsed = Math.min((time - startTime) / scrollAnimationDuration, 1);\n\n const value = easeInOutSine(elapsed);\n\n const currentScrollLeft = startScrollLeft + (endScrollLeft - startScrollLeft) * value;\n scrollElement.scrollLeft = roundingAwayFromZero(currentScrollLeft);\n\n const scrollEnd =\n textDirection === 'ltr' ? Math.max(0, endScrollLeft) : Math.min(0, endScrollLeft);\n if (roundUpElementScrollLeft(scrollElement) !== scrollEnd && elapsed !== 1) {\n requestAnimationFrame(scroll);\n return;\n }\n\n onScrollEnd();\n animationQueue.shift();\n if (animationQueue.length > 0) {\n animationQueue[0]();\n }\n })();\n}\n\n/**\n * @see https://vkui.io/components/horizontal-scroll\n */\nexport const HorizontalScroll = ({\n children,\n getScrollToLeft,\n getScrollToRight,\n showArrows = true,\n arrowSize = 'm',\n arrowOffsetY,\n scrollAnimationDuration = SCROLL_ONE_FRAME_TIME,\n getRef,\n scrollOnAnyWheel = false,\n prevButtonTestId,\n nextButtonTestId,\n // ContentWrapper\n ContentWrapperComponent = 'div',\n contentWrapperRef,\n contentWrapperClassName,\n ...restProps\n}: HorizontalScrollProps): React.ReactNode => {\n const [canScrollStart, setCanScrollStart] = React.useState(false);\n const [canScrollEnd, setCanScrollEnd] = React.useState(false);\n const direction = useConfigDirection();\n const isRtl = direction === 'rtl';\n\n const isCustomScrollingRef = React.useRef(false);\n\n const scrollerRef = useExternRef(getRef);\n\n const animationQueue = React.useRef<VoidFunction[]>([]);\n\n const hasPointer = useAdaptivityHasPointer();\n\n const scrollTo = React.useCallback(\n (getScrollPosition: ScrollPositionHandler) => {\n const scrollElement = scrollerRef.current;\n\n animationQueue.current.push(() =>\n doScroll({\n scrollElement,\n getScrollPosition,\n animationQueue: animationQueue.current,\n onScrollToEndBorder: () => setCanScrollEnd(false),\n onScrollEnd: () => (isCustomScrollingRef.current = false),\n onScrollStart: () => (isCustomScrollingRef.current = true),\n initialScrollWidth: scrollElement?.firstElementChild?.scrollWidth || 0,\n scrollAnimationDuration,\n textDirection: direction,\n }),\n );\n if (animationQueue.current.length === 1) {\n animationQueue.current[0]();\n }\n },\n [scrollerRef, scrollAnimationDuration, direction, setCanScrollEnd],\n );\n\n const scrollToStart = React.useCallback(() => {\n const getScrollPosition =\n getScrollToLeft ?? ((i: number) => i - scrollerRef.current!.offsetWidth);\n scrollTo(getScrollPosition);\n }, [getScrollToLeft, scrollTo, scrollerRef]);\n\n const scrollToEnd = React.useCallback(() => {\n const getScrollPosition =\n getScrollToRight ?? ((i: number) => i + scrollerRef.current!.offsetWidth);\n scrollTo(getScrollPosition);\n }, [getScrollToRight, scrollTo, scrollerRef]);\n\n const calculateArrowsVisibility = React.useCallback(() => {\n if (showArrows && hasPointer && scrollerRef.current && !isCustomScrollingRef.current) {\n const scrollElement = scrollerRef.current;\n const scrollLeft = scrollElement.scrollLeft;\n\n setCanScrollStart(isRtl ? scrollLeft < 0 : scrollLeft > 0);\n setCanScrollEnd(\n Math.abs(roundUpElementScrollLeft(scrollElement)) + scrollElement.offsetWidth <\n scrollElement.scrollWidth,\n );\n }\n }, [showArrows, hasPointer, scrollerRef, isRtl]);\n\n React.useEffect(calculateArrowsVisibility, [calculateArrowsVisibility, children]);\n\n useIsomorphicLayoutEffect(\n function addWheelEventHandler() {\n const scrollEl = scrollerRef.current;\n if (!scrollEl) {\n return noop;\n }\n /**\n * Прокрутка с помощью любого колеса мыши.\n */\n const onWheel = (e: WheelEvent) => {\n scrollerRef.current!.scrollBy({ left: e.deltaX + e.deltaY, behavior: 'auto' });\n e.preventDefault();\n };\n\n const listenerOptions = { passive: false };\n\n if (scrollOnAnyWheel) {\n scrollEl.addEventListener('wheel', onWheel, listenerOptions);\n }\n scrollEl.addEventListener('scroll', calculateArrowsVisibility, listenerOptions);\n\n return () => {\n if (scrollOnAnyWheel) {\n // @ts-expect-error: TS2769 В интерфейсе EventListenerOptions для wheel нет passive свойства\n scrollEl.removeEventListener('wheel', onWheel, listenerOptions);\n }\n // @ts-expect-error: TS2769 В интерфейсе EventListenerOptions для scroll нет passive свойства\n scrollEl.removeEventListener('scroll', calculateArrowsVisibility, listenerOptions);\n };\n },\n [scrollOnAnyWheel, calculateArrowsVisibility, scrollerRef],\n );\n\n return (\n <RootComponent\n {...restProps}\n baseClassName={classNames(\n styles.host,\n 'vkuiInternalHorizontalScroll',\n showArrows === 'always' && styles.withConstArrows,\n isRtl && styles.rtl,\n )}\n onMouseEnter={calculateArrowsVisibility}\n >\n {showArrows && (hasPointer || hasPointer === undefined) && canScrollStart && (\n <ScrollArrow\n data-testid={prevButtonTestId}\n size={arrowSize}\n offsetY={arrowOffsetY}\n direction=\"left\"\n aria-hidden\n tabIndex={-1}\n className={classNames(styles.arrow, styles.arrowLeft)}\n onClick={scrollToStart}\n />\n )}\n {showArrows && (hasPointer || hasPointer === undefined) && canScrollEnd && (\n <ScrollArrow\n data-testid={nextButtonTestId}\n size={arrowSize}\n offsetY={arrowOffsetY}\n direction=\"right\"\n aria-hidden\n tabIndex={-1}\n className={classNames(styles.arrow, styles.arrowRight)}\n onClick={scrollToEnd}\n />\n )}\n <div className={styles.in} ref={scrollerRef}>\n <ContentWrapperComponent\n className={classNames(styles.inWrapper, contentWrapperClassName)}\n ref={contentWrapperRef}\n >\n {children}\n </ContentWrapperComponent>\n </div>\n </RootComponent>\n );\n};\n"],"names":["React","classNames","noop","useAdaptivityHasPointer","useConfigDirection","useExternRef","easeInOutSine","useIsomorphicLayoutEffect","RootComponent","ScrollArrow","now","performance","Date","roundingAwayFromZero","value","Math","ceil","floor","roundUpElementScrollLeft","el","scrollLeft","SCROLL_ONE_FRAME_TIME","doScroll","scrollElement","getScrollPosition","animationQueue","onScrollToEndBorder","onScrollEnd","onScrollStart","initialScrollWidth","scrollAnimationDuration","textDirection","extremeScrollLeft","offsetWidth","startScrollLeft","remappedStartScrollLeft","endScrollLeft","diff","abs","startTime","scroll","time","elapsed","min","currentScrollLeft","scrollEnd","max","requestAnimationFrame","shift","length","HorizontalScroll","children","getScrollToLeft","getScrollToRight","showArrows","arrowSize","arrowOffsetY","getRef","scrollOnAnyWheel","prevButtonTestId","nextButtonTestId","ContentWrapperComponent","contentWrapperRef","contentWrapperClassName","restProps","canScrollStart","setCanScrollStart","useState","canScrollEnd","setCanScrollEnd","direction","isRtl","isCustomScrollingRef","useRef","scrollerRef","hasPointer","scrollTo","useCallback","current","push","firstElementChild","scrollWidth","scrollToStart","i","scrollToEnd","calculateArrowsVisibility","useEffect","addWheelEventHandler","scrollEl","onWheel","e","scrollBy","left","deltaX","deltaY","behavior","preventDefault","listenerOptions","passive","addEventListener","removeEventListener","baseClassName","onMouseEnter","undefined","data-testid","size","offsetY","aria-hidden","tabIndex","className","onClick","div","ref"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/components/HorizontalScroll/HorizontalScroll.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { classNames, noop } from '@vkontakte/vkjs';\nimport { useAdaptivityHasPointer } from '../../hooks/useAdaptivityHasPointer';\nimport { useConfigDirection } from '../../hooks/useConfigDirection';\nimport { useExternRef } from '../../hooks/useExternRef';\nimport { useFocusVisible } from '../../hooks/useFocusVisible';\nimport { useFocusVisibleClassName } from '../../hooks/useFocusVisibleClassName';\nimport { easeInOutSine } from '../../lib/fx';\nimport { useIsomorphicLayoutEffect } from '../../lib/useIsomorphicLayoutEffect';\nimport type { HasRef, HTMLAttributesWithRootRef } from '../../types';\nimport { RootComponent } from '../RootComponent/RootComponent';\nimport { ScrollArrow, type ScrollArrowProps } from '../ScrollArrow/ScrollArrow';\nimport styles from './HorizontalScroll.module.css';\n\n/* eslint-disable jsdoc/require-jsdoc */\ninterface ScrollContext {\n scrollElement: HTMLElement | null;\n scrollAnimationDuration: number;\n animationQueue: VoidFunction[];\n getScrollPosition: (currentPosition: number) => number;\n onScrollToEndBorder: VoidFunction;\n onScrollEnd: VoidFunction;\n onScrollStart: VoidFunction;\n /**\n * Начальная ширина прокрутки.\n * В некоторых случаях может отличаться от текущей ширины прокрутки из-за transforms: translate.\n */\n initialScrollWidth: number;\n textDirection: 'ltr' | 'rtl';\n}\n/* eslint-enable jsdoc/require-jsdoc */\n\nexport type ScrollPositionHandler = (currentPosition: number) => number;\n\nexport interface HorizontalScrollProps\n extends HTMLAttributesWithRootRef<HTMLDivElement>,\n HasRef<HTMLDivElement> {\n /**\n * Функция для расчета величины прокрутки при нажатии на левую стрелку.\n */\n getScrollToLeft?: ScrollPositionHandler;\n /**\n * Функция для расчета величины прокрутки при нажатии на правую стрелку.\n */\n getScrollToRight?: ScrollPositionHandler;\n /**\n * Размер стрелок.\n */\n arrowSize?: ScrollArrowProps['size'];\n /**\n * Смещает иконки кнопок навигации по вертикали.\n */\n arrowOffsetY?: number | string;\n /**\n * Показывать ли стрелки.\n */\n showArrows?: boolean | 'always';\n /**\n * Длительность анимации скролла.\n */\n scrollAnimationDuration?: number;\n /**\n * Добавляет возможность прокручивать контент на любое колесо мыши.\n * По умолчанию прокручивается как любой горизонтальный контент через shift.\n */\n scrollOnAnyWheel?: boolean;\n /**\n * Передает атрибут `data-testid` для кнопки прокрутки горизонтального скролла в направлении предыдущего элемента.\n */\n prevButtonTestId?: string;\n /**\n * Передает атрибут `data-testid` для кнопки прокрутки горизонтального скролла в направлении следующего элемента.\n */\n nextButtonTestId?: string;\n /**\n * Позволяет поменять тег используемый для обертки над контентом, прокинутым в `children`.\n */\n ContentWrapperComponent?: React.ElementType;\n /**\n * `ref` для обертки над контентом, прокинутым в `children`.\n */\n contentWrapperRef?: React.Ref<HTMLElement>;\n /**\n * Специфичный `className` для обертки над контентом, прокинутым в `children`.\n */\n contentWrapperClassName?: string;\n}\n\n/**\n * Timing method.\n */\nfunction now() {\n return performance && performance.now ? performance.now() : Date.now();\n}\n\n/**\n * Округление к большему по модулю.\n *\n * ## Пример\n *\n * ```ts\n * import { strict as assert } from 'node:assert';\n *\n * assert.equal(roundingAwayFromZero(5.1), 6)\n * assert.equal(roundingAwayFromZero(-5.1), -6)\n * ```\n */\nfunction roundingAwayFromZero(value: number): number {\n return value > 0 ? Math.ceil(value) : Math.floor(value);\n}\n\n/**\n * Округляем el.scrollLeft\n * https://github.com/VKCOM/VKUI/pull/2445.\n */\nconst roundUpElementScrollLeft = (el: HTMLElement) => roundingAwayFromZero(el.scrollLeft);\n\n/**\n * Код анимации скрола, на основе полифила: https://github.com/iamdustan/smoothscroll\n * Константа взята из полифила (468), на дизайн-ревью уточнили до 250.\n * @var {number} SCROLL_ONE_FRAME_TIME время анимации скролла\n */\nconst SCROLL_ONE_FRAME_TIME = 250;\n\nfunction doScroll({\n scrollElement,\n getScrollPosition,\n animationQueue,\n onScrollToEndBorder,\n onScrollEnd,\n onScrollStart,\n initialScrollWidth,\n scrollAnimationDuration,\n textDirection,\n}: ScrollContext) {\n if (!scrollElement || !getScrollPosition) {\n return;\n }\n\n /**\n * Крайнее значение сдвига.\n */\n const extremeScrollLeft =\n (textDirection === 'ltr' ? 1 : -1) * (initialScrollWidth - scrollElement.offsetWidth);\n\n const startScrollLeft = roundUpElementScrollLeft(scrollElement);\n const remappedStartScrollLeft = startScrollLeft * (textDirection === 'rtl' ? -1 : 1);\n\n let endScrollLeft = getScrollPosition(remappedStartScrollLeft);\n\n const diff = endScrollLeft - remappedStartScrollLeft;\n if (textDirection === 'rtl') {\n endScrollLeft = startScrollLeft - diff;\n }\n\n onScrollStart();\n\n /**\n * Если окончание прокрутки вышло за ноль.\n */\n if (startScrollLeft * endScrollLeft < 0) {\n endScrollLeft = 0;\n }\n\n if (Math.abs(endScrollLeft) >= Math.abs(extremeScrollLeft)) {\n onScrollToEndBorder();\n endScrollLeft = extremeScrollLeft;\n }\n\n const startTime = now();\n\n (function scroll() {\n const time = now();\n const elapsed = Math.min((time - startTime) / scrollAnimationDuration, 1);\n\n const value = easeInOutSine(elapsed);\n\n const currentScrollLeft = startScrollLeft + (endScrollLeft - startScrollLeft) * value;\n scrollElement.scrollLeft = roundingAwayFromZero(currentScrollLeft);\n\n const scrollEnd =\n textDirection === 'ltr' ? Math.max(0, endScrollLeft) : Math.min(0, endScrollLeft);\n if (roundUpElementScrollLeft(scrollElement) !== scrollEnd && elapsed !== 1) {\n requestAnimationFrame(scroll);\n return;\n }\n\n onScrollEnd();\n animationQueue.shift();\n if (animationQueue.length > 0) {\n animationQueue[0]();\n }\n })();\n}\n\n/**\n * @see https://vkui.io/components/horizontal-scroll\n */\nexport const HorizontalScroll = ({\n children,\n getScrollToLeft,\n getScrollToRight,\n showArrows = true,\n arrowSize = 'm',\n arrowOffsetY,\n scrollAnimationDuration = SCROLL_ONE_FRAME_TIME,\n getRef,\n scrollOnAnyWheel = false,\n prevButtonTestId,\n nextButtonTestId,\n // ContentWrapper\n ContentWrapperComponent = 'div',\n contentWrapperRef,\n contentWrapperClassName,\n ...restProps\n}: HorizontalScrollProps): React.ReactNode => {\n const [canScrollStart, setCanScrollStart] = React.useState(false);\n const [canScrollEnd, setCanScrollEnd] = React.useState(false);\n const { focusVisible, ...focusEvents } = useFocusVisible();\n const focusVisibleClassNames = useFocusVisibleClassName({\n focusVisible,\n });\n\n const direction = useConfigDirection();\n const isRtl = direction === 'rtl';\n\n const isCustomScrollingRef = React.useRef(false);\n\n const scrollerRef = useExternRef(getRef);\n\n const animationQueue = React.useRef<VoidFunction[]>([]);\n\n const hasPointer = useAdaptivityHasPointer();\n\n const scrollTo = React.useCallback(\n (getScrollPosition: ScrollPositionHandler) => {\n const scrollElement = scrollerRef.current;\n\n animationQueue.current.push(() =>\n doScroll({\n scrollElement,\n getScrollPosition,\n animationQueue: animationQueue.current,\n onScrollToEndBorder: () => setCanScrollEnd(false),\n onScrollEnd: () => (isCustomScrollingRef.current = false),\n onScrollStart: () => (isCustomScrollingRef.current = true),\n initialScrollWidth: scrollElement?.firstElementChild?.scrollWidth || 0,\n scrollAnimationDuration,\n textDirection: direction,\n }),\n );\n if (animationQueue.current.length === 1) {\n animationQueue.current[0]();\n }\n },\n [scrollerRef, scrollAnimationDuration, direction, setCanScrollEnd],\n );\n\n const scrollToStart = React.useCallback(() => {\n const getScrollPosition =\n getScrollToLeft ?? ((i: number) => i - scrollerRef.current!.offsetWidth);\n scrollTo(getScrollPosition);\n }, [getScrollToLeft, scrollTo, scrollerRef]);\n\n const scrollToEnd = React.useCallback(() => {\n const getScrollPosition =\n getScrollToRight ?? ((i: number) => i + scrollerRef.current!.offsetWidth);\n scrollTo(getScrollPosition);\n }, [getScrollToRight, scrollTo, scrollerRef]);\n\n const calculateArrowsVisibility = React.useCallback(() => {\n if (showArrows && hasPointer && scrollerRef.current && !isCustomScrollingRef.current) {\n const scrollElement = scrollerRef.current;\n const scrollLeft = scrollElement.scrollLeft;\n\n setCanScrollStart(isRtl ? scrollLeft < 0 : scrollLeft > 0);\n setCanScrollEnd(\n Math.abs(roundUpElementScrollLeft(scrollElement)) + scrollElement.offsetWidth <\n scrollElement.scrollWidth,\n );\n }\n }, [showArrows, hasPointer, scrollerRef, isRtl]);\n\n React.useEffect(calculateArrowsVisibility, [calculateArrowsVisibility, children]);\n\n useIsomorphicLayoutEffect(\n function addWheelEventHandler() {\n const scrollEl = scrollerRef.current;\n if (!scrollEl) {\n return noop;\n }\n /**\n * Прокрутка с помощью любого колеса мыши.\n */\n const onWheel = (e: WheelEvent) => {\n scrollerRef.current!.scrollBy({ left: e.deltaX + e.deltaY, behavior: 'auto' });\n e.preventDefault();\n };\n\n const listenerOptions = { passive: false };\n\n if (scrollOnAnyWheel) {\n scrollEl.addEventListener('wheel', onWheel, listenerOptions);\n }\n scrollEl.addEventListener('scroll', calculateArrowsVisibility, listenerOptions);\n\n return () => {\n if (scrollOnAnyWheel) {\n // @ts-expect-error: TS2769 В интерфейсе EventListenerOptions для wheel нет passive свойства\n scrollEl.removeEventListener('wheel', onWheel, listenerOptions);\n }\n // @ts-expect-error: TS2769 В интерфейсе EventListenerOptions для scroll нет passive свойства\n scrollEl.removeEventListener('scroll', calculateArrowsVisibility, listenerOptions);\n };\n },\n [scrollOnAnyWheel, calculateArrowsVisibility, scrollerRef],\n );\n\n return (\n <RootComponent\n {...restProps}\n baseClassName={classNames(\n styles.host,\n 'vkuiInternalHorizontalScroll',\n showArrows === 'always' && styles.withConstArrows,\n isRtl && styles.rtl,\n )}\n onMouseEnter={calculateArrowsVisibility}\n >\n {showArrows && (hasPointer || hasPointer === undefined) && canScrollStart && (\n <ScrollArrow\n data-testid={prevButtonTestId}\n size={arrowSize}\n offsetY={arrowOffsetY}\n direction=\"left\"\n aria-hidden\n tabIndex={-1}\n className={classNames(styles.arrow, styles.arrowLeft)}\n onClick={scrollToStart}\n />\n )}\n {showArrows && (hasPointer || hasPointer === undefined) && canScrollEnd && (\n <ScrollArrow\n data-testid={nextButtonTestId}\n size={arrowSize}\n offsetY={arrowOffsetY}\n direction=\"right\"\n aria-hidden\n tabIndex={-1}\n className={classNames(styles.arrow, styles.arrowRight)}\n onClick={scrollToEnd}\n />\n )}\n <div\n className={classNames(styles.in, focusVisibleClassNames)}\n ref={scrollerRef}\n tabIndex={0}\n {...focusEvents}\n >\n <ContentWrapperComponent\n className={classNames(styles.inWrapper, contentWrapperClassName)}\n ref={contentWrapperRef}\n >\n {children}\n </ContentWrapperComponent>\n </div>\n </RootComponent>\n );\n};\n"],"names":["React","classNames","noop","useAdaptivityHasPointer","useConfigDirection","useExternRef","useFocusVisible","useFocusVisibleClassName","easeInOutSine","useIsomorphicLayoutEffect","RootComponent","ScrollArrow","now","performance","Date","roundingAwayFromZero","value","Math","ceil","floor","roundUpElementScrollLeft","el","scrollLeft","SCROLL_ONE_FRAME_TIME","doScroll","scrollElement","getScrollPosition","animationQueue","onScrollToEndBorder","onScrollEnd","onScrollStart","initialScrollWidth","scrollAnimationDuration","textDirection","extremeScrollLeft","offsetWidth","startScrollLeft","remappedStartScrollLeft","endScrollLeft","diff","abs","startTime","scroll","time","elapsed","min","currentScrollLeft","scrollEnd","max","requestAnimationFrame","shift","length","HorizontalScroll","children","getScrollToLeft","getScrollToRight","showArrows","arrowSize","arrowOffsetY","getRef","scrollOnAnyWheel","prevButtonTestId","nextButtonTestId","ContentWrapperComponent","contentWrapperRef","contentWrapperClassName","restProps","canScrollStart","setCanScrollStart","useState","canScrollEnd","setCanScrollEnd","focusVisible","focusEvents","focusVisibleClassNames","direction","isRtl","isCustomScrollingRef","useRef","scrollerRef","hasPointer","scrollTo","useCallback","current","push","firstElementChild","scrollWidth","scrollToStart","i","scrollToEnd","calculateArrowsVisibility","useEffect","addWheelEventHandler","scrollEl","onWheel","e","scrollBy","left","deltaX","deltaY","behavior","preventDefault","listenerOptions","passive","addEventListener","removeEventListener","baseClassName","onMouseEnter","undefined","data-testid","size","offsetY","aria-hidden","tabIndex","className","onClick","div","ref"],"mappings":"AAAA;;;;;AAEA,YAAYA,WAAW,QAAQ;AAC/B,SAASC,UAAU,EAAEC,IAAI,QAAQ,kBAAkB;AACnD,SAASC,uBAAuB,QAAQ,yCAAsC;AAC9E,SAASC,kBAAkB,QAAQ,oCAAiC;AACpE,SAASC,YAAY,QAAQ,8BAA2B;AACxD,SAASC,eAAe,QAAQ,iCAA8B;AAC9D,SAASC,wBAAwB,QAAQ,0CAAuC;AAChF,SAASC,aAAa,QAAQ,kBAAe;AAC7C,SAASC,yBAAyB,QAAQ,yCAAsC;AAEhF,SAASC,aAAa,QAAQ,oCAAiC;AAC/D,SAASC,WAAW,QAA+B,gCAA6B;AA6EhF;;CAEC,GACD,SAASC;IACP,OAAOC,eAAeA,YAAYD,GAAG,GAAGC,YAAYD,GAAG,KAAKE,KAAKF,GAAG;AACtE;AAEA;;;;;;;;;;;CAWC,GACD,SAASG,qBAAqBC,KAAa;IACzC,OAAOA,QAAQ,IAAIC,KAAKC,IAAI,CAACF,SAASC,KAAKE,KAAK,CAACH;AACnD;AAEA;;;CAGC,GACD,MAAMI,2BAA2B,CAACC,KAAoBN,qBAAqBM,GAAGC,UAAU;AAExF;;;;CAIC,GACD,MAAMC,wBAAwB;AAE9B,SAASC,SAAS,EAChBC,aAAa,EACbC,iBAAiB,EACjBC,cAAc,EACdC,mBAAmB,EACnBC,WAAW,EACXC,aAAa,EACbC,kBAAkB,EAClBC,uBAAuB,EACvBC,aAAa,EACC;IACd,IAAI,CAACR,iBAAiB,CAACC,mBAAmB;QACxC;IACF;IAEA;;GAEC,GACD,MAAMQ,oBACJ,AAACD,CAAAA,kBAAkB,QAAQ,IAAI,CAAC,CAAA,IAAMF,CAAAA,qBAAqBN,cAAcU,WAAW,AAAD;IAErF,MAAMC,kBAAkBhB,yBAAyBK;IACjD,MAAMY,0BAA0BD,kBAAmBH,CAAAA,kBAAkB,QAAQ,CAAC,IAAI,CAAA;IAElF,IAAIK,gBAAgBZ,kBAAkBW;IAEtC,MAAME,OAAOD,gBAAgBD;IAC7B,IAAIJ,kBAAkB,OAAO;QAC3BK,gBAAgBF,kBAAkBG;IACpC;IAEAT;IAEA;;GAEC,GACD,IAAIM,kBAAkBE,gBAAgB,GAAG;QACvCA,gBAAgB;IAClB;IAEA,IAAIrB,KAAKuB,GAAG,CAACF,kBAAkBrB,KAAKuB,GAAG,CAACN,oBAAoB;QAC1DN;QACAU,gBAAgBJ;IAClB;IAEA,MAAMO,YAAY7B;IAEjB,CAAA,SAAS8B;QACR,MAAMC,OAAO/B;QACb,MAAMgC,UAAU3B,KAAK4B,GAAG,CAAC,AAACF,CAAAA,OAAOF,SAAQ,IAAKT,yBAAyB;QAEvE,MAAMhB,QAAQR,cAAcoC;QAE5B,MAAME,oBAAoBV,kBAAkB,AAACE,CAAAA,gBAAgBF,eAAc,IAAKpB;QAChFS,cAAcH,UAAU,GAAGP,qBAAqB+B;QAEhD,MAAMC,YACJd,kBAAkB,QAAQhB,KAAK+B,GAAG,CAAC,GAAGV,iBAAiBrB,KAAK4B,GAAG,CAAC,GAAGP;QACrE,IAAIlB,yBAAyBK,mBAAmBsB,aAAaH,YAAY,GAAG;YAC1EK,sBAAsBP;YACtB;QACF;QAEAb;QACAF,eAAeuB,KAAK;QACpB,IAAIvB,eAAewB,MAAM,GAAG,GAAG;YAC7BxB,cAAc,CAAC,EAAE;QACnB;IACF,CAAA;AACF;AAEA;;CAEC,GACD,OAAO,MAAMyB,mBAAmB;QAAC,EAC/BC,QAAQ,EACRC,eAAe,EACfC,gBAAgB,EAChBC,aAAa,IAAI,EACjBC,YAAY,GAAG,EACfC,YAAY,EACZ1B,0BAA0BT,qBAAqB,EAC/CoC,MAAM,EACNC,mBAAmB,KAAK,EACxBC,gBAAgB,EAChBC,gBAAgB,EAChB,iBAAiB;IACjBC,0BAA0B,KAAK,EAC/BC,iBAAiB,EACjBC,uBAAuB,EAED,WADnBC;QAfHb;QACAC;QACAC;QACAC;QACAC;QACAC;QACA1B;QACA2B;QACAC;QACAC;QACAC;QAEAC;QACAC;QACAC;;IAGA,MAAM,CAACE,gBAAgBC,kBAAkB,GAAGpE,MAAMqE,QAAQ,CAAC;IAC3D,MAAM,CAACC,cAAcC,gBAAgB,GAAGvE,MAAMqE,QAAQ,CAAC;IACvD,MAAyC/D,mBAAAA,mBAAnC,EAAEkE,YAAY,EAAkB,GAAGlE,kBAAhBmE,yCAAgBnE;QAAjCkE;;IACR,MAAME,yBAAyBnE,yBAAyB;QACtDiE;IACF;IAEA,MAAMG,YAAYvE;IAClB,MAAMwE,QAAQD,cAAc;IAE5B,MAAME,uBAAuB7E,MAAM8E,MAAM,CAAC;IAE1C,MAAMC,cAAc1E,aAAasD;IAEjC,MAAMhC,iBAAiB3B,MAAM8E,MAAM,CAAiB,EAAE;IAEtD,MAAME,aAAa7E;IAEnB,MAAM8E,WAAWjF,MAAMkF,WAAW,CAChC,CAACxD;QACC,MAAMD,gBAAgBsD,YAAYI,OAAO;QAEzCxD,eAAewD,OAAO,CAACC,IAAI,CAAC;gBAQJ3D;mBAPtBD,SAAS;gBACPC;gBACAC;gBACAC,gBAAgBA,eAAewD,OAAO;gBACtCvD,qBAAqB,IAAM2C,gBAAgB;gBAC3C1C,aAAa,IAAOgD,qBAAqBM,OAAO,GAAG;gBACnDrD,eAAe,IAAO+C,qBAAqBM,OAAO,GAAG;gBACrDpD,oBAAoBN,CAAAA,0BAAAA,qCAAAA,mCAAAA,cAAe4D,iBAAiB,cAAhC5D,uDAAAA,iCAAkC6D,WAAW,KAAI;gBACrEtD;gBACAC,eAAe0C;YACjB;;QAEF,IAAIhD,eAAewD,OAAO,CAAChC,MAAM,KAAK,GAAG;YACvCxB,eAAewD,OAAO,CAAC,EAAE;QAC3B;IACF,GACA;QAACJ;QAAa/C;QAAyB2C;QAAWJ;KAAgB;IAGpE,MAAMgB,gBAAgBvF,MAAMkF,WAAW,CAAC;QACtC,MAAMxD,oBACJ4B,4BAAAA,6BAAAA,kBAAoB,CAACkC,IAAcA,IAAIT,YAAYI,OAAO,CAAEhD,WAAW;QACzE8C,SAASvD;IACX,GAAG;QAAC4B;QAAiB2B;QAAUF;KAAY;IAE3C,MAAMU,cAAczF,MAAMkF,WAAW,CAAC;QACpC,MAAMxD,oBACJ6B,6BAAAA,8BAAAA,mBAAqB,CAACiC,IAAcA,IAAIT,YAAYI,OAAO,CAAEhD,WAAW;QAC1E8C,SAASvD;IACX,GAAG;QAAC6B;QAAkB0B;QAAUF;KAAY;IAE5C,MAAMW,4BAA4B1F,MAAMkF,WAAW,CAAC;QAClD,IAAI1B,cAAcwB,cAAcD,YAAYI,OAAO,IAAI,CAACN,qBAAqBM,OAAO,EAAE;YACpF,MAAM1D,gBAAgBsD,YAAYI,OAAO;YACzC,MAAM7D,aAAaG,cAAcH,UAAU;YAE3C8C,kBAAkBQ,QAAQtD,aAAa,IAAIA,aAAa;YACxDiD,gBACEtD,KAAKuB,GAAG,CAACpB,yBAAyBK,kBAAkBA,cAAcU,WAAW,GAC3EV,cAAc6D,WAAW;QAE/B;IACF,GAAG;QAAC9B;QAAYwB;QAAYD;QAAaH;KAAM;IAE/C5E,MAAM2F,SAAS,CAACD,2BAA2B;QAACA;QAA2BrC;KAAS;IAEhF5C,0BACE,SAASmF;QACP,MAAMC,WAAWd,YAAYI,OAAO;QACpC,IAAI,CAACU,UAAU;YACb,OAAO3F;QACT;QACA;;OAEC,GACD,MAAM4F,UAAU,CAACC;YACfhB,YAAYI,OAAO,CAAEa,QAAQ,CAAC;gBAAEC,MAAMF,EAAEG,MAAM,GAAGH,EAAEI,MAAM;gBAAEC,UAAU;YAAO;YAC5EL,EAAEM,cAAc;QAClB;QAEA,MAAMC,kBAAkB;YAAEC,SAAS;QAAM;QAEzC,IAAI3C,kBAAkB;YACpBiC,SAASW,gBAAgB,CAAC,SAASV,SAASQ;QAC9C;QACAT,SAASW,gBAAgB,CAAC,UAAUd,2BAA2BY;QAE/D,OAAO;YACL,IAAI1C,kBAAkB;gBACpB,4FAA4F;gBAC5FiC,SAASY,mBAAmB,CAAC,SAASX,SAASQ;YACjD;YACA,6FAA6F;YAC7FT,SAASY,mBAAmB,CAAC,UAAUf,2BAA2BY;QACpE;IACF,GACA;QAAC1C;QAAkB8B;QAA2BX;KAAY;IAG5D,qBACE,MAACrE,uDACKwD;QACJwC,eAAezG,yCAEb,gCACAuD,eAAe,qDACfoB;QAEF+B,cAAcjB;;YAEblC,cAAewB,CAAAA,cAAcA,eAAe4B,SAAQ,KAAMzC,gCACzD,KAACxD;gBACCkG,eAAahD;gBACbiD,MAAMrD;gBACNsD,SAASrD;gBACTiB,WAAU;gBACVqC,aAAW;gBACXC,UAAU,CAAC;gBACXC,WAAWjH;gBACXkH,SAAS5B;;YAGZ/B,cAAewB,CAAAA,cAAcA,eAAe4B,SAAQ,KAAMtC,8BACzD,KAAC3D;gBACCkG,eAAa/C;gBACbgD,MAAMrD;gBACNsD,SAASrD;gBACTiB,WAAU;gBACVqC,aAAW;gBACXC,UAAU,CAAC;gBACXC,WAAWjH;gBACXkH,SAAS1B;;0BAGb,KAAC2B;gBACCF,WAAWjH,uCAAsByE;gBACjC2C,KAAKtC;gBACLkC,UAAU;eACNxC;0BAEJ,cAAA,KAACV;oBACCmD,WAAWjH,8CAA6BgE;oBACxCoD,KAAKrD;8BAEJX;;;;;AAKX,EAAE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ImageBase.d.ts","sourceRoot":"","sources":["../../../src/components/ImageBase/ImageBase.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAO/B,OAAO,KAAK,EACV,wBAAwB,EAExB,MAAM,EACN,UAAU,EACV,YAAY,EACb,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,cAAc,EAAE,KAAK,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAC3F,OAAO,EACL,KAAK,uBAAuB,EAC5B,KAAK,qBAAqB,EAC1B,qBAAqB,EACrB,KAAK,0BAA0B,EAChC,MAAM,+CAA+C,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,KAAK,qBAAqB,EAAE,MAAM,qCAAqC,CAAC;AACnG,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,KAAK,EAAE,qBAAqB,EAAE,0BAA0B,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAIhG,YAAY,EACV,aAAa,EACb,0BAA0B,EAC1B,mBAAmB,EACnB,qBAAqB,EACrB,qBAAqB,EACrB,0BAA0B,EAC1B,qBAAqB,EACrB,uBAAuB,GACxB,CAAC;AAEF,OAAO,EACL,+BAA+B,EAC/B,kCAAkC,EAClC,iCAAiC,GAClC,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,gBAAgB,EAAE,CAAC;AAO5B,MAAM,WAAW,cACf,SAAQ,KAAK,CAAC,iBAAiB,CAAC,WAAW,CAAC,EAC1C,wBAAwB,EACxB,UAAU,CAAC,cAAc,CAAC,EAC1B,MAAM,CAAC,gBAAgB,CAAC;IAC1B;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,YAAY,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;IAC3C;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5B;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC7B;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;;;;;;;;;OAYG;IACH,YAAY,CAAC,EAAE,KAAK,CAAC,YAAY,CAAC,0BAA0B,CAAC,CAAC;IAC9D;;;OAGG;IACH,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC;;;OAGG;IACH,SAAS,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;IAC7C;;;OAGG;IACH,cAAc,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAAC;IACvD;;;OAGG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,MAAM,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;CACxC;AA8BD;;GAEG;AACH,eAAO,MAAM,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC,cAAc,CAAC,GAAG;IACjD,KAAK,EAAE,OAAO,cAAc,CAAC;IAC7B,OAAO,EAAE,OAAO,gBAAgB,CAAC;IACjC,YAAY,EAAE,OAAO,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"ImageBase.d.ts","sourceRoot":"","sources":["../../../src/components/ImageBase/ImageBase.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAO/B,OAAO,KAAK,EACV,wBAAwB,EAExB,MAAM,EACN,UAAU,EACV,YAAY,EACb,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,cAAc,EAAE,KAAK,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAC3F,OAAO,EACL,KAAK,uBAAuB,EAC5B,KAAK,qBAAqB,EAC1B,qBAAqB,EACrB,KAAK,0BAA0B,EAChC,MAAM,+CAA+C,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,KAAK,qBAAqB,EAAE,MAAM,qCAAqC,CAAC;AACnG,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,KAAK,EAAE,qBAAqB,EAAE,0BAA0B,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAIhG,YAAY,EACV,aAAa,EACb,0BAA0B,EAC1B,mBAAmB,EACnB,qBAAqB,EACrB,qBAAqB,EACrB,0BAA0B,EAC1B,qBAAqB,EACrB,uBAAuB,GACxB,CAAC;AAEF,OAAO,EACL,+BAA+B,EAC/B,kCAAkC,EAClC,iCAAiC,GAClC,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,gBAAgB,EAAE,CAAC;AAO5B,MAAM,WAAW,cACf,SAAQ,KAAK,CAAC,iBAAiB,CAAC,WAAW,CAAC,EAC1C,wBAAwB,EACxB,UAAU,CAAC,cAAc,CAAC,EAC1B,MAAM,CAAC,gBAAgB,CAAC;IAC1B;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,YAAY,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;IAC3C;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5B;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC7B;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;;;;;;;;;OAYG;IACH,YAAY,CAAC,EAAE,KAAK,CAAC,YAAY,CAAC,0BAA0B,CAAC,CAAC;IAC9D;;;OAGG;IACH,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC;;;OAGG;IACH,SAAS,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;IAC7C;;;OAGG;IACH,cAAc,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAAC;IACvD;;;OAGG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,MAAM,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;CACxC;AA8BD;;GAEG;AACH,eAAO,MAAM,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC,cAAc,CAAC,GAAG;IACjD,KAAK,EAAE,OAAO,cAAc,CAAC;IAC7B,OAAO,EAAE,OAAO,gBAAgB,CAAC;IACjC,YAAY,EAAE,OAAO,qBAAqB,CAAC;CA2K5C,CAAC"}
|
|
@@ -92,11 +92,10 @@ const sizeToNumber = (size)=>{
|
|
|
92
92
|
const mouseOverHandlersRef = useRef([]);
|
|
93
93
|
const mouseOutHandlersRef = useRef([]);
|
|
94
94
|
const hasSrc = src || srcSet;
|
|
95
|
-
const
|
|
96
|
-
const fallbackIcon = needShowFallbackIcon ? fallbackIconProp : null;
|
|
95
|
+
const fallbackIcon = failed || !hasSrc ? fallbackIconProp : null;
|
|
97
96
|
if (process.env.NODE_ENV === 'development') {
|
|
98
97
|
validateSize(size);
|
|
99
|
-
if (fallbackIcon) {
|
|
98
|
+
if (/*#__PURE__*/ React.isValidElement(fallbackIcon)) {
|
|
100
99
|
validateFallbackIcon(size, {
|
|
101
100
|
name: 'fallbackIcon',
|
|
102
101
|
value: fallbackIcon
|
|
@@ -168,7 +167,7 @@ const sizeToNumber = (size)=>{
|
|
|
168
167
|
hasSrc && /*#__PURE__*/ _jsx("img", _object_spread({
|
|
169
168
|
ref: imgRef,
|
|
170
169
|
alt: alt,
|
|
171
|
-
className: classNames("vkuiImageBase__img", getObjectFitClassName(objectFit), objectPosition && "vkuiImageBase__withObjectPosition", filter && "vkuiImageBase__withFilter", keepAspectRatio && "vkuiImageBase__imgKeepRatio"),
|
|
170
|
+
className: classNames("vkuiImageBase__img", getObjectFitClassName(objectFit), objectPosition && "vkuiImageBase__withObjectPosition", filter && "vkuiImageBase__withFilter", keepAspectRatio && "vkuiImageBase__imgKeepRatio", failed && "vkuiImageBase__imgHiddenAlt"),
|
|
172
171
|
crossOrigin: crossOrigin,
|
|
173
172
|
decoding: decoding,
|
|
174
173
|
loading: loading,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/ImageBase/ImageBase.tsx"],"sourcesContent":["'use client';\n\nimport { useRef } from 'react';\nimport * as React from 'react';\nimport { classNames } from '@vkontakte/vkjs';\nimport { mergeStyle } from '../../helpers/mergeStyle';\nimport { useExternRef } from '../../hooks/useExternRef';\nimport { minOr } from '../../lib/comparing';\nimport { defineComponentDisplayNames } from '../../lib/react/defineComponentDisplayNames';\nimport { getFetchPriorityProp } from '../../lib/utils';\nimport type {\n AnchorHTMLAttributesOnly,\n CSSCustomProperties,\n HasRef,\n HasRootRef,\n LiteralUnion,\n} from '../../types';\nimport { Clickable } from '../Clickable/Clickable';\nimport { ImageBaseBadge, type ImageBaseBadgeProps } from './ImageBaseBadge/ImageBaseBadge';\nimport {\n type FloatElementIndentation,\n type FloatElementPlacement,\n ImageBaseFloatElement,\n type ImageBaseFloatElementProps,\n} from './ImageBaseFloatElement/ImageBaseFloatElement';\nimport { ImageBaseOverlay, type ImageBaseOverlayProps } from './ImageBaseOverlay/ImageBaseOverlay';\nimport { ImageBaseContext } from './context';\nimport type { ImageBaseContextProps, ImageBaseExpectedIconProps, ImageBaseSize } from './types';\nimport { validateFallbackIcon, validateSize } from './validators';\nimport styles from './ImageBase.module.css';\n\nexport type {\n ImageBaseSize,\n ImageBaseExpectedIconProps,\n ImageBaseBadgeProps,\n ImageBaseOverlayProps,\n ImageBaseContextProps,\n ImageBaseFloatElementProps,\n FloatElementPlacement,\n FloatElementIndentation,\n};\n\nexport {\n getBadgeIconSizeByImageBaseSize,\n getFallbackIconSizeByImageBaseSize,\n getOverlayIconSizeByImageBaseSize,\n} from './helpers';\n\nexport { ImageBaseContext };\n\n/**\n * Размер по умолчанию.\n */\nconst defaultSize = 24;\n\nexport interface ImageBaseProps\n extends React.ImgHTMLAttributes<HTMLElement>,\n AnchorHTMLAttributesOnly,\n HasRootRef<HTMLDivElement>,\n HasRef<HTMLImageElement> {\n /**\n * Задаёт размер картинки.\n *\n * Используйте размеры заданные дизайн-системой `16 | 20 | 24 | 28 | 32 | 36 | 40 | 44 | 48 | 56 | 64 | 72 | 80 | 88 | 96`.\n *\n * > ⚠️ Использование кастомного размера – это пограничный кейс.\n */\n size?: LiteralUnion<ImageBaseSize, number>;\n /**\n * Ширина изображения.\n */\n widthSize?: number | string;\n /**\n * Высота изображения.\n */\n heightSize?: number | string;\n /**\n * Отключает обводку.\n */\n noBorder?: boolean;\n /**\n * Фолбек на случай, если картинка не прогрузилась.\n *\n * > 📝 Нужный для `<ImageBase size={...} />` размер можно узнать из функции `getFallbackIconSizeByImageBaseSize()`.\n *\n * > Предпочтительней использовать иконки из `@vkontakte/icons`.\n *\n * > 📊️ Если вы хотите передать кастомную иконку, то следует именовать её по шаблону `Icon<size><name>`. Или же\n * > чтобы в неё был передан параметр `width`. Тогда мы сможем выводить в консоль подсказку правильного ли размера вы\n * > использовали иконку.\n *\n * > ⚠️ Может перекрывать `children`.\n */\n fallbackIcon?: React.ReactElement<ImageBaseExpectedIconProps>;\n /**\n * Отключает фон, заданный по умолчанию. Полезен для отображения картинок с прозрачностью.\n * @since 5.10.0\n */\n withTransparentBackground?: boolean;\n /**\n * Пользовательское значения стиля object-fit\n * Подробнее можно почитать в [документации](https://developer.mozilla.org/ru/docs/Web/CSS/object-fit).\n */\n objectFit?: React.CSSProperties['objectFit'];\n /**\n * Пользовательское значения стиля object-position\n * Подробнее можно почитать в [документации](https://developer.mozilla.org/ru/docs/Web/CSS/object-position).\n */\n objectPosition?: React.CSSProperties['objectPosition'];\n /**\n * Флаг для сохранения пропорций картинки.\n * Для корректной работы необходимо задать размеры хотя бы одной стороны картинки.\n */\n keepAspectRatio?: boolean;\n /**\n * Смотри https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/elementtiming.\n */\n elementTiming?: string;\n /**\n * Пользовательское значения стиля filter\n * Подробнее можно почитать в [документации](https://developer.mozilla.org/ru/docs/Web/CSS/filter).\n */\n filter?: React.CSSProperties['filter'];\n}\n\nconst getObjectFitClassName = (objectFit: React.CSSProperties['objectFit']) => {\n switch (objectFit) {\n case 'contain':\n return styles.imgObjectFitContain;\n case 'cover':\n return styles.imgObjectFitCover;\n case 'none':\n return styles.imgObjectFitNone;\n case 'scale-down':\n return styles.imgObjectFitScaleDown;\n }\n return undefined;\n};\n\nconst parsePx = (value: string): number | undefined => {\n if (value.endsWith('px')) {\n return parseInt(value);\n }\n return undefined;\n};\n\nconst sizeToNumber = (size: number | string | undefined): number | undefined => {\n if (typeof size === 'string') {\n return parsePx(size);\n }\n return size;\n};\n\n/**\n * @see https://vkui.io/components/image-base\n */\nexport const ImageBase: React.FC<ImageBaseProps> & {\n Badge: typeof ImageBaseBadge;\n Overlay: typeof ImageBaseOverlay;\n FloatElement: typeof ImageBaseFloatElement;\n} = ({\n alt,\n crossOrigin,\n decoding,\n loading,\n referrerPolicy,\n sizes,\n src,\n srcSet,\n useMap,\n fetchPriority,\n getRef,\n size: sizeProp,\n width: widthImg,\n height: heightImg,\n widthSize,\n heightSize,\n noBorder = false,\n fallbackIcon: fallbackIconProp,\n children,\n onLoad,\n onError,\n withTransparentBackground,\n objectFit = 'cover',\n objectPosition,\n filter,\n keepAspectRatio = false,\n getRootRef,\n elementTiming,\n ...restProps\n}: ImageBaseProps) => {\n const size = sizeProp ?? minOr([sizeToNumber(widthSize), sizeToNumber(heightSize)], defaultSize);\n const wrapperRef = useExternRef(getRootRef);\n\n const width = widthSize ?? (keepAspectRatio ? undefined : size);\n const height = heightSize ?? (keepAspectRatio ? undefined : size);\n\n const [loaded, setLoaded] = React.useState(false);\n const [failed, setFailed] = React.useState(false);\n\n const mouseOverHandlersRef = useRef<VoidFunction[]>([]);\n const mouseOutHandlersRef = useRef<VoidFunction[]>([]);\n\n const hasSrc = src || srcSet;\n const needShowFallbackIcon = (failed || !hasSrc) && React.isValidElement(fallbackIconProp);\n\n const fallbackIcon = needShowFallbackIcon ? fallbackIconProp : null;\n\n if (process.env.NODE_ENV === 'development') {\n validateSize(size);\n if (fallbackIcon) {\n validateFallbackIcon(size, { name: 'fallbackIcon', value: fallbackIcon });\n }\n }\n\n const handleImageLoad = (event: React.SyntheticEvent<HTMLImageElement>) => {\n if (loaded) {\n return;\n }\n\n setLoaded(true);\n setFailed(false);\n onLoad?.(event);\n };\n\n const handleImageError = (event: React.SyntheticEvent<HTMLImageElement>) => {\n setLoaded(false);\n setFailed(true);\n onError?.(event);\n };\n\n const imgRef = useExternRef(getRef);\n const isOnLoadStatusCheckedRef = React.useRef(false);\n React.useEffect(\n function dispatchLoadEventForAlreadyLoadedResourceIfReactInitializedLater() {\n if (isOnLoadStatusCheckedRef.current) {\n return;\n }\n isOnLoadStatusCheckedRef.current = true;\n\n if (imgRef.current && imgRef.current.complete && !loaded) {\n const event = new Event('load');\n imgRef.current.dispatchEvent(event);\n }\n },\n [imgRef, loaded],\n );\n\n const onMouseOver = () => {\n mouseOverHandlersRef.current.forEach((fn) => fn());\n };\n\n const onMouseOut = () => {\n mouseOutHandlersRef.current.forEach((fn) => fn());\n };\n\n const contextValue = React.useMemo(\n () => ({\n size,\n onMouseOverHandlers: mouseOverHandlersRef.current,\n onMouseOutHandlers: mouseOutHandlersRef.current,\n }),\n [size],\n );\n\n const imgStyles:\n | CSSCustomProperties<React.CSSProperties['objectPosition'] | React.CSSProperties['filter']>\n | undefined =\n objectPosition || filter\n ? {\n '--vkui_internal--ImageBase_object_position': objectPosition,\n '--vkui_internal--ImageBase_object_filter': filter,\n }\n : undefined;\n\n const keepAspectRationStyles = keepAspectRatio\n ? {\n width: widthImg || width,\n height: heightImg || height,\n }\n : undefined;\n\n return (\n <ImageBaseContext.Provider value={contextValue}>\n <Clickable\n baseStyle={{ width, height }}\n baseClassName={classNames(\n styles.host,\n hasSrc && loaded && styles.loaded,\n withTransparentBackground && styles.transparentBackground,\n )}\n getRootRef={wrapperRef}\n onMouseOver={onMouseOver}\n onMouseOut={onMouseOut}\n {...restProps}\n >\n {hasSrc && (\n <img\n ref={imgRef}\n alt={alt}\n className={classNames(\n styles.img,\n getObjectFitClassName(objectFit),\n objectPosition && styles.withObjectPosition,\n filter && styles.withFilter,\n keepAspectRatio && styles.imgKeepRatio,\n )}\n crossOrigin={crossOrigin}\n decoding={decoding}\n loading={loading}\n referrerPolicy={referrerPolicy}\n style={mergeStyle(keepAspectRationStyles, imgStyles)}\n sizes={sizes}\n src={src}\n srcSet={srcSet}\n useMap={useMap}\n width={widthImg}\n height={heightImg}\n onLoad={handleImageLoad}\n onError={handleImageError}\n // @ts-expect-error: TS2322 отсутствует в @types/react\n elementtiming={elementTiming} // eslint-disable-line react/no-unknown-property\n {...getFetchPriorityProp(fetchPriority)}\n />\n )}\n {fallbackIcon && <div className={styles.fallback}>{fallbackIcon}</div>}\n {children && <div className={styles.children}>{children}</div>}\n {!noBorder && <div aria-hidden className={styles.border} />}\n </Clickable>\n </ImageBaseContext.Provider>\n );\n};\nImageBase.Badge = ImageBaseBadge;\nImageBase.Overlay = ImageBaseOverlay;\nImageBase.FloatElement = ImageBaseFloatElement;\n\nif (process.env.NODE_ENV !== 'production') {\n defineComponentDisplayNames(ImageBase.Badge, 'ImageBase.Badge');\n defineComponentDisplayNames(ImageBase.Overlay, 'ImageBase.Overlay');\n defineComponentDisplayNames(ImageBase.FloatElement, 'ImageBase.FloatElement');\n}\n"],"names":["useRef","React","classNames","mergeStyle","useExternRef","minOr","defineComponentDisplayNames","getFetchPriorityProp","Clickable","ImageBaseBadge","ImageBaseFloatElement","ImageBaseOverlay","ImageBaseContext","validateFallbackIcon","validateSize","getBadgeIconSizeByImageBaseSize","getFallbackIconSizeByImageBaseSize","getOverlayIconSizeByImageBaseSize","defaultSize","getObjectFitClassName","objectFit","undefined","parsePx","value","endsWith","parseInt","sizeToNumber","size","ImageBase","alt","crossOrigin","decoding","loading","referrerPolicy","sizes","src","srcSet","useMap","fetchPriority","getRef","sizeProp","width","widthImg","height","heightImg","widthSize","heightSize","noBorder","fallbackIcon","fallbackIconProp","children","onLoad","onError","withTransparentBackground","objectPosition","filter","keepAspectRatio","getRootRef","elementTiming","restProps","wrapperRef","loaded","setLoaded","useState","failed","setFailed","mouseOverHandlersRef","mouseOutHandlersRef","hasSrc","needShowFallbackIcon","isValidElement","process","env","NODE_ENV","name","handleImageLoad","event","handleImageError","imgRef","isOnLoadStatusCheckedRef","useEffect","dispatchLoadEventForAlreadyLoadedResourceIfReactInitializedLater","current","complete","Event","dispatchEvent","onMouseOver","forEach","fn","onMouseOut","contextValue","useMemo","onMouseOverHandlers","onMouseOutHandlers","imgStyles","keepAspectRationStyles","Provider","baseStyle","baseClassName","img","ref","className","style","elementtiming","div","aria-hidden","Badge","Overlay","FloatElement"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/components/ImageBase/ImageBase.tsx"],"sourcesContent":["'use client';\n\nimport { useRef } from 'react';\nimport * as React from 'react';\nimport { classNames } from '@vkontakte/vkjs';\nimport { mergeStyle } from '../../helpers/mergeStyle';\nimport { useExternRef } from '../../hooks/useExternRef';\nimport { minOr } from '../../lib/comparing';\nimport { defineComponentDisplayNames } from '../../lib/react/defineComponentDisplayNames';\nimport { getFetchPriorityProp } from '../../lib/utils';\nimport type {\n AnchorHTMLAttributesOnly,\n CSSCustomProperties,\n HasRef,\n HasRootRef,\n LiteralUnion,\n} from '../../types';\nimport { Clickable } from '../Clickable/Clickable';\nimport { ImageBaseBadge, type ImageBaseBadgeProps } from './ImageBaseBadge/ImageBaseBadge';\nimport {\n type FloatElementIndentation,\n type FloatElementPlacement,\n ImageBaseFloatElement,\n type ImageBaseFloatElementProps,\n} from './ImageBaseFloatElement/ImageBaseFloatElement';\nimport { ImageBaseOverlay, type ImageBaseOverlayProps } from './ImageBaseOverlay/ImageBaseOverlay';\nimport { ImageBaseContext } from './context';\nimport type { ImageBaseContextProps, ImageBaseExpectedIconProps, ImageBaseSize } from './types';\nimport { validateFallbackIcon, validateSize } from './validators';\nimport styles from './ImageBase.module.css';\n\nexport type {\n ImageBaseSize,\n ImageBaseExpectedIconProps,\n ImageBaseBadgeProps,\n ImageBaseOverlayProps,\n ImageBaseContextProps,\n ImageBaseFloatElementProps,\n FloatElementPlacement,\n FloatElementIndentation,\n};\n\nexport {\n getBadgeIconSizeByImageBaseSize,\n getFallbackIconSizeByImageBaseSize,\n getOverlayIconSizeByImageBaseSize,\n} from './helpers';\n\nexport { ImageBaseContext };\n\n/**\n * Размер по умолчанию.\n */\nconst defaultSize = 24;\n\nexport interface ImageBaseProps\n extends React.ImgHTMLAttributes<HTMLElement>,\n AnchorHTMLAttributesOnly,\n HasRootRef<HTMLDivElement>,\n HasRef<HTMLImageElement> {\n /**\n * Задаёт размер картинки.\n *\n * Используйте размеры заданные дизайн-системой `16 | 20 | 24 | 28 | 32 | 36 | 40 | 44 | 48 | 56 | 64 | 72 | 80 | 88 | 96`.\n *\n * > ⚠️ Использование кастомного размера – это пограничный кейс.\n */\n size?: LiteralUnion<ImageBaseSize, number>;\n /**\n * Ширина изображения.\n */\n widthSize?: number | string;\n /**\n * Высота изображения.\n */\n heightSize?: number | string;\n /**\n * Отключает обводку.\n */\n noBorder?: boolean;\n /**\n * Фолбек на случай, если картинка не прогрузилась.\n *\n * > 📝 Нужный для `<ImageBase size={...} />` размер можно узнать из функции `getFallbackIconSizeByImageBaseSize()`.\n *\n * > Предпочтительней использовать иконки из `@vkontakte/icons`.\n *\n * > 📊️ Если вы хотите передать кастомную иконку, то следует именовать её по шаблону `Icon<size><name>`. Или же\n * > чтобы в неё был передан параметр `width`. Тогда мы сможем выводить в консоль подсказку правильного ли размера вы\n * > использовали иконку.\n *\n * > ⚠️ Может перекрывать `children`.\n */\n fallbackIcon?: React.ReactElement<ImageBaseExpectedIconProps>;\n /**\n * Отключает фон, заданный по умолчанию. Полезен для отображения картинок с прозрачностью.\n * @since 5.10.0\n */\n withTransparentBackground?: boolean;\n /**\n * Пользовательское значения стиля object-fit\n * Подробнее можно почитать в [документации](https://developer.mozilla.org/ru/docs/Web/CSS/object-fit).\n */\n objectFit?: React.CSSProperties['objectFit'];\n /**\n * Пользовательское значения стиля object-position\n * Подробнее можно почитать в [документации](https://developer.mozilla.org/ru/docs/Web/CSS/object-position).\n */\n objectPosition?: React.CSSProperties['objectPosition'];\n /**\n * Флаг для сохранения пропорций картинки.\n * Для корректной работы необходимо задать размеры хотя бы одной стороны картинки.\n */\n keepAspectRatio?: boolean;\n /**\n * Смотри https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/elementtiming.\n */\n elementTiming?: string;\n /**\n * Пользовательское значения стиля filter\n * Подробнее можно почитать в [документации](https://developer.mozilla.org/ru/docs/Web/CSS/filter).\n */\n filter?: React.CSSProperties['filter'];\n}\n\nconst getObjectFitClassName = (objectFit: React.CSSProperties['objectFit']) => {\n switch (objectFit) {\n case 'contain':\n return styles.imgObjectFitContain;\n case 'cover':\n return styles.imgObjectFitCover;\n case 'none':\n return styles.imgObjectFitNone;\n case 'scale-down':\n return styles.imgObjectFitScaleDown;\n }\n return undefined;\n};\n\nconst parsePx = (value: string): number | undefined => {\n if (value.endsWith('px')) {\n return parseInt(value);\n }\n return undefined;\n};\n\nconst sizeToNumber = (size: number | string | undefined): number | undefined => {\n if (typeof size === 'string') {\n return parsePx(size);\n }\n return size;\n};\n\n/**\n * @see https://vkui.io/components/image-base\n */\nexport const ImageBase: React.FC<ImageBaseProps> & {\n Badge: typeof ImageBaseBadge;\n Overlay: typeof ImageBaseOverlay;\n FloatElement: typeof ImageBaseFloatElement;\n} = ({\n alt,\n crossOrigin,\n decoding,\n loading,\n referrerPolicy,\n sizes,\n src,\n srcSet,\n useMap,\n fetchPriority,\n getRef,\n size: sizeProp,\n width: widthImg,\n height: heightImg,\n widthSize,\n heightSize,\n noBorder = false,\n fallbackIcon: fallbackIconProp,\n children,\n onLoad,\n onError,\n withTransparentBackground,\n objectFit = 'cover',\n objectPosition,\n filter,\n keepAspectRatio = false,\n getRootRef,\n elementTiming,\n ...restProps\n}: ImageBaseProps) => {\n const size = sizeProp ?? minOr([sizeToNumber(widthSize), sizeToNumber(heightSize)], defaultSize);\n const wrapperRef = useExternRef(getRootRef);\n\n const width = widthSize ?? (keepAspectRatio ? undefined : size);\n const height = heightSize ?? (keepAspectRatio ? undefined : size);\n\n const [loaded, setLoaded] = React.useState(false);\n const [failed, setFailed] = React.useState(false);\n\n const mouseOverHandlersRef = useRef<VoidFunction[]>([]);\n const mouseOutHandlersRef = useRef<VoidFunction[]>([]);\n\n const hasSrc = src || srcSet;\n const fallbackIcon = failed || !hasSrc ? fallbackIconProp : null;\n\n if (process.env.NODE_ENV === 'development') {\n validateSize(size);\n if (React.isValidElement(fallbackIcon)) {\n validateFallbackIcon(size, { name: 'fallbackIcon', value: fallbackIcon });\n }\n }\n\n const handleImageLoad = (event: React.SyntheticEvent<HTMLImageElement>) => {\n if (loaded) {\n return;\n }\n\n setLoaded(true);\n setFailed(false);\n onLoad?.(event);\n };\n\n const handleImageError = (event: React.SyntheticEvent<HTMLImageElement>) => {\n setLoaded(false);\n setFailed(true);\n onError?.(event);\n };\n\n const imgRef = useExternRef(getRef);\n const isOnLoadStatusCheckedRef = React.useRef(false);\n React.useEffect(\n function dispatchLoadEventForAlreadyLoadedResourceIfReactInitializedLater() {\n if (isOnLoadStatusCheckedRef.current) {\n return;\n }\n isOnLoadStatusCheckedRef.current = true;\n\n if (imgRef.current && imgRef.current.complete && !loaded) {\n const event = new Event('load');\n imgRef.current.dispatchEvent(event);\n }\n },\n [imgRef, loaded],\n );\n\n const onMouseOver = () => {\n mouseOverHandlersRef.current.forEach((fn) => fn());\n };\n\n const onMouseOut = () => {\n mouseOutHandlersRef.current.forEach((fn) => fn());\n };\n\n const contextValue = React.useMemo(\n () => ({\n size,\n onMouseOverHandlers: mouseOverHandlersRef.current,\n onMouseOutHandlers: mouseOutHandlersRef.current,\n }),\n [size],\n );\n\n const imgStyles:\n | CSSCustomProperties<React.CSSProperties['objectPosition'] | React.CSSProperties['filter']>\n | undefined =\n objectPosition || filter\n ? {\n '--vkui_internal--ImageBase_object_position': objectPosition,\n '--vkui_internal--ImageBase_object_filter': filter,\n }\n : undefined;\n\n const keepAspectRationStyles = keepAspectRatio\n ? {\n width: widthImg || width,\n height: heightImg || height,\n }\n : undefined;\n\n return (\n <ImageBaseContext.Provider value={contextValue}>\n <Clickable\n baseStyle={{ width, height }}\n baseClassName={classNames(\n styles.host,\n hasSrc && loaded && styles.loaded,\n withTransparentBackground && styles.transparentBackground,\n )}\n getRootRef={wrapperRef}\n onMouseOver={onMouseOver}\n onMouseOut={onMouseOut}\n {...restProps}\n >\n {hasSrc && (\n <img\n ref={imgRef}\n alt={alt}\n className={classNames(\n styles.img,\n getObjectFitClassName(objectFit),\n objectPosition && styles.withObjectPosition,\n filter && styles.withFilter,\n keepAspectRatio && styles.imgKeepRatio,\n failed && styles.imgHiddenAlt,\n )}\n crossOrigin={crossOrigin}\n decoding={decoding}\n loading={loading}\n referrerPolicy={referrerPolicy}\n style={mergeStyle(keepAspectRationStyles, imgStyles)}\n sizes={sizes}\n src={src}\n srcSet={srcSet}\n useMap={useMap}\n width={widthImg}\n height={heightImg}\n onLoad={handleImageLoad}\n onError={handleImageError}\n // @ts-expect-error: TS2322 отсутствует в @types/react\n elementtiming={elementTiming} // eslint-disable-line react/no-unknown-property\n {...getFetchPriorityProp(fetchPriority)}\n />\n )}\n {fallbackIcon && <div className={styles.fallback}>{fallbackIcon}</div>}\n {children && <div className={styles.children}>{children}</div>}\n {!noBorder && <div aria-hidden className={styles.border} />}\n </Clickable>\n </ImageBaseContext.Provider>\n );\n};\nImageBase.Badge = ImageBaseBadge;\nImageBase.Overlay = ImageBaseOverlay;\nImageBase.FloatElement = ImageBaseFloatElement;\n\nif (process.env.NODE_ENV !== 'production') {\n defineComponentDisplayNames(ImageBase.Badge, 'ImageBase.Badge');\n defineComponentDisplayNames(ImageBase.Overlay, 'ImageBase.Overlay');\n defineComponentDisplayNames(ImageBase.FloatElement, 'ImageBase.FloatElement');\n}\n"],"names":["useRef","React","classNames","mergeStyle","useExternRef","minOr","defineComponentDisplayNames","getFetchPriorityProp","Clickable","ImageBaseBadge","ImageBaseFloatElement","ImageBaseOverlay","ImageBaseContext","validateFallbackIcon","validateSize","getBadgeIconSizeByImageBaseSize","getFallbackIconSizeByImageBaseSize","getOverlayIconSizeByImageBaseSize","defaultSize","getObjectFitClassName","objectFit","undefined","parsePx","value","endsWith","parseInt","sizeToNumber","size","ImageBase","alt","crossOrigin","decoding","loading","referrerPolicy","sizes","src","srcSet","useMap","fetchPriority","getRef","sizeProp","width","widthImg","height","heightImg","widthSize","heightSize","noBorder","fallbackIcon","fallbackIconProp","children","onLoad","onError","withTransparentBackground","objectPosition","filter","keepAspectRatio","getRootRef","elementTiming","restProps","wrapperRef","loaded","setLoaded","useState","failed","setFailed","mouseOverHandlersRef","mouseOutHandlersRef","hasSrc","process","env","NODE_ENV","isValidElement","name","handleImageLoad","event","handleImageError","imgRef","isOnLoadStatusCheckedRef","useEffect","dispatchLoadEventForAlreadyLoadedResourceIfReactInitializedLater","current","complete","Event","dispatchEvent","onMouseOver","forEach","fn","onMouseOut","contextValue","useMemo","onMouseOverHandlers","onMouseOutHandlers","imgStyles","keepAspectRationStyles","Provider","baseStyle","baseClassName","img","ref","className","style","elementtiming","div","aria-hidden","Badge","Overlay","FloatElement"],"mappings":"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"}
|