@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.
@@ -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;AAO/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,SA+IhC,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":"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,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,GAAGlE,MAAMmE,QAAQ,CAAC;IAC3D,MAAM,CAACC,cAAcC,gBAAgB,GAAGrE,MAAMmE,QAAQ,CAAC;IACvD,MAAMG,YAAYlE;IAClB,MAAMmE,QAAQD,cAAc;IAE5B,MAAME,uBAAuBxE,MAAMyE,MAAM,CAAC;IAE1C,MAAMC,cAAcrE,aAAaoD;IAEjC,MAAMhC,iBAAiBzB,MAAMyE,MAAM,CAAiB,EAAE;IAEtD,MAAME,aAAaxE;IAEnB,MAAMyE,WAAW5E,MAAM6E,WAAW,CAChC,CAACrD;QACC,MAAMD,gBAAgBmD,YAAYI,OAAO;QAEzCrD,eAAeqD,OAAO,CAACC,IAAI,CAAC;gBAQJxD;mBAPtBD,SAAS;gBACPC;gBACAC;gBACAC,gBAAgBA,eAAeqD,OAAO;gBACtCpD,qBAAqB,IAAM2C,gBAAgB;gBAC3C1C,aAAa,IAAO6C,qBAAqBM,OAAO,GAAG;gBACnDlD,eAAe,IAAO4C,qBAAqBM,OAAO,GAAG;gBACrDjD,oBAAoBN,CAAAA,0BAAAA,qCAAAA,mCAAAA,cAAeyD,iBAAiB,cAAhCzD,uDAAAA,iCAAkC0D,WAAW,KAAI;gBACrEnD;gBACAC,eAAeuC;YACjB;;QAEF,IAAI7C,eAAeqD,OAAO,CAAC7B,MAAM,KAAK,GAAG;YACvCxB,eAAeqD,OAAO,CAAC,EAAE;QAC3B;IACF,GACA;QAACJ;QAAa5C;QAAyBwC;QAAWD;KAAgB;IAGpE,MAAMa,gBAAgBlF,MAAM6E,WAAW,CAAC;QACtC,MAAMrD,oBACJ4B,4BAAAA,6BAAAA,kBAAoB,CAAC+B,IAAcA,IAAIT,YAAYI,OAAO,CAAE7C,WAAW;QACzE2C,SAASpD;IACX,GAAG;QAAC4B;QAAiBwB;QAAUF;KAAY;IAE3C,MAAMU,cAAcpF,MAAM6E,WAAW,CAAC;QACpC,MAAMrD,oBACJ6B,6BAAAA,8BAAAA,mBAAqB,CAAC8B,IAAcA,IAAIT,YAAYI,OAAO,CAAE7C,WAAW;QAC1E2C,SAASpD;IACX,GAAG;QAAC6B;QAAkBuB;QAAUF;KAAY;IAE5C,MAAMW,4BAA4BrF,MAAM6E,WAAW,CAAC;QAClD,IAAIvB,cAAcqB,cAAcD,YAAYI,OAAO,IAAI,CAACN,qBAAqBM,OAAO,EAAE;YACpF,MAAMvD,gBAAgBmD,YAAYI,OAAO;YACzC,MAAM1D,aAAaG,cAAcH,UAAU;YAE3C8C,kBAAkBK,QAAQnD,aAAa,IAAIA,aAAa;YACxDiD,gBACEtD,KAAKuB,GAAG,CAACpB,yBAAyBK,kBAAkBA,cAAcU,WAAW,GAC3EV,cAAc0D,WAAW;QAE/B;IACF,GAAG;QAAC3B;QAAYqB;QAAYD;QAAaH;KAAM;IAE/CvE,MAAMsF,SAAS,CAACD,2BAA2B;QAACA;QAA2BlC;KAAS;IAEhF5C,0BACE,SAASgF;QACP,MAAMC,WAAWd,YAAYI,OAAO;QACpC,IAAI,CAACU,UAAU;YACb,OAAOtF;QACT;QACA;;OAEC,GACD,MAAMuF,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,IAAIxC,kBAAkB;YACpB8B,SAASW,gBAAgB,CAAC,SAASV,SAASQ;QAC9C;QACAT,SAASW,gBAAgB,CAAC,UAAUd,2BAA2BY;QAE/D,OAAO;YACL,IAAIvC,kBAAkB;gBACpB,4FAA4F;gBAC5F8B,SAASY,mBAAmB,CAAC,SAASX,SAASQ;YACjD;YACA,6FAA6F;YAC7FT,SAASY,mBAAmB,CAAC,UAAUf,2BAA2BY;QACpE;IACF,GACA;QAACvC;QAAkB2B;QAA2BX;KAAY;IAG5D,qBACE,MAAClE,uDACKwD;QACJqC,eAAepG,yCAEb,gCACAqD,eAAe,qDACfiB;QAEF+B,cAAcjB;;YAEb/B,cAAeqB,CAAAA,cAAcA,eAAe4B,SAAQ,KAAMtC,gCACzD,KAACxD;gBACC+F,eAAa7C;gBACb8C,MAAMlD;gBACNmD,SAASlD;gBACTc,WAAU;gBACVqC,aAAW;gBACXC,UAAU,CAAC;gBACXC,WAAW5G;gBACX6G,SAAS5B;;YAGZ5B,cAAeqB,CAAAA,cAAcA,eAAe4B,SAAQ,KAAMnC,8BACzD,KAAC3D;gBACC+F,eAAa5C;gBACb6C,MAAMlD;gBACNmD,SAASlD;gBACTc,WAAU;gBACVqC,aAAW;gBACXC,UAAU,CAAC;gBACXC,WAAW5G;gBACX6G,SAAS1B;;0BAGb,KAAC2B;gBAAIF,SAAS;gBAAaG,KAAKtC;0BAC9B,cAAA,KAACb;oBACCgD,WAAW5G,8CAA6B8D;oBACxCiD,KAAKlD;8BAEJX;;;;;AAKX,EAAE"}
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":"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"}
@@ -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;CA4K5C,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 needShowFallbackIcon = (failed || !hasSrc) && /*#__PURE__*/ React.isValidElement(fallbackIconProp);
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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"}