@vkontakte/vkui 6.2.0 → 6.2.1

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.
Files changed (132) hide show
  1. package/dist/cjs/components/Avatar/Avatar.d.ts +1 -4
  2. package/dist/cjs/components/Avatar/Avatar.d.ts.map +1 -1
  3. package/dist/cjs/components/ChipsInputBase/ChipsInputBase.js +2 -2
  4. package/dist/cjs/components/ChipsInputBase/ChipsInputBase.js.map +1 -1
  5. package/dist/cjs/components/ChipsInputBase/constants.js +2 -3
  6. package/dist/cjs/components/ChipsInputBase/constants.js.map +1 -1
  7. package/dist/cjs/components/CustomSelect/CustomSelect.js +4 -5
  8. package/dist/cjs/components/CustomSelect/CustomSelect.js.map +1 -1
  9. package/dist/cjs/components/GridAvatar/GridAvatar.js +1 -1
  10. package/dist/cjs/components/GridAvatar/GridAvatar.js.map +1 -1
  11. package/dist/cjs/components/Image/Image.d.ts +2 -4
  12. package/dist/cjs/components/Image/Image.d.ts.map +1 -1
  13. package/dist/cjs/components/ImageBase/ImageBase.d.ts +1 -4
  14. package/dist/cjs/components/ImageBase/ImageBase.d.ts.map +1 -1
  15. package/dist/cjs/components/ImageBase/ImageBaseOverlay/ImageBaseOverlay.d.ts +4 -38
  16. package/dist/cjs/components/ImageBase/ImageBaseOverlay/ImageBaseOverlay.d.ts.map +1 -1
  17. package/dist/cjs/components/ImageBase/ImageBaseOverlay/ImageBaseOverlay.js +60 -19
  18. package/dist/cjs/components/ImageBase/ImageBaseOverlay/ImageBaseOverlay.js.map +1 -1
  19. package/dist/cjs/components/ImageBase/ImageBaseOverlay/hooks.d.ts +6 -0
  20. package/dist/cjs/components/ImageBase/ImageBaseOverlay/hooks.d.ts.map +1 -0
  21. package/dist/cjs/components/ImageBase/ImageBaseOverlay/hooks.js +37 -0
  22. package/dist/cjs/components/ImageBase/ImageBaseOverlay/hooks.js.map +1 -0
  23. package/dist/cjs/components/ImageBase/ImageBaseOverlay/types.d.ts +54 -0
  24. package/dist/cjs/components/ImageBase/ImageBaseOverlay/types.d.ts.map +1 -0
  25. package/dist/cjs/components/ImageBase/ImageBaseOverlay/types.js +8 -0
  26. package/dist/cjs/components/ImageBase/ImageBaseOverlay/types.js.map +1 -0
  27. package/dist/cjs/components/Popover/Popover.d.ts +2 -2
  28. package/dist/cjs/components/Popover/Popover.d.ts.map +1 -1
  29. package/dist/cjs/components/Popover/Popover.js +4 -2
  30. package/dist/cjs/components/Popover/Popover.js.map +1 -1
  31. package/dist/cjs/hooks/useEnsuredControl.js +1 -1
  32. package/dist/cjs/hooks/useEnsuredControl.js.map +1 -1
  33. package/dist/cjs/lib/tokens/TokensClassProvider.d.ts.map +1 -1
  34. package/dist/cjs/lib/tokens/TokensClassProvider.js +1 -1
  35. package/dist/cjs/lib/tokens/TokensClassProvider.js.map +1 -1
  36. package/dist/components/Avatar/Avatar.d.ts +1 -4
  37. package/dist/components/Avatar/Avatar.d.ts.map +1 -1
  38. package/dist/components/ChipsInputBase/ChipsInputBase.js +2 -2
  39. package/dist/components/ChipsInputBase/ChipsInputBase.js.map +1 -1
  40. package/dist/components/ChipsInputBase/constants.js +2 -3
  41. package/dist/components/ChipsInputBase/constants.js.map +1 -1
  42. package/dist/components/CustomSelect/CustomSelect.js +4 -5
  43. package/dist/components/CustomSelect/CustomSelect.js.map +1 -1
  44. package/dist/components/GridAvatar/GridAvatar.js +1 -1
  45. package/dist/components/GridAvatar/GridAvatar.js.map +1 -1
  46. package/dist/components/Image/Image.d.ts +2 -4
  47. package/dist/components/Image/Image.d.ts.map +1 -1
  48. package/dist/components/ImageBase/ImageBase.d.ts +1 -4
  49. package/dist/components/ImageBase/ImageBase.d.ts.map +1 -1
  50. package/dist/components/ImageBase/ImageBaseOverlay/ImageBaseOverlay.d.ts +4 -38
  51. package/dist/components/ImageBase/ImageBaseOverlay/ImageBaseOverlay.d.ts.map +1 -1
  52. package/dist/components/ImageBase/ImageBaseOverlay/ImageBaseOverlay.js +64 -23
  53. package/dist/components/ImageBase/ImageBaseOverlay/ImageBaseOverlay.js.map +1 -1
  54. package/dist/components/ImageBase/ImageBaseOverlay/hooks.d.ts +6 -0
  55. package/dist/components/ImageBase/ImageBaseOverlay/hooks.d.ts.map +1 -0
  56. package/dist/components/ImageBase/ImageBaseOverlay/hooks.js +26 -0
  57. package/dist/components/ImageBase/ImageBaseOverlay/hooks.js.map +1 -0
  58. package/dist/components/ImageBase/ImageBaseOverlay/types.d.ts +54 -0
  59. package/dist/components/ImageBase/ImageBaseOverlay/types.d.ts.map +1 -0
  60. package/dist/components/ImageBase/ImageBaseOverlay/types.js +3 -0
  61. package/dist/components/ImageBase/ImageBaseOverlay/types.js.map +1 -0
  62. package/dist/components/Popover/Popover.d.ts +2 -2
  63. package/dist/components/Popover/Popover.d.ts.map +1 -1
  64. package/dist/components/Popover/Popover.js +4 -2
  65. package/dist/components/Popover/Popover.js.map +1 -1
  66. package/dist/components.css +2 -2
  67. package/dist/components.css.map +1 -1
  68. package/dist/components.js.tmp +235 -117
  69. package/dist/cssm/components/Avatar/Avatar.d.ts +1 -4
  70. package/dist/cssm/components/Avatar/Avatar.d.ts.map +1 -1
  71. package/dist/cssm/components/ChipsInputBase/ChipsInputBase.js +2 -2
  72. package/dist/cssm/components/ChipsInputBase/ChipsInputBase.js.map +1 -1
  73. package/dist/cssm/components/ChipsInputBase/constants.js +2 -2
  74. package/dist/cssm/components/ChipsInputBase/constants.js.map +1 -1
  75. package/dist/cssm/components/CustomScrollView/CustomScrollView.module.css +2 -0
  76. package/dist/cssm/components/CustomSelect/CustomSelect.js +4 -4
  77. package/dist/cssm/components/CustomSelect/CustomSelect.js.map +1 -1
  78. package/dist/cssm/components/CustomSelectOption/CustomSelectOption.module.css +1 -0
  79. package/dist/cssm/components/GridAvatar/GridAvatar.js +1 -1
  80. package/dist/cssm/components/GridAvatar/GridAvatar.js.map +1 -1
  81. package/dist/cssm/components/Image/Image.d.ts +2 -4
  82. package/dist/cssm/components/Image/Image.d.ts.map +1 -1
  83. package/dist/cssm/components/ImageBase/ImageBase.d.ts +1 -4
  84. package/dist/cssm/components/ImageBase/ImageBase.d.ts.map +1 -1
  85. package/dist/cssm/components/ImageBase/ImageBaseOverlay/ImageBaseOverlay.d.ts +4 -38
  86. package/dist/cssm/components/ImageBase/ImageBaseOverlay/ImageBaseOverlay.d.ts.map +1 -1
  87. package/dist/cssm/components/ImageBase/ImageBaseOverlay/ImageBaseOverlay.js +54 -18
  88. package/dist/cssm/components/ImageBase/ImageBaseOverlay/ImageBaseOverlay.js.map +1 -1
  89. package/dist/cssm/components/ImageBase/ImageBaseOverlay/ImageBaseOverlay.module.css +10 -0
  90. package/dist/cssm/components/ImageBase/ImageBaseOverlay/hooks.d.ts +6 -0
  91. package/dist/cssm/components/ImageBase/ImageBaseOverlay/hooks.d.ts.map +1 -0
  92. package/dist/cssm/components/ImageBase/ImageBaseOverlay/hooks.js +26 -0
  93. package/dist/cssm/components/ImageBase/ImageBaseOverlay/hooks.js.map +1 -0
  94. package/dist/cssm/components/ImageBase/ImageBaseOverlay/types.d.ts +54 -0
  95. package/dist/cssm/components/ImageBase/ImageBaseOverlay/types.d.ts.map +1 -0
  96. package/dist/cssm/components/ImageBase/ImageBaseOverlay/types.js +3 -0
  97. package/dist/cssm/components/ImageBase/ImageBaseOverlay/types.js.map +1 -0
  98. package/dist/cssm/components/ModalDismissButton/ModalDismissButton.module.css +5 -6
  99. package/dist/cssm/components/Popover/Popover.d.ts +2 -2
  100. package/dist/cssm/components/Popover/Popover.d.ts.map +1 -1
  101. package/dist/cssm/components/Popover/Popover.js +3 -2
  102. package/dist/cssm/components/Popover/Popover.js.map +1 -1
  103. package/dist/cssm/hooks/useEnsuredControl.js +1 -1
  104. package/dist/cssm/hooks/useEnsuredControl.js.map +1 -1
  105. package/dist/cssm/lib/tokens/TokensClassProvider.d.ts.map +1 -1
  106. package/dist/cssm/lib/tokens/TokensClassProvider.js +2 -1
  107. package/dist/cssm/lib/tokens/TokensClassProvider.js.map +1 -1
  108. package/dist/cssm/lib/tokens/TokensClassProvider.module.css +4 -0
  109. package/dist/hooks/useEnsuredControl.js +1 -1
  110. package/dist/hooks/useEnsuredControl.js.map +1 -1
  111. package/dist/lib/tokens/TokensClassProvider.d.ts.map +1 -1
  112. package/dist/lib/tokens/TokensClassProvider.js +1 -1
  113. package/dist/lib/tokens/TokensClassProvider.js.map +1 -1
  114. package/dist/vkui.css +2 -2
  115. package/dist/vkui.css.map +1 -1
  116. package/dist/vkui.js.tmp +235 -117
  117. package/package.json +1 -1
  118. package/src/components/ChipsInputBase/ChipsInputBase.tsx +2 -2
  119. package/src/components/ChipsInputBase/constants.tsx +2 -2
  120. package/src/components/CustomScrollView/CustomScrollView.module.css +2 -0
  121. package/src/components/CustomSelect/CustomSelect.tsx +7 -7
  122. package/src/components/CustomSelectOption/CustomSelectOption.module.css +1 -0
  123. package/src/components/GridAvatar/GridAvatar.tsx +1 -1
  124. package/src/components/ImageBase/ImageBaseOverlay/ImageBaseOverlay.module.css +10 -0
  125. package/src/components/ImageBase/ImageBaseOverlay/ImageBaseOverlay.tsx +89 -65
  126. package/src/components/ImageBase/ImageBaseOverlay/hooks.ts +26 -0
  127. package/src/components/ImageBase/ImageBaseOverlay/types.ts +58 -0
  128. package/src/components/ModalDismissButton/ModalDismissButton.module.css +5 -6
  129. package/src/components/Popover/Popover.tsx +3 -0
  130. package/src/hooks/useEnsuredControl.ts +1 -1
  131. package/src/lib/tokens/TokensClassProvider.module.css +4 -0
  132. package/src/lib/tokens/TokensClassProvider.tsx +6 -1
@@ -120,7 +120,7 @@ const defaultOptions = [];
120
120
  ]);
121
121
  const scrollToElement = React.useCallback((index, center = false)=>{
122
122
  const dropdown = scrollBoxRef.current;
123
- const item = dropdown ? dropdown.children[index] : null;
123
+ const item = dropdown && dropdown.firstElementChild ? dropdown.firstElementChild.children[index] : null;
124
124
  if (!item || !dropdown) {
125
125
  return;
126
126
  }
@@ -401,10 +401,10 @@ const defaultOptions = [];
401
401
  x: 0,
402
402
  y: 0
403
403
  });
404
- const focusOptionOnMouseMove = React.useCallback((e)=>{
404
+ const focusOptionOnMouseMove = React.useCallback((e, index)=>{
405
405
  const isMouseChangedPosition = Math.abs(prevMousePositionRef.current.x - e.clientX) >= 1 || Math.abs(prevMousePositionRef.current.y - e.clientY) >= 1;
406
406
  if (isMouseChangedPosition) {
407
- focusOptionByIndex(Array.prototype.indexOf.call(e.currentTarget.parentNode?.children, e.currentTarget), false);
407
+ focusOptionByIndex(index, false);
408
408
  }
409
409
  prevMousePositionRef.current = {
410
410
  x: e.clientX,
@@ -433,7 +433,7 @@ const defaultOptions = [];
433
433
  // Причём координаты события меняются на пару пикселей по сравнению с прошлым вызовом,
434
434
  // а значит нельзя на них опираться, чтобы запретить обработку такого события.
435
435
  // C mousemove такой проблемы нет, что позволяет реализовать поведение при наведении с клавиатуры и при наведении мышью идентично `<select>`.
436
- onMouseMove: focusOptionOnMouseMove,
436
+ onMouseMove: (e)=>focusOptionOnMouseMove(e, index),
437
437
  id: `${popupAriaId}-${option.value}`
438
438
  })
439
439
  }, `${option.value}`);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/CustomSelect/CustomSelect.tsx"],"sourcesContent":["import * as React from 'react';\nimport { classNames } from '@vkontakte/vkjs';\nimport { useAdaptivity } from '../../hooks/useAdaptivity';\nimport { useExternRef } from '../../hooks/useExternRef';\nimport { useFocusWithin } from '../../hooks/useFocusWithin';\nimport { useDOM } from '../../lib/dom';\nimport type { PlacementWithAuto } from '../../lib/floating';\nimport { defaultFilterFn, type FilterFn } from '../../lib/select';\nimport { useIsomorphicLayoutEffect } from '../../lib/useIsomorphicLayoutEffect';\nimport { debounce } from '../../lib/utils';\nimport { warnOnce } from '../../lib/warnOnce';\nimport { TrackerOptionsProps } from '../CustomScrollView/useTrackerVisibility';\nimport { CustomSelectDropdown } from '../CustomSelectDropdown/CustomSelectDropdown';\nimport {\n CustomSelectOption,\n CustomSelectOptionProps,\n} from '../CustomSelectOption/CustomSelectOption';\nimport { DropdownIcon } from '../DropdownIcon/DropdownIcon';\nimport { FormFieldProps } from '../FormField/FormField';\nimport { NativeSelectProps } from '../NativeSelect/NativeSelect';\nimport { SelectType } from '../Select/Select';\nimport { Footnote } from '../Typography/Footnote/Footnote';\nimport { VisuallyHidden } from '../VisuallyHidden/VisuallyHidden';\nimport {\n CustomSelectClearButton,\n type CustomSelectClearButtonProps,\n} from './CustomSelectClearButton';\nimport { CustomSelectInput } from './CustomSelectInput';\nimport styles from './CustomSelect.module.css';\n\nconst sizeYClassNames = {\n none: styles['CustomSelect--sizeY-none'],\n ['compact']: styles['CustomSelect--sizeY-compact'],\n};\n\nconst findIndexAfter = (options: CustomSelectOptionInterface[] = [], startIndex = -1) => {\n if (startIndex >= options.length - 1) {\n return -1;\n }\n return options.findIndex((option, i) => i > startIndex && !option.disabled);\n};\n\nconst findIndexBefore = (\n options: CustomSelectOptionInterface[] = [],\n endIndex: number = options.length,\n) => {\n let result = -1;\n if (endIndex <= 0) {\n return result;\n }\n for (let i = endIndex - 1; i >= 0; i--) {\n let option = options[i];\n\n if (!option.disabled) {\n result = i;\n break;\n }\n }\n return result;\n};\n\nconst warn = warnOnce('CustomSelect');\n\nconst checkOptionsValueType = <T extends CustomSelectOptionInterface>(options: T[]) => {\n if (new Set(options.map((item) => typeof item.value)).size > 1) {\n warn(\n 'Некоторые значения ваших опций имеют разные типы. onChange всегда возвращает строковый тип.',\n 'error',\n );\n }\n};\n\nfunction defaultRenderOptionFn<T extends CustomSelectOptionInterface>({\n option,\n ...props\n}: CustomSelectRenderOption<T>): React.ReactNode {\n return <CustomSelectOption {...props} />;\n}\n\nconst handleOptionDown: MouseEventHandler = (e: React.MouseEvent<HTMLElement>) => {\n e.preventDefault();\n};\n\nfunction findSelectedIndex<T extends CustomSelectOptionInterface>(\n options: T[] = [],\n value: SelectValue,\n withClear: boolean,\n) {\n if (withClear && value === '') {\n return -1;\n }\n return (\n options.findIndex((item) => {\n value = typeof item.value === 'number' ? Number(value) : value;\n return item.value === value;\n }) ?? -1\n );\n}\n\nconst filter = <T extends CustomSelectOptionInterface>(\n options: SelectProps<T>['options'],\n inputValue: string,\n filterFn: SelectProps<T>['filterFn'],\n) => {\n return typeof filterFn === 'function'\n ? options.filter((option) => filterFn(inputValue, option))\n : options;\n};\n\nconst defaultOptions: CustomSelectOptionInterface[] = [];\n\ntype SelectValue = React.SelectHTMLAttributes<HTMLSelectElement>['value'];\n\nexport interface CustomSelectOptionInterface {\n value: SelectValue;\n label: React.ReactElement | string;\n disabled?: boolean;\n [index: string]: any;\n}\n\nexport interface CustomSelectRenderOption<T extends CustomSelectOptionInterface>\n extends CustomSelectOptionProps {\n option: T;\n}\n\nexport type { CustomSelectClearButtonProps };\n\nexport interface SelectProps<\n OptionInterfaceT extends CustomSelectOptionInterface = CustomSelectOptionInterface,\n> extends NativeSelectProps,\n FormFieldProps,\n TrackerOptionsProps {\n /**\n * Если `true`, то при клике на `CustomSelect` в нём появится текстовое поле для поиска по `options`. По умолчанию поиск\n * производится по `option.label`.\n */\n searchable?: boolean;\n /**\n * Текст, который будет отображен, если приходит пустой `options`.\n */\n emptyText?: string;\n /**\n * Событие изменения текстового поля\n */\n onInputChange?: (e: React.ChangeEvent) => void;\n options: OptionInterfaceT[];\n /**\n * Функция для кастомной фильтрации. По умолчанию поиск производится по `option.label`.\n */\n filterFn?: false | FilterFn<OptionInterfaceT>;\n popupDirection?: 'top' | 'bottom';\n /**\n * Рендер-проп для кастомного рендера опции.\n * В объекте аргумента приходят [свойства опции](https://vkcom.github.io/VKUI/#/CustomSelectOption?id=props)\n *\n * > ⚠️ Важно: cвойство опции `disabled` должно выставляться только через проп `options`.\n * > Запрещается выставлять `disabled` проп опциям в обход `options`, иначе `CustomSelect` не будет знать об актуальном состоянии\n * опции.\n */\n renderOption?: (props: CustomSelectRenderOption<OptionInterfaceT>) => React.ReactNode;\n /**\n * Рендер-проп для кастомного рендера содержимого дропдауна.\n * В `defaultDropdownContent` содержится список опций в виде скроллящегося блока.\n */\n renderDropdown?: ({\n defaultDropdownContent,\n }: {\n defaultDropdownContent: React.ReactNode;\n }) => React.ReactNode;\n /**\n * Если `true`, то в дропдауне вместо списка опций рисуется спиннер. При переданных `renderDropdown` и `fetching: true`\n * \"победит\" `renderDropdown`.\n */\n fetching?: boolean;\n onClose?: VoidFunction;\n onOpen?: VoidFunction;\n /**\n * Иконка раскрывающегося списка\n */\n icon?: React.ReactNode;\n /**\n * Кастомная кнопка для очистки значения.\n * Должна принимать обязательное свойство `onClick`\n */\n ClearButton?: React.ComponentType<CustomSelectClearButtonProps>;\n /**\n * Если `true`, то справа будет отображаться кнопка для очистки значения\n */\n allowClearButton?: boolean;\n /**\n * (e2e) testId кнопки очистки\n */\n clearButtonTestId?: string;\n /**\n * Отступ от выпадающего списка\n */\n dropdownOffsetDistance?: number;\n /**\n * Ширина раскрывающегося списка зависит от контента\n */\n dropdownAutoWidth?: boolean;\n forceDropdownPortal?: boolean;\n selectType?: SelectType;\n /**\n * Отключает максимальную высоту по умолчанию\n */\n noMaxHeight?: boolean;\n /**\n * (e2e) testId элемента, внутри которого отображается текст выбранной опции `CustomSelect` или плейсхолдер.\n */\n labelTextTestId?: string;\n nativeSelectTestId?: string;\n}\n\ntype MouseEventHandler = (event: React.MouseEvent<HTMLElement>) => void;\n\n/**\n * @see https://vkcom.github.io/VKUI/#/CustomSelect\n */\nexport function CustomSelect<OptionInterfaceT extends CustomSelectOptionInterface>(\n props: SelectProps<OptionInterfaceT>,\n) {\n const [opened, setOpened] = React.useState(false);\n const {\n before,\n name,\n className,\n getRef,\n getRootRef,\n popupDirection = 'bottom',\n style,\n onChange,\n children,\n onInputChange: onInputChangeProp,\n renderDropdown,\n onOpen,\n onClose,\n fetching,\n forceDropdownPortal,\n selectType = 'default',\n autoHideScrollbar,\n autoHideScrollbarDelay,\n searchable = false,\n renderOption: renderOptionProp = defaultRenderOptionFn,\n options: optionsProp = defaultOptions as OptionInterfaceT[],\n emptyText = 'Ничего не найдено',\n filterFn = defaultFilterFn,\n icon: iconProp,\n ClearButton = CustomSelectClearButton,\n allowClearButton = false,\n dropdownOffsetDistance = 0,\n dropdownAutoWidth = false,\n noMaxHeight = false,\n ['aria-labelledby']: ariaLabelledBy,\n clearButtonTestId,\n nativeSelectTestId,\n defaultValue,\n required,\n ...restProps\n } = props;\n\n if (process.env.NODE_ENV === 'development') {\n checkOptionsValueType(optionsProp);\n }\n\n const { sizeY = 'none' } = useAdaptivity();\n\n const containerRef = React.useRef<HTMLDivElement>(null);\n const handleRootRef = useExternRef(containerRef, getRootRef);\n const scrollBoxRef = React.useRef<HTMLDivElement | null>(null);\n const selectElRef = useExternRef(getRef);\n\n const [focusedOptionIndex, setFocusedOptionIndex] = React.useState<number | undefined>(-1);\n const [isControlledOutside, setIsControlledOutside] = React.useState(props.value !== undefined);\n const [inputValue, setInputValue] = React.useState('');\n const [nativeSelectValue, setNativeSelectValue] = React.useState(\n () => props.value ?? defaultValue ?? (allowClearButton ? '' : undefined),\n );\n const [popperPlacement, setPopperPlacement] = React.useState<PlacementWithAuto | undefined>(\n popupDirection,\n );\n const [options, setOptions] = React.useState(optionsProp);\n const [selectedOptionIndex, setSelectedOptionIndex] = React.useState<number | undefined>(\n findSelectedIndex(optionsProp, props.value ?? defaultValue, allowClearButton),\n );\n\n React.useEffect(() => {\n setIsControlledOutside(props.value !== undefined);\n setNativeSelectValue((nativeSelectValue) => props.value ?? nativeSelectValue);\n }, [props.value]);\n\n useIsomorphicLayoutEffect(() => {\n if (\n options.some(({ value }) => nativeSelectValue === value) ||\n (allowClearButton && nativeSelectValue === '')\n ) {\n const event = new Event('change', { bubbles: true });\n\n selectElRef.current?.dispatchEvent(event);\n }\n }, [nativeSelectValue]);\n\n const selected = React.useMemo(() => {\n if (!options.length) {\n return null;\n }\n\n return selectedOptionIndex !== undefined ? options[selectedOptionIndex] : undefined;\n }, [options, selectedOptionIndex]);\n\n const openedClassNames = React.useMemo(\n () =>\n (opened &&\n dropdownOffsetDistance === 0 &&\n (popperPlacement?.includes('top')\n ? styles['CustomSelect--pop-up']\n : styles['CustomSelect--pop-down'])) ||\n undefined,\n [dropdownOffsetDistance, opened, popperPlacement],\n );\n\n const scrollToElement = React.useCallback((index: number, center = false) => {\n const dropdown = scrollBoxRef.current;\n const item = dropdown ? (dropdown.children[index] as HTMLElement) : null;\n\n if (!item || !dropdown) {\n return;\n }\n\n const dropdownHeight = dropdown.offsetHeight;\n const scrollTop = dropdown.scrollTop;\n const itemTop = item.offsetTop;\n const itemHeight = item.offsetHeight;\n\n if (center) {\n dropdown.scrollTop = itemTop - dropdownHeight / 2 + itemHeight / 2;\n } else if (itemTop + itemHeight > dropdownHeight + scrollTop) {\n dropdown.scrollTop = itemTop - dropdownHeight + itemHeight;\n } else if (itemTop < scrollTop) {\n dropdown.scrollTop = itemTop;\n }\n }, []);\n\n const focusOptionByIndex = React.useCallback(\n (index: number | undefined, scrollTo = true) => {\n if (index === undefined || index < 0 || index > (options.length ?? 0) - 1) {\n return;\n }\n\n const option = options[index];\n\n if (option?.disabled) {\n return;\n }\n\n if (scrollTo) {\n scrollToElement(index);\n }\n\n // Это оптимизация, прежде всего, под `onMouseMove`\n setFocusedOptionIndex((focusedOptionIndex) =>\n focusedOptionIndex !== index ? index : focusedOptionIndex,\n );\n },\n [options, scrollToElement],\n );\n\n const isValidIndex = React.useCallback(\n (index: number) => {\n return index >= 0 && index < (options.length ?? 0);\n },\n [options.length],\n );\n\n const setScrollBoxRef = React.useCallback(\n (ref: HTMLDivElement | null) => {\n scrollBoxRef.current = ref;\n\n if (ref && selectedOptionIndex !== undefined && isValidIndex(selectedOptionIndex)) {\n {\n scrollToElement(selectedOptionIndex, true);\n }\n }\n },\n [isValidIndex, scrollToElement, selectedOptionIndex],\n );\n\n const [keyboardInput, setKeyboardInput] = React.useState('');\n const resetKeyboardInput = React.useCallback(() => {\n setKeyboardInput('');\n }, []);\n\n const resetFocusedOption = React.useCallback(() => {\n setFocusedOptionIndex(-1);\n }, []);\n\n const onKeyboardInput = React.useCallback(\n (key: string) => {\n if (!opened) {\n setOpened(true);\n }\n resetFocusedOption();\n const fullInput = keyboardInput + key;\n\n setKeyboardInput(fullInput);\n },\n [keyboardInput, opened, resetFocusedOption],\n );\n\n /**\n * Note: сбрасывать `options` через `setOptions(optionsProp)` не нужно.\n * Сброс происходит в одном из эффекте `updateOptionsAndSelectedOptionIndex()`.\n */\n const close = React.useCallback(() => {\n resetKeyboardInput();\n\n setInputValue('');\n setOpened(false);\n resetFocusedOption();\n onClose?.();\n }, [onClose, resetKeyboardInput, resetFocusedOption]);\n\n const selectOption = React.useCallback(\n (index: number) => {\n const item = options[index];\n\n setNativeSelectValue(item?.value);\n close();\n\n const shouldTriggerOnChangeWhenControlledAndInnerValueIsOutOfSync =\n isControlledOutside &&\n props.value !== nativeSelectValue &&\n nativeSelectValue === item?.value;\n\n if (shouldTriggerOnChangeWhenControlledAndInnerValueIsOutOfSync) {\n const event = new Event('change', { bubbles: true });\n selectElRef.current?.dispatchEvent(event);\n }\n },\n [close, options, selectElRef, isControlledOutside, props.value, nativeSelectValue],\n );\n\n const selectFocused = React.useCallback(() => {\n if (focusedOptionIndex === undefined || !isValidIndex(focusedOptionIndex)) {\n return;\n }\n\n selectOption(focusedOptionIndex);\n }, [focusedOptionIndex, isValidIndex, selectOption]);\n\n const open = React.useCallback(() => {\n setOpened(true);\n setFocusedOptionIndex(selectedOptionIndex);\n\n if (typeof onOpen === 'function') {\n onOpen();\n }\n }, [onOpen, selectedOptionIndex]);\n\n const onBlur = React.useCallback(() => {\n close();\n const event = new Event('focusout', { bubbles: true });\n selectElRef.current?.dispatchEvent(event);\n }, [close, selectElRef]);\n\n const onFocus = React.useCallback(() => {\n const event = new Event('focusin', { bubbles: true });\n selectElRef.current?.dispatchEvent(event);\n }, [selectElRef]);\n\n const onClick = React.useCallback(() => {\n if (opened) {\n close();\n } else {\n open();\n }\n }, [close, open, opened]);\n\n const handleKeyUp = React.useMemo(() => debounce(resetKeyboardInput, 1000), [resetKeyboardInput]);\n\n const focusOption = React.useCallback(\n (type: 'next' | 'prev') => {\n let index = focusedOptionIndex;\n\n if (type === 'next') {\n const nextIndex = findIndexAfter(options, index);\n index = nextIndex === -1 ? findIndexAfter(options) : nextIndex; // Следующий за index или первый валидный до index\n } else if (type === 'prev') {\n const beforeIndex = findIndexBefore(options, index);\n index = beforeIndex === -1 ? findIndexBefore(options) : beforeIndex; // Предшествующий index или последний валидный после index\n }\n\n focusOptionByIndex(index);\n },\n [focusOptionByIndex, focusedOptionIndex, options],\n );\n\n React.useEffect(\n function updateOptionsAndSelectedOptionIndex() {\n const value = props.value ?? nativeSelectValue ?? defaultValue;\n\n const options =\n searchable && inputValue !== undefined\n ? filter(optionsProp, inputValue, filterFn)\n : optionsProp;\n\n setOptions(options);\n setSelectedOptionIndex(findSelectedIndex(options, value, allowClearButton));\n },\n [\n filterFn,\n inputValue,\n nativeSelectValue,\n optionsProp,\n defaultValue,\n props.value,\n searchable,\n allowClearButton,\n ],\n );\n\n const onNativeSelectChange: React.ChangeEventHandler<HTMLSelectElement> = (e) => {\n const newSelectedOptionIndex = findSelectedIndex(\n options,\n e.currentTarget.value,\n allowClearButton,\n );\n\n if (selectedOptionIndex !== newSelectedOptionIndex) {\n if (!isControlledOutside) {\n setSelectedOptionIndex(newSelectedOptionIndex);\n }\n onChange?.(e);\n }\n };\n\n const onInputChange: React.ChangeEventHandler<HTMLInputElement> = React.useCallback(\n (e) => {\n onInputChangeProp && onInputChangeProp(e);\n\n const options = filter(optionsProp, e.target.value, filterFn);\n setOptions(options);\n setSelectedOptionIndex(findSelectedIndex(options, nativeSelectValue, allowClearButton));\n\n setInputValue(e.target.value);\n },\n [filterFn, nativeSelectValue, onInputChangeProp, optionsProp, allowClearButton],\n );\n\n const areOptionsShown = React.useCallback(() => {\n return scrollBoxRef.current !== null;\n }, []);\n\n const handleKeyDownSelect = React.useCallback(\n (event: React.KeyboardEvent) => {\n if (event.key.length === 1 && event.key !== ' ') {\n onKeyboardInput(event.key);\n return;\n }\n\n ['ArrowUp', 'ArrowDown', 'Escape', 'Enter'].includes(event.key) &&\n areOptionsShown() &&\n event.preventDefault();\n\n switch (event.key) {\n case 'ArrowUp':\n if (opened) {\n areOptionsShown() && focusOption('prev');\n } else {\n open();\n }\n break;\n case 'ArrowDown':\n if (opened) {\n areOptionsShown() && focusOption('next');\n } else {\n open();\n }\n break;\n case 'Escape':\n close();\n break;\n case 'Backspace':\n case 'Delete': {\n if (!opened) {\n setOpened(true);\n }\n resetFocusedOption();\n\n break;\n }\n case 'Enter':\n case 'Spacebar':\n case ' ':\n if (opened) {\n areOptionsShown() && selectFocused();\n } else {\n open();\n }\n break;\n }\n },\n [\n areOptionsShown,\n close,\n focusOption,\n onKeyboardInput,\n open,\n opened,\n selectFocused,\n resetFocusedOption,\n ],\n );\n\n const handleOptionClick = React.useCallback(\n (e: React.MouseEvent<HTMLElement>) => {\n const index = Array.prototype.indexOf.call(\n e.currentTarget.parentNode?.children,\n e.currentTarget,\n );\n const option = options[index];\n\n if (option && !option.disabled) {\n selectOption(index);\n }\n },\n [options, selectOption],\n );\n\n const prevMousePositionRef = React.useRef<{\n x: React.MouseEvent['clientX'];\n y: React.MouseEvent['clientY'];\n }>({ x: 0, y: 0 });\n const focusOptionOnMouseMove = React.useCallback(\n (e: React.MouseEvent<HTMLElement>) => {\n const isMouseChangedPosition =\n Math.abs(prevMousePositionRef.current.x - e.clientX) >= 1 ||\n Math.abs(prevMousePositionRef.current.y - e.clientY) >= 1;\n\n if (isMouseChangedPosition) {\n focusOptionByIndex(\n Array.prototype.indexOf.call(e.currentTarget.parentNode?.children, e.currentTarget),\n false,\n );\n }\n\n prevMousePositionRef.current = { x: e.clientX, y: e.clientY };\n },\n [focusOptionByIndex],\n );\n\n const popupAriaId = React.useId();\n const renderOption = React.useCallback(\n (option: OptionInterfaceT, index: number) => {\n const hovered = index === focusedOptionIndex;\n const selected = index === selectedOptionIndex;\n\n return (\n <React.Fragment key={`${option.value}`}>\n {renderOptionProp({\n option,\n hovered,\n children: option.label,\n selected,\n disabled: option.disabled,\n onClick: handleOptionClick,\n onMouseDown: handleOptionDown,\n // Используем `onMouseMove` вместо `onMouseEnter/onMouseOver`.\n // Потому что если при навигации с клавиатуры курсор наведён на\n // список, то при первом автоматическом скролле списка вызывается событие MouseOver/MouseEnter\n // обработчик которого фокусирует опцию под курсором, хотя при навигация с клавиатуры пользователь мог уйти дальше по списку, это путает.\n // Причём координаты события меняются на пару пикселей по сравнению с прошлым вызовом,\n // а значит нельзя на них опираться, чтобы запретить обработку такого события.\n // C mousemove такой проблемы нет, что позволяет реализовать поведение при наведении с клавиатуры и при наведении мышью идентично `<select>`.\n onMouseMove: focusOptionOnMouseMove,\n id: `${popupAriaId}-${option.value}`,\n })}\n </React.Fragment>\n );\n },\n [\n focusedOptionIndex,\n handleOptionClick,\n focusOptionOnMouseMove,\n renderOptionProp,\n selectedOptionIndex,\n popupAriaId,\n ],\n );\n\n const resolvedContent = React.useMemo(() => {\n const defaultDropdownContent =\n options?.length > 0 ? (\n options.map(renderOption)\n ) : (\n <Footnote className={styles['CustomSelect__empty']}>{emptyText}</Footnote>\n );\n\n if (typeof renderDropdown === 'function') {\n return renderDropdown({ defaultDropdownContent });\n } else {\n return defaultDropdownContent;\n }\n }, [emptyText, options, renderDropdown, renderOption]);\n\n const selectInputRef = React.useRef<HTMLInputElement | null>(null);\n const focusOnInputTimerRef = React.useRef<ReturnType<typeof setTimeout>>();\n const focusOnInput = React.useCallback(() => {\n clearTimeout(focusOnInputTimerRef.current);\n\n focusOnInputTimerRef.current = setTimeout(() => {\n selectInputRef.current && selectInputRef.current.focus();\n }, 0);\n }, []);\n useIsomorphicLayoutEffect(function clearFocusOnInputTimer() {\n return () => {\n clearTimeout(focusOnInputTimerRef.current);\n };\n }, []);\n\n const controlledValueSet = isControlledOutside && props.value !== '';\n const uncontrolledValueSet = !isControlledOutside && nativeSelectValue !== '';\n const clearButtonShown =\n allowClearButton && !opened && (controlledValueSet || uncontrolledValueSet);\n\n const clearButton = React.useMemo(() => {\n if (!clearButtonShown) {\n return null;\n }\n\n return (\n <ClearButton\n className={iconProp === undefined ? styles['CustomSelect--clear-icon'] : undefined}\n onClick={function clearSelectState() {\n setNativeSelectValue('');\n setInputValue('');\n focusOnInput();\n }}\n disabled={restProps.disabled}\n data-testid={clearButtonTestId}\n />\n );\n }, [\n clearButtonShown,\n ClearButton,\n iconProp,\n restProps.disabled,\n clearButtonTestId,\n focusOnInput,\n ]);\n\n const icon = React.useMemo(() => {\n if (iconProp !== undefined) {\n return iconProp;\n }\n\n return (\n <DropdownIcon\n className={clearButtonShown ? styles['CustomSelect__dropdown-icon'] : undefined}\n opened={opened}\n />\n );\n }, [clearButtonShown, iconProp, opened]);\n\n const afterIcons = (icon || clearButtonShown) && (\n <React.Fragment>\n {clearButton}\n {icon}\n </React.Fragment>\n );\n\n const { document } = useDOM();\n const passClickAndFocusToInputOnClick = React.useCallback(\n (e: React.MouseEvent<HTMLDivElement>) => {\n // Раньше внешней оберткой CustomSelect был <label>, что позволяло по клику в любую область CustomSelect,\n // даже где нету интерактивного элемента, фокусировать <input> и передавать на него событие клика.\n // Так как мы больше не оборачиваем CustomSelect в <label>, то для обертки CustomSelect мы симулируем работу <label>.\n // передаем фокус и клик по <input>, если пользователь кликнул в зоне обертки.\n // В <label> мы не больше не оборачиваем, потому что это заставляет скринридер\n // дважды произносить текст выбранной опции при фокусе, если CustomSelect связан с внешним <label>.\n // Воспроизводится в некоторых версиях Chrome, при навигации по странице с помощью стрелок.\n // Договорились со специалистом по доступности убрать <label>-обёртки из Select и CustomSelect\n\n if (!selectInputRef.current || !document) {\n return;\n }\n\n const clickTargetIsNotAnInput = e.target !== selectInputRef.current;\n if (clickTargetIsNotAnInput) {\n selectInputRef.current.click();\n\n const inputIsNotFocused = document.activeElement !== selectInputRef.current;\n if (inputIsNotFocused) {\n focusOnInput();\n }\n }\n },\n [document, focusOnInput],\n );\n\n const preventInputBlurWhenClickInsideFocusedSelectArea = (\n e: React.MouseEvent<HTMLDivElement>,\n ) => {\n // Так как инпут больше не оборачивается пустым лэйблом, то клик внутри обертки,\n // но вне инпута (например по иконке дропдауна), будет убирать фокус с инпута.\n // Чтобы в такой ситуации отключить blur инпута мы превентим mousedown событие обёртки\n const isInputFocused = document && document.activeElement === selectInputRef.current;\n if (isInputFocused) {\n e.preventDefault();\n }\n };\n\n const ariaActiveDescendantOptionIndex: undefined | number =\n focusedOptionIndex !== -1 ? focusedOptionIndex : undefined;\n const ariaActiveDescendantId =\n ariaActiveDescendantOptionIndex !== undefined\n ? options[ariaActiveDescendantOptionIndex] && options[ariaActiveDescendantOptionIndex].value\n : null;\n\n const selectInputAriaProps: React.HTMLAttributes<HTMLElement> = {\n 'role': 'combobox',\n 'aria-controls': popupAriaId,\n 'aria-owns': popupAriaId,\n 'aria-expanded': opened,\n ['aria-activedescendant']:\n ariaActiveDescendantId && opened ? `${popupAriaId}-${ariaActiveDescendantId}` : undefined,\n 'aria-labelledby': ariaLabelledBy,\n 'aria-haspopup': 'listbox',\n 'aria-autocomplete': 'none',\n };\n\n const focusWithin = useFocusWithin(handleRootRef);\n\n return (\n <div\n className={classNames(\n styles['CustomSelect'],\n sizeY !== 'regular' && sizeYClassNames[sizeY],\n className,\n )}\n style={style}\n ref={handleRootRef}\n onClick={passClickAndFocusToInputOnClick}\n onMouseDown={preventInputBlurWhenClickInsideFocusedSelectArea}\n >\n {focusWithin && selected && !opened && (\n <VisuallyHidden aria-live=\"polite\">{selected.label}</VisuallyHidden>\n )}\n <CustomSelectInput\n autoComplete=\"off\"\n autoCapitalize=\"none\"\n autoCorrect=\"off\"\n spellCheck=\"false\"\n {...restProps}\n {...selectInputAriaProps}\n getRef={selectInputRef}\n onFocus={onFocus}\n onBlur={onBlur}\n className={openedClassNames}\n readOnly={!searchable}\n fetching={fetching}\n value={inputValue}\n onKeyUp={handleKeyUp}\n onKeyDown={handleKeyDownSelect}\n onChange={onInputChange}\n onClick={onClick}\n before={before}\n after={afterIcons}\n selectType={selectType}\n >\n {selected?.label}\n </CustomSelectInput>\n <select\n ref={selectElRef}\n name={name}\n onChange={onNativeSelectChange}\n onBlur={props.onBlur}\n onFocus={props.onFocus}\n onClick={props.onClick}\n value={nativeSelectValue}\n aria-hidden\n className={styles['CustomSelect__control']}\n data-testid={nativeSelectTestId}\n required={required}\n >\n {allowClearButton && <option key=\"\" value=\"\" />}\n {optionsProp.map((item) => (\n <option key={`${item.value}`} value={item.value} />\n ))}\n </select>\n {opened && (\n <CustomSelectDropdown\n targetRef={containerRef}\n placement={popupDirection}\n scrollBoxRef={setScrollBoxRef}\n onPlacementChange={setPopperPlacement}\n onMouseLeave={resetFocusedOption}\n fetching={fetching}\n offsetDistance={dropdownOffsetDistance}\n autoWidth={dropdownAutoWidth}\n forcePortal={forceDropdownPortal}\n autoHideScrollbar={autoHideScrollbar}\n autoHideScrollbarDelay={autoHideScrollbarDelay}\n noMaxHeight={noMaxHeight}\n role=\"listbox\"\n id={popupAriaId}\n aria-labelledby={ariaLabelledBy}\n tabIndex={-1}\n >\n {resolvedContent}\n </CustomSelectDropdown>\n )}\n </div>\n );\n}\n"],"names":["React","classNames","useAdaptivity","useExternRef","useFocusWithin","useDOM","defaultFilterFn","useIsomorphicLayoutEffect","debounce","warnOnce","CustomSelectDropdown","CustomSelectOption","DropdownIcon","Footnote","VisuallyHidden","CustomSelectClearButton","CustomSelectInput","styles","sizeYClassNames","none","findIndexAfter","options","startIndex","length","findIndex","option","i","disabled","findIndexBefore","endIndex","result","warn","checkOptionsValueType","Set","map","item","value","size","defaultRenderOptionFn","props","handleOptionDown","e","preventDefault","findSelectedIndex","withClear","Number","filter","inputValue","filterFn","defaultOptions","CustomSelect","opened","setOpened","useState","before","name","className","getRef","getRootRef","popupDirection","style","onChange","children","onInputChange","onInputChangeProp","renderDropdown","onOpen","onClose","fetching","forceDropdownPortal","selectType","autoHideScrollbar","autoHideScrollbarDelay","searchable","renderOption","renderOptionProp","optionsProp","emptyText","icon","iconProp","ClearButton","allowClearButton","dropdownOffsetDistance","dropdownAutoWidth","noMaxHeight","ariaLabelledBy","clearButtonTestId","nativeSelectTestId","defaultValue","required","restProps","process","env","NODE_ENV","sizeY","containerRef","useRef","handleRootRef","scrollBoxRef","selectElRef","focusedOptionIndex","setFocusedOptionIndex","isControlledOutside","setIsControlledOutside","undefined","setInputValue","nativeSelectValue","setNativeSelectValue","popperPlacement","setPopperPlacement","setOptions","selectedOptionIndex","setSelectedOptionIndex","useEffect","some","event","Event","bubbles","current","dispatchEvent","selected","useMemo","openedClassNames","includes","scrollToElement","useCallback","index","center","dropdown","dropdownHeight","offsetHeight","scrollTop","itemTop","offsetTop","itemHeight","focusOptionByIndex","scrollTo","isValidIndex","setScrollBoxRef","ref","keyboardInput","setKeyboardInput","resetKeyboardInput","resetFocusedOption","onKeyboardInput","key","fullInput","close","selectOption","shouldTriggerOnChangeWhenControlledAndInnerValueIsOutOfSync","selectFocused","open","onBlur","onFocus","onClick","handleKeyUp","focusOption","type","nextIndex","beforeIndex","updateOptionsAndSelectedOptionIndex","onNativeSelectChange","newSelectedOptionIndex","currentTarget","target","areOptionsShown","handleKeyDownSelect","handleOptionClick","Array","prototype","indexOf","call","parentNode","prevMousePositionRef","x","y","focusOptionOnMouseMove","isMouseChangedPosition","Math","abs","clientX","clientY","popupAriaId","useId","hovered","Fragment","label","onMouseDown","onMouseMove","id","resolvedContent","defaultDropdownContent","selectInputRef","focusOnInputTimerRef","focusOnInput","clearTimeout","setTimeout","focus","clearFocusOnInputTimer","controlledValueSet","uncontrolledValueSet","clearButtonShown","clearButton","clearSelectState","data-testid","afterIcons","document","passClickAndFocusToInputOnClick","clickTargetIsNotAnInput","click","inputIsNotFocused","activeElement","preventInputBlurWhenClickInsideFocusedSelectArea","isInputFocused","ariaActiveDescendantOptionIndex","ariaActiveDescendantId","selectInputAriaProps","focusWithin","div","aria-live","autoComplete","autoCapitalize","autoCorrect","spellCheck","readOnly","onKeyUp","onKeyDown","after","select","aria-hidden","targetRef","placement","onPlacementChange","onMouseLeave","offsetDistance","autoWidth","forcePortal","role","aria-labelledby","tabIndex"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../src/components/CustomSelect/CustomSelect.tsx"],"sourcesContent":["import * as React from 'react';\nimport { classNames } from '@vkontakte/vkjs';\nimport { useAdaptivity } from '../../hooks/useAdaptivity';\nimport { useExternRef } from '../../hooks/useExternRef';\nimport { useFocusWithin } from '../../hooks/useFocusWithin';\nimport { useDOM } from '../../lib/dom';\nimport type { PlacementWithAuto } from '../../lib/floating';\nimport { defaultFilterFn, type FilterFn } from '../../lib/select';\nimport { useIsomorphicLayoutEffect } from '../../lib/useIsomorphicLayoutEffect';\nimport { debounce } from '../../lib/utils';\nimport { warnOnce } from '../../lib/warnOnce';\nimport { TrackerOptionsProps } from '../CustomScrollView/useTrackerVisibility';\nimport { CustomSelectDropdown } from '../CustomSelectDropdown/CustomSelectDropdown';\nimport {\n CustomSelectOption,\n CustomSelectOptionProps,\n} from '../CustomSelectOption/CustomSelectOption';\nimport { DropdownIcon } from '../DropdownIcon/DropdownIcon';\nimport { FormFieldProps } from '../FormField/FormField';\nimport { NativeSelectProps } from '../NativeSelect/NativeSelect';\nimport { SelectType } from '../Select/Select';\nimport { Footnote } from '../Typography/Footnote/Footnote';\nimport { VisuallyHidden } from '../VisuallyHidden/VisuallyHidden';\nimport {\n CustomSelectClearButton,\n type CustomSelectClearButtonProps,\n} from './CustomSelectClearButton';\nimport { CustomSelectInput } from './CustomSelectInput';\nimport styles from './CustomSelect.module.css';\n\nconst sizeYClassNames = {\n none: styles['CustomSelect--sizeY-none'],\n ['compact']: styles['CustomSelect--sizeY-compact'],\n};\n\nconst findIndexAfter = (options: CustomSelectOptionInterface[] = [], startIndex = -1) => {\n if (startIndex >= options.length - 1) {\n return -1;\n }\n return options.findIndex((option, i) => i > startIndex && !option.disabled);\n};\n\nconst findIndexBefore = (\n options: CustomSelectOptionInterface[] = [],\n endIndex: number = options.length,\n) => {\n let result = -1;\n if (endIndex <= 0) {\n return result;\n }\n for (let i = endIndex - 1; i >= 0; i--) {\n let option = options[i];\n\n if (!option.disabled) {\n result = i;\n break;\n }\n }\n return result;\n};\n\nconst warn = warnOnce('CustomSelect');\n\nconst checkOptionsValueType = <T extends CustomSelectOptionInterface>(options: T[]) => {\n if (new Set(options.map((item) => typeof item.value)).size > 1) {\n warn(\n 'Некоторые значения ваших опций имеют разные типы. onChange всегда возвращает строковый тип.',\n 'error',\n );\n }\n};\n\nfunction defaultRenderOptionFn<T extends CustomSelectOptionInterface>({\n option,\n ...props\n}: CustomSelectRenderOption<T>): React.ReactNode {\n return <CustomSelectOption {...props} />;\n}\n\nconst handleOptionDown: MouseEventHandler = (e: React.MouseEvent<HTMLElement>) => {\n e.preventDefault();\n};\n\nfunction findSelectedIndex<T extends CustomSelectOptionInterface>(\n options: T[] = [],\n value: SelectValue,\n withClear: boolean,\n) {\n if (withClear && value === '') {\n return -1;\n }\n return (\n options.findIndex((item) => {\n value = typeof item.value === 'number' ? Number(value) : value;\n return item.value === value;\n }) ?? -1\n );\n}\n\nconst filter = <T extends CustomSelectOptionInterface>(\n options: SelectProps<T>['options'],\n inputValue: string,\n filterFn: SelectProps<T>['filterFn'],\n) => {\n return typeof filterFn === 'function'\n ? options.filter((option) => filterFn(inputValue, option))\n : options;\n};\n\nconst defaultOptions: CustomSelectOptionInterface[] = [];\n\ntype SelectValue = React.SelectHTMLAttributes<HTMLSelectElement>['value'];\n\nexport interface CustomSelectOptionInterface {\n value: SelectValue;\n label: React.ReactElement | string;\n disabled?: boolean;\n [index: string]: any;\n}\n\nexport interface CustomSelectRenderOption<T extends CustomSelectOptionInterface>\n extends CustomSelectOptionProps {\n option: T;\n}\n\nexport type { CustomSelectClearButtonProps };\n\nexport interface SelectProps<\n OptionInterfaceT extends CustomSelectOptionInterface = CustomSelectOptionInterface,\n> extends NativeSelectProps,\n FormFieldProps,\n TrackerOptionsProps {\n /**\n * Если `true`, то при клике на `CustomSelect` в нём появится текстовое поле для поиска по `options`. По умолчанию поиск\n * производится по `option.label`.\n */\n searchable?: boolean;\n /**\n * Текст, который будет отображен, если приходит пустой `options`.\n */\n emptyText?: string;\n /**\n * Событие изменения текстового поля\n */\n onInputChange?: (e: React.ChangeEvent) => void;\n options: OptionInterfaceT[];\n /**\n * Функция для кастомной фильтрации. По умолчанию поиск производится по `option.label`.\n */\n filterFn?: false | FilterFn<OptionInterfaceT>;\n popupDirection?: 'top' | 'bottom';\n /**\n * Рендер-проп для кастомного рендера опции.\n * В объекте аргумента приходят [свойства опции](https://vkcom.github.io/VKUI/#/CustomSelectOption?id=props)\n *\n * > ⚠️ Важно: cвойство опции `disabled` должно выставляться только через проп `options`.\n * > Запрещается выставлять `disabled` проп опциям в обход `options`, иначе `CustomSelect` не будет знать об актуальном состоянии\n * опции.\n */\n renderOption?: (props: CustomSelectRenderOption<OptionInterfaceT>) => React.ReactNode;\n /**\n * Рендер-проп для кастомного рендера содержимого дропдауна.\n * В `defaultDropdownContent` содержится список опций в виде скроллящегося блока.\n */\n renderDropdown?: ({\n defaultDropdownContent,\n }: {\n defaultDropdownContent: React.ReactNode;\n }) => React.ReactNode;\n /**\n * Если `true`, то в дропдауне вместо списка опций рисуется спиннер. При переданных `renderDropdown` и `fetching: true`\n * \"победит\" `renderDropdown`.\n */\n fetching?: boolean;\n onClose?: VoidFunction;\n onOpen?: VoidFunction;\n /**\n * Иконка раскрывающегося списка\n */\n icon?: React.ReactNode;\n /**\n * Кастомная кнопка для очистки значения.\n * Должна принимать обязательное свойство `onClick`\n */\n ClearButton?: React.ComponentType<CustomSelectClearButtonProps>;\n /**\n * Если `true`, то справа будет отображаться кнопка для очистки значения\n */\n allowClearButton?: boolean;\n /**\n * (e2e) testId кнопки очистки\n */\n clearButtonTestId?: string;\n /**\n * Отступ от выпадающего списка\n */\n dropdownOffsetDistance?: number;\n /**\n * Ширина раскрывающегося списка зависит от контента\n */\n dropdownAutoWidth?: boolean;\n forceDropdownPortal?: boolean;\n selectType?: SelectType;\n /**\n * Отключает максимальную высоту по умолчанию\n */\n noMaxHeight?: boolean;\n /**\n * (e2e) testId элемента, внутри которого отображается текст выбранной опции `CustomSelect` или плейсхолдер.\n */\n labelTextTestId?: string;\n nativeSelectTestId?: string;\n}\n\ntype MouseEventHandler = (event: React.MouseEvent<HTMLElement>) => void;\n\n/**\n * @see https://vkcom.github.io/VKUI/#/CustomSelect\n */\nexport function CustomSelect<OptionInterfaceT extends CustomSelectOptionInterface>(\n props: SelectProps<OptionInterfaceT>,\n) {\n const [opened, setOpened] = React.useState(false);\n const {\n before,\n name,\n className,\n getRef,\n getRootRef,\n popupDirection = 'bottom',\n style,\n onChange,\n children,\n onInputChange: onInputChangeProp,\n renderDropdown,\n onOpen,\n onClose,\n fetching,\n forceDropdownPortal,\n selectType = 'default',\n autoHideScrollbar,\n autoHideScrollbarDelay,\n searchable = false,\n renderOption: renderOptionProp = defaultRenderOptionFn,\n options: optionsProp = defaultOptions as OptionInterfaceT[],\n emptyText = 'Ничего не найдено',\n filterFn = defaultFilterFn,\n icon: iconProp,\n ClearButton = CustomSelectClearButton,\n allowClearButton = false,\n dropdownOffsetDistance = 0,\n dropdownAutoWidth = false,\n noMaxHeight = false,\n ['aria-labelledby']: ariaLabelledBy,\n clearButtonTestId,\n nativeSelectTestId,\n defaultValue,\n required,\n ...restProps\n } = props;\n\n if (process.env.NODE_ENV === 'development') {\n checkOptionsValueType(optionsProp);\n }\n\n const { sizeY = 'none' } = useAdaptivity();\n\n const containerRef = React.useRef<HTMLDivElement>(null);\n const handleRootRef = useExternRef(containerRef, getRootRef);\n const scrollBoxRef = React.useRef<HTMLDivElement | null>(null);\n const selectElRef = useExternRef(getRef);\n\n const [focusedOptionIndex, setFocusedOptionIndex] = React.useState<number | undefined>(-1);\n const [isControlledOutside, setIsControlledOutside] = React.useState(props.value !== undefined);\n const [inputValue, setInputValue] = React.useState('');\n const [nativeSelectValue, setNativeSelectValue] = React.useState(\n () => props.value ?? defaultValue ?? (allowClearButton ? '' : undefined),\n );\n const [popperPlacement, setPopperPlacement] = React.useState<PlacementWithAuto | undefined>(\n popupDirection,\n );\n const [options, setOptions] = React.useState(optionsProp);\n const [selectedOptionIndex, setSelectedOptionIndex] = React.useState<number | undefined>(\n findSelectedIndex(optionsProp, props.value ?? defaultValue, allowClearButton),\n );\n\n React.useEffect(() => {\n setIsControlledOutside(props.value !== undefined);\n setNativeSelectValue((nativeSelectValue) => props.value ?? nativeSelectValue);\n }, [props.value]);\n\n useIsomorphicLayoutEffect(() => {\n if (\n options.some(({ value }) => nativeSelectValue === value) ||\n (allowClearButton && nativeSelectValue === '')\n ) {\n const event = new Event('change', { bubbles: true });\n\n selectElRef.current?.dispatchEvent(event);\n }\n }, [nativeSelectValue]);\n\n const selected = React.useMemo(() => {\n if (!options.length) {\n return null;\n }\n\n return selectedOptionIndex !== undefined ? options[selectedOptionIndex] : undefined;\n }, [options, selectedOptionIndex]);\n\n const openedClassNames = React.useMemo(\n () =>\n (opened &&\n dropdownOffsetDistance === 0 &&\n (popperPlacement?.includes('top')\n ? styles['CustomSelect--pop-up']\n : styles['CustomSelect--pop-down'])) ||\n undefined,\n [dropdownOffsetDistance, opened, popperPlacement],\n );\n\n const scrollToElement = React.useCallback((index: number, center = false) => {\n const dropdown = scrollBoxRef.current;\n const item =\n dropdown && dropdown.firstElementChild\n ? (dropdown.firstElementChild.children[index] as HTMLElement)\n : null;\n\n if (!item || !dropdown) {\n return;\n }\n\n const dropdownHeight = dropdown.offsetHeight;\n const scrollTop = dropdown.scrollTop;\n const itemTop = item.offsetTop;\n const itemHeight = item.offsetHeight;\n\n if (center) {\n dropdown.scrollTop = itemTop - dropdownHeight / 2 + itemHeight / 2;\n } else if (itemTop + itemHeight > dropdownHeight + scrollTop) {\n dropdown.scrollTop = itemTop - dropdownHeight + itemHeight;\n } else if (itemTop < scrollTop) {\n dropdown.scrollTop = itemTop;\n }\n }, []);\n\n const focusOptionByIndex = React.useCallback(\n (index: number | undefined, scrollTo = true) => {\n if (index === undefined || index < 0 || index > (options.length ?? 0) - 1) {\n return;\n }\n\n const option = options[index];\n\n if (option?.disabled) {\n return;\n }\n\n if (scrollTo) {\n scrollToElement(index);\n }\n\n // Это оптимизация, прежде всего, под `onMouseMove`\n setFocusedOptionIndex((focusedOptionIndex) =>\n focusedOptionIndex !== index ? index : focusedOptionIndex,\n );\n },\n [options, scrollToElement],\n );\n\n const isValidIndex = React.useCallback(\n (index: number) => {\n return index >= 0 && index < (options.length ?? 0);\n },\n [options.length],\n );\n\n const setScrollBoxRef = React.useCallback(\n (ref: HTMLDivElement | null) => {\n scrollBoxRef.current = ref;\n\n if (ref && selectedOptionIndex !== undefined && isValidIndex(selectedOptionIndex)) {\n {\n scrollToElement(selectedOptionIndex, true);\n }\n }\n },\n [isValidIndex, scrollToElement, selectedOptionIndex],\n );\n\n const [keyboardInput, setKeyboardInput] = React.useState('');\n const resetKeyboardInput = React.useCallback(() => {\n setKeyboardInput('');\n }, []);\n\n const resetFocusedOption = React.useCallback(() => {\n setFocusedOptionIndex(-1);\n }, []);\n\n const onKeyboardInput = React.useCallback(\n (key: string) => {\n if (!opened) {\n setOpened(true);\n }\n resetFocusedOption();\n const fullInput = keyboardInput + key;\n\n setKeyboardInput(fullInput);\n },\n [keyboardInput, opened, resetFocusedOption],\n );\n\n /**\n * Note: сбрасывать `options` через `setOptions(optionsProp)` не нужно.\n * Сброс происходит в одном из эффекте `updateOptionsAndSelectedOptionIndex()`.\n */\n const close = React.useCallback(() => {\n resetKeyboardInput();\n\n setInputValue('');\n setOpened(false);\n resetFocusedOption();\n onClose?.();\n }, [onClose, resetKeyboardInput, resetFocusedOption]);\n\n const selectOption = React.useCallback(\n (index: number) => {\n const item = options[index];\n\n setNativeSelectValue(item?.value);\n close();\n\n const shouldTriggerOnChangeWhenControlledAndInnerValueIsOutOfSync =\n isControlledOutside &&\n props.value !== nativeSelectValue &&\n nativeSelectValue === item?.value;\n\n if (shouldTriggerOnChangeWhenControlledAndInnerValueIsOutOfSync) {\n const event = new Event('change', { bubbles: true });\n selectElRef.current?.dispatchEvent(event);\n }\n },\n [close, options, selectElRef, isControlledOutside, props.value, nativeSelectValue],\n );\n\n const selectFocused = React.useCallback(() => {\n if (focusedOptionIndex === undefined || !isValidIndex(focusedOptionIndex)) {\n return;\n }\n\n selectOption(focusedOptionIndex);\n }, [focusedOptionIndex, isValidIndex, selectOption]);\n\n const open = React.useCallback(() => {\n setOpened(true);\n setFocusedOptionIndex(selectedOptionIndex);\n\n if (typeof onOpen === 'function') {\n onOpen();\n }\n }, [onOpen, selectedOptionIndex]);\n\n const onBlur = React.useCallback(() => {\n close();\n const event = new Event('focusout', { bubbles: true });\n selectElRef.current?.dispatchEvent(event);\n }, [close, selectElRef]);\n\n const onFocus = React.useCallback(() => {\n const event = new Event('focusin', { bubbles: true });\n selectElRef.current?.dispatchEvent(event);\n }, [selectElRef]);\n\n const onClick = React.useCallback(() => {\n if (opened) {\n close();\n } else {\n open();\n }\n }, [close, open, opened]);\n\n const handleKeyUp = React.useMemo(() => debounce(resetKeyboardInput, 1000), [resetKeyboardInput]);\n\n const focusOption = React.useCallback(\n (type: 'next' | 'prev') => {\n let index = focusedOptionIndex;\n\n if (type === 'next') {\n const nextIndex = findIndexAfter(options, index);\n index = nextIndex === -1 ? findIndexAfter(options) : nextIndex; // Следующий за index или первый валидный до index\n } else if (type === 'prev') {\n const beforeIndex = findIndexBefore(options, index);\n index = beforeIndex === -1 ? findIndexBefore(options) : beforeIndex; // Предшествующий index или последний валидный после index\n }\n\n focusOptionByIndex(index);\n },\n [focusOptionByIndex, focusedOptionIndex, options],\n );\n\n React.useEffect(\n function updateOptionsAndSelectedOptionIndex() {\n const value = props.value ?? nativeSelectValue ?? defaultValue;\n\n const options =\n searchable && inputValue !== undefined\n ? filter(optionsProp, inputValue, filterFn)\n : optionsProp;\n\n setOptions(options);\n setSelectedOptionIndex(findSelectedIndex(options, value, allowClearButton));\n },\n [\n filterFn,\n inputValue,\n nativeSelectValue,\n optionsProp,\n defaultValue,\n props.value,\n searchable,\n allowClearButton,\n ],\n );\n\n const onNativeSelectChange: React.ChangeEventHandler<HTMLSelectElement> = (e) => {\n const newSelectedOptionIndex = findSelectedIndex(\n options,\n e.currentTarget.value,\n allowClearButton,\n );\n\n if (selectedOptionIndex !== newSelectedOptionIndex) {\n if (!isControlledOutside) {\n setSelectedOptionIndex(newSelectedOptionIndex);\n }\n onChange?.(e);\n }\n };\n\n const onInputChange: React.ChangeEventHandler<HTMLInputElement> = React.useCallback(\n (e) => {\n onInputChangeProp && onInputChangeProp(e);\n\n const options = filter(optionsProp, e.target.value, filterFn);\n setOptions(options);\n setSelectedOptionIndex(findSelectedIndex(options, nativeSelectValue, allowClearButton));\n\n setInputValue(e.target.value);\n },\n [filterFn, nativeSelectValue, onInputChangeProp, optionsProp, allowClearButton],\n );\n\n const areOptionsShown = React.useCallback(() => {\n return scrollBoxRef.current !== null;\n }, []);\n\n const handleKeyDownSelect = React.useCallback(\n (event: React.KeyboardEvent) => {\n if (event.key.length === 1 && event.key !== ' ') {\n onKeyboardInput(event.key);\n return;\n }\n\n ['ArrowUp', 'ArrowDown', 'Escape', 'Enter'].includes(event.key) &&\n areOptionsShown() &&\n event.preventDefault();\n\n switch (event.key) {\n case 'ArrowUp':\n if (opened) {\n areOptionsShown() && focusOption('prev');\n } else {\n open();\n }\n break;\n case 'ArrowDown':\n if (opened) {\n areOptionsShown() && focusOption('next');\n } else {\n open();\n }\n break;\n case 'Escape':\n close();\n break;\n case 'Backspace':\n case 'Delete': {\n if (!opened) {\n setOpened(true);\n }\n resetFocusedOption();\n\n break;\n }\n case 'Enter':\n case 'Spacebar':\n case ' ':\n if (opened) {\n areOptionsShown() && selectFocused();\n } else {\n open();\n }\n break;\n }\n },\n [\n areOptionsShown,\n close,\n focusOption,\n onKeyboardInput,\n open,\n opened,\n selectFocused,\n resetFocusedOption,\n ],\n );\n\n const handleOptionClick = React.useCallback(\n (e: React.MouseEvent<HTMLElement>) => {\n const index = Array.prototype.indexOf.call(\n e.currentTarget.parentNode?.children,\n e.currentTarget,\n );\n const option = options[index];\n\n if (option && !option.disabled) {\n selectOption(index);\n }\n },\n [options, selectOption],\n );\n\n const prevMousePositionRef = React.useRef<{\n x: React.MouseEvent['clientX'];\n y: React.MouseEvent['clientY'];\n }>({ x: 0, y: 0 });\n const focusOptionOnMouseMove = React.useCallback(\n (e: React.MouseEvent<HTMLElement>, index: number) => {\n const isMouseChangedPosition =\n Math.abs(prevMousePositionRef.current.x - e.clientX) >= 1 ||\n Math.abs(prevMousePositionRef.current.y - e.clientY) >= 1;\n\n if (isMouseChangedPosition) {\n focusOptionByIndex(index, false);\n }\n\n prevMousePositionRef.current = { x: e.clientX, y: e.clientY };\n },\n [focusOptionByIndex],\n );\n\n const popupAriaId = React.useId();\n const renderOption = React.useCallback(\n (option: OptionInterfaceT, index: number) => {\n const hovered = index === focusedOptionIndex;\n const selected = index === selectedOptionIndex;\n\n return (\n <React.Fragment key={`${option.value}`}>\n {renderOptionProp({\n option,\n hovered,\n children: option.label,\n selected,\n disabled: option.disabled,\n onClick: handleOptionClick,\n onMouseDown: handleOptionDown,\n // Используем `onMouseMove` вместо `onMouseEnter/onMouseOver`.\n // Потому что если при навигации с клавиатуры курсор наведён на\n // список, то при первом автоматическом скролле списка вызывается событие MouseOver/MouseEnter\n // обработчик которого фокусирует опцию под курсором, хотя при навигация с клавиатуры пользователь мог уйти дальше по списку, это путает.\n // Причём координаты события меняются на пару пикселей по сравнению с прошлым вызовом,\n // а значит нельзя на них опираться, чтобы запретить обработку такого события.\n // C mousemove такой проблемы нет, что позволяет реализовать поведение при наведении с клавиатуры и при наведении мышью идентично `<select>`.\n onMouseMove: (e) => focusOptionOnMouseMove(e, index),\n id: `${popupAriaId}-${option.value}`,\n })}\n </React.Fragment>\n );\n },\n [\n focusedOptionIndex,\n handleOptionClick,\n focusOptionOnMouseMove,\n renderOptionProp,\n selectedOptionIndex,\n popupAriaId,\n ],\n );\n\n const resolvedContent = React.useMemo(() => {\n const defaultDropdownContent =\n options?.length > 0 ? (\n options.map(renderOption)\n ) : (\n <Footnote className={styles['CustomSelect__empty']}>{emptyText}</Footnote>\n );\n\n if (typeof renderDropdown === 'function') {\n return renderDropdown({ defaultDropdownContent });\n } else {\n return defaultDropdownContent;\n }\n }, [emptyText, options, renderDropdown, renderOption]);\n\n const selectInputRef = React.useRef<HTMLInputElement | null>(null);\n const focusOnInputTimerRef = React.useRef<ReturnType<typeof setTimeout>>();\n const focusOnInput = React.useCallback(() => {\n clearTimeout(focusOnInputTimerRef.current);\n\n focusOnInputTimerRef.current = setTimeout(() => {\n selectInputRef.current && selectInputRef.current.focus();\n }, 0);\n }, []);\n useIsomorphicLayoutEffect(function clearFocusOnInputTimer() {\n return () => {\n clearTimeout(focusOnInputTimerRef.current);\n };\n }, []);\n\n const controlledValueSet = isControlledOutside && props.value !== '';\n const uncontrolledValueSet = !isControlledOutside && nativeSelectValue !== '';\n const clearButtonShown =\n allowClearButton && !opened && (controlledValueSet || uncontrolledValueSet);\n\n const clearButton = React.useMemo(() => {\n if (!clearButtonShown) {\n return null;\n }\n\n return (\n <ClearButton\n className={iconProp === undefined ? styles['CustomSelect--clear-icon'] : undefined}\n onClick={function clearSelectState() {\n setNativeSelectValue('');\n setInputValue('');\n focusOnInput();\n }}\n disabled={restProps.disabled}\n data-testid={clearButtonTestId}\n />\n );\n }, [\n clearButtonShown,\n ClearButton,\n iconProp,\n restProps.disabled,\n clearButtonTestId,\n focusOnInput,\n ]);\n\n const icon = React.useMemo(() => {\n if (iconProp !== undefined) {\n return iconProp;\n }\n\n return (\n <DropdownIcon\n className={clearButtonShown ? styles['CustomSelect__dropdown-icon'] : undefined}\n opened={opened}\n />\n );\n }, [clearButtonShown, iconProp, opened]);\n\n const afterIcons = (icon || clearButtonShown) && (\n <React.Fragment>\n {clearButton}\n {icon}\n </React.Fragment>\n );\n\n const { document } = useDOM();\n const passClickAndFocusToInputOnClick = React.useCallback(\n (e: React.MouseEvent<HTMLDivElement>) => {\n // Раньше внешней оберткой CustomSelect был <label>, что позволяло по клику в любую область CustomSelect,\n // даже где нету интерактивного элемента, фокусировать <input> и передавать на него событие клика.\n // Так как мы больше не оборачиваем CustomSelect в <label>, то для обертки CustomSelect мы симулируем работу <label>.\n // передаем фокус и клик по <input>, если пользователь кликнул в зоне обертки.\n // В <label> мы не больше не оборачиваем, потому что это заставляет скринридер\n // дважды произносить текст выбранной опции при фокусе, если CustomSelect связан с внешним <label>.\n // Воспроизводится в некоторых версиях Chrome, при навигации по странице с помощью стрелок.\n // Договорились со специалистом по доступности убрать <label>-обёртки из Select и CustomSelect\n\n if (!selectInputRef.current || !document) {\n return;\n }\n\n const clickTargetIsNotAnInput = e.target !== selectInputRef.current;\n if (clickTargetIsNotAnInput) {\n selectInputRef.current.click();\n\n const inputIsNotFocused = document.activeElement !== selectInputRef.current;\n if (inputIsNotFocused) {\n focusOnInput();\n }\n }\n },\n [document, focusOnInput],\n );\n\n const preventInputBlurWhenClickInsideFocusedSelectArea = (\n e: React.MouseEvent<HTMLDivElement>,\n ) => {\n // Так как инпут больше не оборачивается пустым лэйблом, то клик внутри обертки,\n // но вне инпута (например по иконке дропдауна), будет убирать фокус с инпута.\n // Чтобы в такой ситуации отключить blur инпута мы превентим mousedown событие обёртки\n const isInputFocused = document && document.activeElement === selectInputRef.current;\n if (isInputFocused) {\n e.preventDefault();\n }\n };\n\n const ariaActiveDescendantOptionIndex: undefined | number =\n focusedOptionIndex !== -1 ? focusedOptionIndex : undefined;\n const ariaActiveDescendantId =\n ariaActiveDescendantOptionIndex !== undefined\n ? options[ariaActiveDescendantOptionIndex] && options[ariaActiveDescendantOptionIndex].value\n : null;\n\n const selectInputAriaProps: React.HTMLAttributes<HTMLElement> = {\n 'role': 'combobox',\n 'aria-controls': popupAriaId,\n 'aria-owns': popupAriaId,\n 'aria-expanded': opened,\n ['aria-activedescendant']:\n ariaActiveDescendantId && opened ? `${popupAriaId}-${ariaActiveDescendantId}` : undefined,\n 'aria-labelledby': ariaLabelledBy,\n 'aria-haspopup': 'listbox',\n 'aria-autocomplete': 'none',\n };\n\n const focusWithin = useFocusWithin(handleRootRef);\n\n return (\n <div\n className={classNames(\n styles['CustomSelect'],\n sizeY !== 'regular' && sizeYClassNames[sizeY],\n className,\n )}\n style={style}\n ref={handleRootRef}\n onClick={passClickAndFocusToInputOnClick}\n onMouseDown={preventInputBlurWhenClickInsideFocusedSelectArea}\n >\n {focusWithin && selected && !opened && (\n <VisuallyHidden aria-live=\"polite\">{selected.label}</VisuallyHidden>\n )}\n <CustomSelectInput\n autoComplete=\"off\"\n autoCapitalize=\"none\"\n autoCorrect=\"off\"\n spellCheck=\"false\"\n {...restProps}\n {...selectInputAriaProps}\n getRef={selectInputRef}\n onFocus={onFocus}\n onBlur={onBlur}\n className={openedClassNames}\n readOnly={!searchable}\n fetching={fetching}\n value={inputValue}\n onKeyUp={handleKeyUp}\n onKeyDown={handleKeyDownSelect}\n onChange={onInputChange}\n onClick={onClick}\n before={before}\n after={afterIcons}\n selectType={selectType}\n >\n {selected?.label}\n </CustomSelectInput>\n <select\n ref={selectElRef}\n name={name}\n onChange={onNativeSelectChange}\n onBlur={props.onBlur}\n onFocus={props.onFocus}\n onClick={props.onClick}\n value={nativeSelectValue}\n aria-hidden\n className={styles['CustomSelect__control']}\n data-testid={nativeSelectTestId}\n required={required}\n >\n {allowClearButton && <option key=\"\" value=\"\" />}\n {optionsProp.map((item) => (\n <option key={`${item.value}`} value={item.value} />\n ))}\n </select>\n {opened && (\n <CustomSelectDropdown\n targetRef={containerRef}\n placement={popupDirection}\n scrollBoxRef={setScrollBoxRef}\n onPlacementChange={setPopperPlacement}\n onMouseLeave={resetFocusedOption}\n fetching={fetching}\n offsetDistance={dropdownOffsetDistance}\n autoWidth={dropdownAutoWidth}\n forcePortal={forceDropdownPortal}\n autoHideScrollbar={autoHideScrollbar}\n autoHideScrollbarDelay={autoHideScrollbarDelay}\n noMaxHeight={noMaxHeight}\n role=\"listbox\"\n id={popupAriaId}\n aria-labelledby={ariaLabelledBy}\n tabIndex={-1}\n >\n {resolvedContent}\n </CustomSelectDropdown>\n )}\n </div>\n );\n}\n"],"names":["React","classNames","useAdaptivity","useExternRef","useFocusWithin","useDOM","defaultFilterFn","useIsomorphicLayoutEffect","debounce","warnOnce","CustomSelectDropdown","CustomSelectOption","DropdownIcon","Footnote","VisuallyHidden","CustomSelectClearButton","CustomSelectInput","styles","sizeYClassNames","none","findIndexAfter","options","startIndex","length","findIndex","option","i","disabled","findIndexBefore","endIndex","result","warn","checkOptionsValueType","Set","map","item","value","size","defaultRenderOptionFn","props","handleOptionDown","e","preventDefault","findSelectedIndex","withClear","Number","filter","inputValue","filterFn","defaultOptions","CustomSelect","opened","setOpened","useState","before","name","className","getRef","getRootRef","popupDirection","style","onChange","children","onInputChange","onInputChangeProp","renderDropdown","onOpen","onClose","fetching","forceDropdownPortal","selectType","autoHideScrollbar","autoHideScrollbarDelay","searchable","renderOption","renderOptionProp","optionsProp","emptyText","icon","iconProp","ClearButton","allowClearButton","dropdownOffsetDistance","dropdownAutoWidth","noMaxHeight","ariaLabelledBy","clearButtonTestId","nativeSelectTestId","defaultValue","required","restProps","process","env","NODE_ENV","sizeY","containerRef","useRef","handleRootRef","scrollBoxRef","selectElRef","focusedOptionIndex","setFocusedOptionIndex","isControlledOutside","setIsControlledOutside","undefined","setInputValue","nativeSelectValue","setNativeSelectValue","popperPlacement","setPopperPlacement","setOptions","selectedOptionIndex","setSelectedOptionIndex","useEffect","some","event","Event","bubbles","current","dispatchEvent","selected","useMemo","openedClassNames","includes","scrollToElement","useCallback","index","center","dropdown","firstElementChild","dropdownHeight","offsetHeight","scrollTop","itemTop","offsetTop","itemHeight","focusOptionByIndex","scrollTo","isValidIndex","setScrollBoxRef","ref","keyboardInput","setKeyboardInput","resetKeyboardInput","resetFocusedOption","onKeyboardInput","key","fullInput","close","selectOption","shouldTriggerOnChangeWhenControlledAndInnerValueIsOutOfSync","selectFocused","open","onBlur","onFocus","onClick","handleKeyUp","focusOption","type","nextIndex","beforeIndex","updateOptionsAndSelectedOptionIndex","onNativeSelectChange","newSelectedOptionIndex","currentTarget","target","areOptionsShown","handleKeyDownSelect","handleOptionClick","Array","prototype","indexOf","call","parentNode","prevMousePositionRef","x","y","focusOptionOnMouseMove","isMouseChangedPosition","Math","abs","clientX","clientY","popupAriaId","useId","hovered","Fragment","label","onMouseDown","onMouseMove","id","resolvedContent","defaultDropdownContent","selectInputRef","focusOnInputTimerRef","focusOnInput","clearTimeout","setTimeout","focus","clearFocusOnInputTimer","controlledValueSet","uncontrolledValueSet","clearButtonShown","clearButton","clearSelectState","data-testid","afterIcons","document","passClickAndFocusToInputOnClick","clickTargetIsNotAnInput","click","inputIsNotFocused","activeElement","preventInputBlurWhenClickInsideFocusedSelectArea","isInputFocused","ariaActiveDescendantOptionIndex","ariaActiveDescendantId","selectInputAriaProps","focusWithin","div","aria-live","autoComplete","autoCapitalize","autoCorrect","spellCheck","readOnly","onKeyUp","onKeyDown","after","select","aria-hidden","targetRef","placement","onPlacementChange","onMouseLeave","offsetDistance","autoWidth","forcePortal","role","aria-labelledby","tabIndex"],"mappings":"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"}
@@ -61,6 +61,7 @@
61
61
 
62
62
  .CustomSelectOption__children {
63
63
  min-inline-size: 0;
64
+ word-break: break-word;
64
65
  }
65
66
 
66
67
  .CustomSelectOption__after {
@@ -28,7 +28,7 @@ const warn = warnOnce('GridAvatar');
28
28
  style: {
29
29
  backgroundImage: `url(${url})`
30
30
  }
31
- }, url) : null)
31
+ }, index) : null)
32
32
  }),
33
33
  children
34
34
  ]
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/GridAvatar/GridAvatar.tsx"],"sourcesContent":["import { classNames } from '@vkontakte/vkjs';\nimport { warnOnce } from '../../lib/warnOnce';\nimport { ImageBase, type ImageBaseProps } from '../ImageBase/ImageBase';\nimport { GridAvatarBadge, type GridAvatarBadgeProps } from './GridAvatarBadge/GridAvatarBadge';\nimport styles from './GridAvatar.module.css';\n\nexport { GridAvatarBadgeProps };\n\nexport const GRID_AVATAR_DEFAULT_SIZE = 48;\n\nexport const MAX_GRID_LENGTH = 4;\n\nexport interface GridAvatarProps extends Omit<ImageBaseProps, 'src' | 'fallbackIcon'> {\n /**\n * Массив со ссылками. От 1 до 4 элементов.\n */\n src?: string[];\n}\n\nconst warn = warnOnce('GridAvatar');\n\n/**\n * @see https://vkcom.github.io/VKUI/#/GridAvatar\n */\nexport const GridAvatar = ({\n src = [],\n size = GRID_AVATAR_DEFAULT_SIZE,\n className,\n children,\n ...restProps\n}: GridAvatarProps) => {\n if (process.env.NODE_ENV === 'development') {\n if (src.length > MAX_GRID_LENGTH) {\n warn(`Длина массива src (${src.length}) больше максимальной (${MAX_GRID_LENGTH})`, 'error');\n }\n }\n\n return (\n <ImageBase {...restProps} size={size} className={classNames(styles['GridAvatar'], className)}>\n <div className={styles['GridAvatar__in']} aria-hidden>\n {src.map((url, index) =>\n index < MAX_GRID_LENGTH ? (\n <div\n key={url}\n className={styles['GridAvatar__item']}\n style={{ backgroundImage: `url(${url})` }}\n />\n ) : null,\n )}\n </div>\n {children}\n </ImageBase>\n );\n};\n\nGridAvatar.Badge = GridAvatarBadge;\n"],"names":["classNames","warnOnce","ImageBase","GridAvatarBadge","styles","GRID_AVATAR_DEFAULT_SIZE","MAX_GRID_LENGTH","warn","GridAvatar","src","size","className","children","restProps","process","env","NODE_ENV","length","div","aria-hidden","map","url","index","style","backgroundImage","Badge"],"mappings":";AAAA,SAASA,UAAU,QAAQ,kBAAkB;AAC7C,SAASC,QAAQ,QAAQ,qBAAqB;AAC9C,SAASC,SAAS,QAA6B,yBAAyB;AACxE,SAASC,eAAe,QAAmC,oCAAoC;AAC/F,OAAOC,YAAY,0BAA0B;AAI7C,OAAO,MAAMC,2BAA2B,GAAG;AAE3C,OAAO,MAAMC,kBAAkB,EAAE;AASjC,MAAMC,OAAON,SAAS;AAEtB;;CAEC,GACD,OAAO,MAAMO,aAAa,CAAC,EACzBC,MAAM,EAAE,EACRC,OAAOL,wBAAwB,EAC/BM,SAAS,EACTC,QAAQ,EACR,GAAGC,WACa;IAChB,IAAIC,QAAQC,GAAG,CAACC,QAAQ,KAAK,eAAe;QAC1C,IAAIP,IAAIQ,MAAM,GAAGX,iBAAiB;YAChCC,KAAK,CAAC,mBAAmB,EAAEE,IAAIQ,MAAM,CAAC,uBAAuB,EAAEX,gBAAgB,CAAC,CAAC,EAAE;QACrF;IACF;IAEA,qBACE,MAACJ;QAAW,GAAGW,SAAS;QAAEH,MAAMA;QAAMC,WAAWX,WAAWI,MAAM,CAAC,aAAa,EAAEO;;0BAChF,KAACO;gBAAIP,WAAWP,MAAM,CAAC,iBAAiB;gBAAEe,aAAW;0BAClDV,IAAIW,GAAG,CAAC,CAACC,KAAKC,QACbA,QAAQhB,gCACN,KAACY;wBAECP,WAAWP,MAAM,CAAC,mBAAmB;wBACrCmB,OAAO;4BAAEC,iBAAiB,CAAC,IAAI,EAAEH,IAAI,CAAC,CAAC;wBAAC;uBAFnCA,OAIL;;YAGPT;;;AAGP,EAAE;AAEFJ,WAAWiB,KAAK,GAAGtB"}
1
+ {"version":3,"sources":["../../../../src/components/GridAvatar/GridAvatar.tsx"],"sourcesContent":["import { classNames } from '@vkontakte/vkjs';\nimport { warnOnce } from '../../lib/warnOnce';\nimport { ImageBase, type ImageBaseProps } from '../ImageBase/ImageBase';\nimport { GridAvatarBadge, type GridAvatarBadgeProps } from './GridAvatarBadge/GridAvatarBadge';\nimport styles from './GridAvatar.module.css';\n\nexport { GridAvatarBadgeProps };\n\nexport const GRID_AVATAR_DEFAULT_SIZE = 48;\n\nexport const MAX_GRID_LENGTH = 4;\n\nexport interface GridAvatarProps extends Omit<ImageBaseProps, 'src' | 'fallbackIcon'> {\n /**\n * Массив со ссылками. От 1 до 4 элементов.\n */\n src?: string[];\n}\n\nconst warn = warnOnce('GridAvatar');\n\n/**\n * @see https://vkcom.github.io/VKUI/#/GridAvatar\n */\nexport const GridAvatar = ({\n src = [],\n size = GRID_AVATAR_DEFAULT_SIZE,\n className,\n children,\n ...restProps\n}: GridAvatarProps) => {\n if (process.env.NODE_ENV === 'development') {\n if (src.length > MAX_GRID_LENGTH) {\n warn(`Длина массива src (${src.length}) больше максимальной (${MAX_GRID_LENGTH})`, 'error');\n }\n }\n\n return (\n <ImageBase {...restProps} size={size} className={classNames(styles['GridAvatar'], className)}>\n <div className={styles['GridAvatar__in']} aria-hidden>\n {src.map((url, index) =>\n index < MAX_GRID_LENGTH ? (\n <div\n key={index}\n className={styles['GridAvatar__item']}\n style={{ backgroundImage: `url(${url})` }}\n />\n ) : null,\n )}\n </div>\n {children}\n </ImageBase>\n );\n};\n\nGridAvatar.Badge = GridAvatarBadge;\n"],"names":["classNames","warnOnce","ImageBase","GridAvatarBadge","styles","GRID_AVATAR_DEFAULT_SIZE","MAX_GRID_LENGTH","warn","GridAvatar","src","size","className","children","restProps","process","env","NODE_ENV","length","div","aria-hidden","map","url","index","style","backgroundImage","Badge"],"mappings":";AAAA,SAASA,UAAU,QAAQ,kBAAkB;AAC7C,SAASC,QAAQ,QAAQ,qBAAqB;AAC9C,SAASC,SAAS,QAA6B,yBAAyB;AACxE,SAASC,eAAe,QAAmC,oCAAoC;AAC/F,OAAOC,YAAY,0BAA0B;AAI7C,OAAO,MAAMC,2BAA2B,GAAG;AAE3C,OAAO,MAAMC,kBAAkB,EAAE;AASjC,MAAMC,OAAON,SAAS;AAEtB;;CAEC,GACD,OAAO,MAAMO,aAAa,CAAC,EACzBC,MAAM,EAAE,EACRC,OAAOL,wBAAwB,EAC/BM,SAAS,EACTC,QAAQ,EACR,GAAGC,WACa;IAChB,IAAIC,QAAQC,GAAG,CAACC,QAAQ,KAAK,eAAe;QAC1C,IAAIP,IAAIQ,MAAM,GAAGX,iBAAiB;YAChCC,KAAK,CAAC,mBAAmB,EAAEE,IAAIQ,MAAM,CAAC,uBAAuB,EAAEX,gBAAgB,CAAC,CAAC,EAAE;QACrF;IACF;IAEA,qBACE,MAACJ;QAAW,GAAGW,SAAS;QAAEH,MAAMA;QAAMC,WAAWX,WAAWI,MAAM,CAAC,aAAa,EAAEO;;0BAChF,KAACO;gBAAIP,WAAWP,MAAM,CAAC,iBAAiB;gBAAEe,aAAW;0BAClDV,IAAIW,GAAG,CAAC,CAACC,KAAKC,QACbA,QAAQhB,gCACN,KAACY;wBAECP,WAAWP,MAAM,CAAC,mBAAmB;wBACrCmB,OAAO;4BAAEC,iBAAiB,CAAC,IAAI,EAAEH,IAAI,CAAC,CAAC;wBAAC;uBAFnCC,SAIL;;YAGPV;;;AAGP,EAAE;AAEFJ,WAAWiB,KAAK,GAAGtB"}
@@ -1,3 +1,4 @@
1
+ import * as React from 'react';
1
2
  import { type ImageBaseOverlayProps, type ImageBaseProps } from '../ImageBase/ImageBase';
2
3
  import { type ImageBadgeProps } from './ImageBadge/ImageBadge';
3
4
  export type { ImageBadgeProps, ImageBaseOverlayProps as ImageOverlayProps };
@@ -18,9 +19,6 @@ export declare const Image: {
18
19
  ({ className, ...restProps }: ImageBadgeProps): import("react/jsx-runtime").JSX.Element;
19
20
  displayName: string;
20
21
  };
21
- Overlay: {
22
- ({ className, theme: themeProp, visibility: visibilityProp, children, onClick: onClickProp, ...restProps }: ImageBaseOverlayProps): import("react/jsx-runtime").JSX.Element;
23
- displayName: string;
24
- };
22
+ Overlay: React.FC<ImageBaseOverlayProps>;
25
23
  };
26
24
  //# sourceMappingURL=Image.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Image.d.ts","sourceRoot":"","sources":["../../../../src/components/Image/Image.tsx"],"names":[],"mappings":"AACA,OAAO,EAAa,KAAK,qBAAqB,EAAE,KAAK,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACpG,OAAO,EAAc,KAAK,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE3E,YAAY,EAAE,eAAe,EAAE,qBAAqB,IAAI,iBAAiB,EAAE,CAAC;AAE5E,eAAO,MAAM,kBAAkB,KAAK,CAAC;AAErC,MAAM,WAAW,UAAW,SAAQ,IAAI,CAAC,cAAc,EAAE,OAAO,CAAC;IAC/D;;OAEG;IACH,YAAY,CAAC,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;CAChC;AA0DD;;GAEG;AACH,eAAO,MAAM,KAAK;+EAMf,UAAU;;;;;;;;;;CAcZ,CAAC"}
1
+ {"version":3,"file":"Image.d.ts","sourceRoot":"","sources":["../../../../src/components/Image/Image.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAa,KAAK,qBAAqB,EAAE,KAAK,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACpG,OAAO,EAAc,KAAK,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE3E,YAAY,EAAE,eAAe,EAAE,qBAAqB,IAAI,iBAAiB,EAAE,CAAC;AAE5E,eAAO,MAAM,kBAAkB,KAAK,CAAC;AAErC,MAAM,WAAW,UAAW,SAAQ,IAAI,CAAC,cAAc,EAAE,OAAO,CAAC;IAC/D;;OAEG;IACH,YAAY,CAAC,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;CAChC;AA0DD;;GAEG;AACH,eAAO,MAAM,KAAK;+EAMf,UAAU;;;;;;;CAcZ,CAAC"}
@@ -58,9 +58,6 @@ export declare const ImageBase: {
58
58
  ({ background, ...restProps }: ImageBaseBadgeProps): import("react/jsx-runtime").JSX.Element;
59
59
  displayName: string;
60
60
  };
61
- Overlay: {
62
- ({ className, theme: themeProp, visibility: visibilityProp, children, onClick: onClickProp, ...restProps }: ImageBaseOverlayProps): import("react/jsx-runtime").JSX.Element;
63
- displayName: string;
64
- };
61
+ Overlay: React.FC<ImageBaseOverlayProps>;
65
62
  };
66
63
  //# sourceMappingURL=ImageBase.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ImageBase.d.ts","sourceRoot":"","sources":["../../../../src/components/ImageBase/ImageBase.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAK/B,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE9F,OAAO,EAAkB,KAAK,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAC3F,OAAO,EAAoB,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,GACtB,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,CAAC;IACnB;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;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;CACrC;AAED;;GAEG;AACH,eAAO,MAAM,SAAS;iTAyBnB,cAAc;;;;;;;;;;CA2FhB,CAAC"}
1
+ {"version":3,"file":"ImageBase.d.ts","sourceRoot":"","sources":["../../../../src/components/ImageBase/ImageBase.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAK/B,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE9F,OAAO,EAAkB,KAAK,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAC3F,OAAO,EAAoB,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,GACtB,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,CAAC;IACnB;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;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;CACrC;AAED;;GAEG;AACH,eAAO,MAAM,SAAS;iTAyBnB,cAAc;;;;;;;CA2FhB,CAAC"}
@@ -1,42 +1,8 @@
1
1
  import * as React from 'react';
2
- import type { ImageBaseExpectedIconProps } from '../types';
3
- export interface ImageBaseOverlayProps extends React.AriaAttributes {
4
- /**
5
- * Задаёт тему оформления.
6
- *
7
- * > По умолчанию берётся из параметра `appearance` в `ConfigProvider`.
8
- */
9
- theme?: 'dark' | 'light';
10
- /**
11
- * Определяет каким образом должен показываться оверлей.
12
- *
13
- * - `"on-hover"` – на наведение указателя мыши.
14
- * - `"always"` – всегда показывать.
15
- *
16
- * > По умолчанию определяется в зависимости от того, есть ли у пользователя мышь или нет.
17
- */
18
- visibility?: 'on-hover' | 'always';
19
- /**
20
- * Принимает иконку.
21
- *
22
- *
23
- * > 📝 Нужный для `<ImageBase size={...} />` размер можно узнать из функции `getOverlayIconSizeByImageBaseSize()`.
24
- *
25
- * > Предпочтительней использовать иконки из `@vkontakte/icons`.
26
- *
27
- * > 📊️ Если вы хотите передать кастомную иконку, то следует именовать её по шаблону `Icon<size><name>`. Или же
28
- * > чтобы в неё был передан параметр `width`. Тогда мы сможем выводить в консоль подсказку правильного ли размера вы
29
- * > использовали иконку.
30
- */
31
- children: React.ReactElement<ImageBaseExpectedIconProps>;
32
- className?: string;
33
- onClick?: React.MouseEventHandler<HTMLElement>;
34
- }
2
+ import type { ImageBaseOverlayInteractiveProps, ImageBaseOverlayNonInteractiveProps } from './types';
3
+ export type ImageBaseOverlayProps = ImageBaseOverlayInteractiveProps | ImageBaseOverlayNonInteractiveProps;
35
4
  /**
36
- * Интерактивный оверлей над картинкой.
5
+ * Оверлей над картинкой.
37
6
  */
38
- export declare const ImageBaseOverlay: {
39
- ({ className, theme: themeProp, visibility: visibilityProp, children, onClick: onClickProp, ...restProps }: ImageBaseOverlayProps): import("react/jsx-runtime").JSX.Element;
40
- displayName: string;
41
- };
7
+ export declare const ImageBaseOverlay: React.FC<ImageBaseOverlayProps>;
42
8
  //# sourceMappingURL=ImageBaseOverlay.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ImageBaseOverlay.d.ts","sourceRoot":"","sources":["../../../../../src/components/ImageBase/ImageBaseOverlay/ImageBaseOverlay.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAO/B,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,UAAU,CAAC;AAI3D,MAAM,WAAW,qBAAsB,SAAQ,KAAK,CAAC,cAAc;IACjE;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACzB;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,UAAU,GAAG,QAAQ,CAAC;IACnC;;;;;;;;;;;OAWG;IACH,QAAQ,EAAE,KAAK,CAAC,YAAY,CAAC,0BAA0B,CAAC,CAAC;IACzD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC;CAChD;AAED;;GAEG;AACH,eAAO,MAAM,gBAAgB;gHAO1B,qBAAqB;;CAsCvB,CAAC"}
1
+ {"version":3,"file":"ImageBaseOverlay.d.ts","sourceRoot":"","sources":["../../../../../src/components/ImageBase/ImageBaseOverlay/ImageBaseOverlay.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAW/B,OAAO,KAAK,EACV,gCAAgC,EAChC,mCAAmC,EACpC,MAAM,SAAS,CAAC;AAGjB,MAAM,MAAM,qBAAqB,GAC7B,gCAAgC,GAChC,mCAAmC,CAAC;AAiExC;;GAEG;AACH,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CA6B5D,CAAC"}
@@ -1,20 +1,23 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import * as React from 'react';
3
- import { classNames, noop } from '@vkontakte/vkjs';
3
+ import { classNames } from '@vkontakte/vkjs';
4
+ import { useKeyboard } from '../../../components/Clickable/useKeyboard';
4
5
  import { useAdaptivityHasPointer } from '../../../hooks/useAdaptivityHasPointer';
5
6
  import { useAppearance } from '../../../hooks/useAppearance';
6
- import { focusVisiblePresetModeClassNames } from '../../../hooks/useFocusVisibleClassName';
7
- import { Tappable } from '../../Tappable/Tappable';
7
+ import { useExternRef } from '../../../hooks/useExternRef';
8
+ import { useFocusVisible } from '../../../hooks/useFocusVisible';
9
+ import { useFocusVisibleClassName } from '../../../hooks/useFocusVisibleClassName';
8
10
  import { ImageBaseContext } from '../context';
9
11
  import { validateOverlayIcon } from '../validators';
12
+ import { useNonInteractiveOverlayProps } from './hooks';
10
13
  import styles from './ImageBaseOverlay.module.css';
11
- /**
12
- * Интерактивный оверлей над картинкой.
13
- */ export const ImageBaseOverlay = ({ className, theme: themeProp, visibility: visibilityProp, children, onClick: onClickProp, ...restProps })=>{
14
- const appearance = useAppearance();
15
- const hasPointer = useAdaptivityHasPointer();
16
- const theme = themeProp ?? appearance;
17
- const visibility = visibilityProp ?? (hasPointer ? 'on-hover' : 'always');
14
+ const ImageBaseOverlayInteractive = ({ children, className, getRootRef, disableInteractive, overlayShown, ...restProps })=>{
15
+ const { focusVisible, ...focusEvents } = useFocusVisible();
16
+ const focusVisibleClassNames = useFocusVisibleClassName({
17
+ focusVisible,
18
+ mode: 'inside'
19
+ });
20
+ const keyboardHandlers = useKeyboard();
18
21
  if (process.env.NODE_ENV === 'development') {
19
22
  if (children) {
20
23
  // eslint-disable-next-line react-hooks/rules-of-hooks
@@ -25,18 +28,51 @@ import styles from './ImageBaseOverlay.module.css';
25
28
  });
26
29
  }
27
30
  }
28
- const onClick = onClickProp ?? visibility === 'on-hover' ? noop : undefined;
29
- return /*#__PURE__*/ _jsx(Tappable, {
31
+ return /*#__PURE__*/ _jsx("div", {
30
32
  ...restProps,
31
- className: classNames(styles['ImageBaseOverlay'], visibility === 'always' && styles['ImageBaseOverlay--visible'], theme === 'light' && styles['ImageBaseOverlay--theme-light'], theme === 'dark' && styles['ImageBaseOverlay--theme-dark'], className),
32
- hasHover: visibility === 'on-hover',
33
- hoverMode: visibility === 'on-hover' ? styles['ImageBaseOverlay--visible'] : undefined,
34
- focusVisibleMode: classNames(focusVisiblePresetModeClassNames['inside'], styles['ImageBaseOverlay--visible']),
35
- hasActive: false,
36
- onClick: onClick,
33
+ tabIndex: 0,
34
+ role: "button",
35
+ className: classNames(styles['ImageBaseOverlay--clickable'], (focusVisible || overlayShown) && styles['ImageBaseOverlay--visible'], focusVisibleClassNames, className),
36
+ ref: getRootRef,
37
+ ...focusEvents,
38
+ ...keyboardHandlers,
37
39
  children: children
38
40
  });
39
41
  };
42
+ const ImageBaseOverlayNonInteractive = ({ className, getRootRef, disableInteractive, overlayShown: overlayShownProps, ...restProps })=>{
43
+ const rootRef = useExternRef(getRootRef);
44
+ const { shown: overlayShown, onClick: onOverlayClick } = useNonInteractiveOverlayProps(rootRef);
45
+ return /*#__PURE__*/ _jsx("div", {
46
+ ...restProps,
47
+ ref: rootRef,
48
+ className: classNames((overlayShown || overlayShownProps) && styles['ImageBaseOverlay--visible'], className),
49
+ onClick: onOverlayClick
50
+ });
51
+ };
52
+ /**
53
+ * Оверлей над картинкой.
54
+ */ export const ImageBaseOverlay = ({ className, theme: themeProp, visibility: visibilityProp, ...restProps })=>{
55
+ const appearance = useAppearance();
56
+ const hasPointer = useAdaptivityHasPointer();
57
+ const theme = themeProp ?? appearance;
58
+ const visibility = visibilityProp ?? (hasPointer ? 'on-hover' : 'always');
59
+ const commonClassNames = classNames(styles['ImageBaseOverlay'], theme === 'light' && styles['ImageBaseOverlay--theme-light'], theme === 'dark' && styles['ImageBaseOverlay--theme-dark'], className);
60
+ const commonProps = {
61
+ className: commonClassNames,
62
+ overlayShown: visibility === 'always'
63
+ };
64
+ // Не делаем деструктуризацию пропа, потому что Typescript не вывозит
65
+ if (restProps.disableInteractive) {
66
+ return /*#__PURE__*/ _jsx(ImageBaseOverlayNonInteractive, {
67
+ ...restProps,
68
+ ...commonProps
69
+ });
70
+ }
71
+ return /*#__PURE__*/ _jsx(ImageBaseOverlayInteractive, {
72
+ ...restProps,
73
+ ...commonProps
74
+ });
75
+ };
40
76
  ImageBaseOverlay.displayName = 'ImageBaseOverlay';
41
77
 
42
78
  //# sourceMappingURL=ImageBaseOverlay.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/components/ImageBase/ImageBaseOverlay/ImageBaseOverlay.tsx"],"sourcesContent":["import * as React from 'react';\nimport { classNames, noop } from '@vkontakte/vkjs';\nimport { useAdaptivityHasPointer } from '../../../hooks/useAdaptivityHasPointer';\nimport { useAppearance } from '../../../hooks/useAppearance';\nimport { focusVisiblePresetModeClassNames } from '../../../hooks/useFocusVisibleClassName';\nimport { Tappable } from '../../Tappable/Tappable';\nimport { ImageBaseContext } from '../context';\nimport type { ImageBaseExpectedIconProps } from '../types';\nimport { validateOverlayIcon } from '../validators';\nimport styles from './ImageBaseOverlay.module.css';\n\nexport interface ImageBaseOverlayProps extends React.AriaAttributes {\n /**\n * Задаёт тему оформления.\n *\n * > По умолчанию берётся из параметра `appearance` в `ConfigProvider`.\n */\n theme?: 'dark' | 'light';\n /**\n * Определяет каким образом должен показываться оверлей.\n *\n * - `\"on-hover\"` на наведение указателя мыши.\n * - `\"always\"` – всегда показывать.\n *\n * > По умолчанию определяется в зависимости от того, есть ли у пользователя мышь или нет.\n */\n visibility?: 'on-hover' | 'always';\n /**\n * Принимает иконку.\n *\n *\n * > 📝 Нужный для `<ImageBase size={...} />` размер можно узнать из функции `getOverlayIconSizeByImageBaseSize()`.\n *\n * > Предпочтительней использовать иконки из `@vkontakte/icons`.\n *\n * > 📊️ Если вы хотите передать кастомную иконку, то следует именовать её по шаблону `Icon<size><name>`. Или же\n * > чтобы в неё был передан параметр `width`. Тогда мы сможем выводить в консоль подсказку правильного ли размера вы\n * > использовали иконку.\n */\n children: React.ReactElement<ImageBaseExpectedIconProps>;\n className?: string;\n onClick?: React.MouseEventHandler<HTMLElement>;\n}\n\n/**\n * Интерактивный оверлей над картинкой.\n */\nexport const ImageBaseOverlay = ({\n className,\n theme: themeProp,\n visibility: visibilityProp,\n children,\n onClick: onClickProp,\n ...restProps\n}: ImageBaseOverlayProps) => {\n const appearance = useAppearance();\n const hasPointer = useAdaptivityHasPointer();\n const theme = themeProp ?? appearance;\n const visibility = visibilityProp ?? (hasPointer ? 'on-hover' : 'always');\n\n if (process.env.NODE_ENV === 'development') {\n if (children) {\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const { size } = React.useContext(ImageBaseContext);\n validateOverlayIcon(size, { name: 'children', value: children });\n }\n }\n\n const onClick = onClickProp ?? visibility === 'on-hover' ? noop : undefined;\n\n return (\n <Tappable\n {...restProps}\n className={classNames(\n styles['ImageBaseOverlay'],\n visibility === 'always' && styles['ImageBaseOverlay--visible'],\n theme === 'light' && styles['ImageBaseOverlay--theme-light'],\n theme === 'dark' && styles['ImageBaseOverlay--theme-dark'],\n className,\n )}\n hasHover={visibility === 'on-hover'}\n hoverMode={visibility === 'on-hover' ? styles['ImageBaseOverlay--visible'] : undefined}\n focusVisibleMode={classNames(\n focusVisiblePresetModeClassNames['inside'],\n styles['ImageBaseOverlay--visible'],\n )}\n hasActive={false}\n onClick={onClick}\n >\n {children}\n </Tappable>\n );\n};\n\nImageBaseOverlay.displayName = 'ImageBaseOverlay';\n"],"names":["React","classNames","noop","useAdaptivityHasPointer","useAppearance","focusVisiblePresetModeClassNames","Tappable","ImageBaseContext","validateOverlayIcon","styles","ImageBaseOverlay","className","theme","themeProp","visibility","visibilityProp","children","onClick","onClickProp","restProps","appearance","hasPointer","process","env","NODE_ENV","size","useContext","name","value","undefined","hasHover","hoverMode","focusVisibleMode","hasActive","displayName"],"mappings":";AAAA,YAAYA,WAAW,QAAQ;AAC/B,SAASC,UAAU,EAAEC,IAAI,QAAQ,kBAAkB;AACnD,SAASC,uBAAuB,QAAQ,yCAAyC;AACjF,SAASC,aAAa,QAAQ,+BAA+B;AAC7D,SAASC,gCAAgC,QAAQ,0CAA0C;AAC3F,SAASC,QAAQ,QAAQ,0BAA0B;AACnD,SAASC,gBAAgB,QAAQ,aAAa;AAE9C,SAASC,mBAAmB,QAAQ,gBAAgB;AACpD,OAAOC,YAAY,gCAAgC;AAmCnD;;CAEC,GACD,OAAO,MAAMC,mBAAmB,CAAC,EAC/BC,SAAS,EACTC,OAAOC,SAAS,EAChBC,YAAYC,cAAc,EAC1BC,QAAQ,EACRC,SAASC,WAAW,EACpB,GAAGC,WACmB;IACtB,MAAMC,aAAahB;IACnB,MAAMiB,aAAalB;IACnB,MAAMS,QAAQC,aAAaO;IAC3B,MAAMN,aAAaC,kBAAmBM,CAAAA,aAAa,aAAa,QAAO;IAEvE,IAAIC,QAAQC,GAAG,CAACC,QAAQ,KAAK,eAAe;QAC1C,IAAIR,UAAU;YACZ,sDAAsD;YACtD,MAAM,EAAES,IAAI,EAAE,GAAGzB,MAAM0B,UAAU,CAACnB;YAClCC,oBAAoBiB,MAAM;gBAAEE,MAAM;gBAAYC,OAAOZ;YAAS;QAChE;IACF;IAEA,MAAMC,UAAUC,eAAeJ,eAAe,aAAaZ,OAAO2B;IAElE,qBACE,KAACvB;QACE,GAAGa,SAAS;QACbR,WAAWV,WACTQ,MAAM,CAAC,mBAAmB,EAC1BK,eAAe,YAAYL,MAAM,CAAC,4BAA4B,EAC9DG,UAAU,WAAWH,MAAM,CAAC,gCAAgC,EAC5DG,UAAU,UAAUH,MAAM,CAAC,+BAA+B,EAC1DE;QAEFmB,UAAUhB,eAAe;QACzBiB,WAAWjB,eAAe,aAAaL,MAAM,CAAC,4BAA4B,GAAGoB;QAC7EG,kBAAkB/B,WAChBI,gCAAgC,CAAC,SAAS,EAC1CI,MAAM,CAAC,4BAA4B;QAErCwB,WAAW;QACXhB,SAASA;kBAERD;;AAGP,EAAE;AAEFN,iBAAiBwB,WAAW,GAAG"}
1
+ {"version":3,"sources":["../../../../../src/components/ImageBase/ImageBaseOverlay/ImageBaseOverlay.tsx"],"sourcesContent":["import * as React from 'react';\nimport { classNames } from '@vkontakte/vkjs';\nimport { useKeyboard } from '../../../components/Clickable/useKeyboard';\nimport { useAdaptivityHasPointer } from '../../../hooks/useAdaptivityHasPointer';\nimport { useAppearance } from '../../../hooks/useAppearance';\nimport { useExternRef } from '../../../hooks/useExternRef';\nimport { useFocusVisible } from '../../../hooks/useFocusVisible';\nimport { useFocusVisibleClassName } from '../../../hooks/useFocusVisibleClassName';\nimport { ImageBaseContext } from '../context';\nimport { validateOverlayIcon } from '../validators';\nimport { useNonInteractiveOverlayProps } from './hooks';\nimport type {\n ImageBaseOverlayInteractiveProps,\n ImageBaseOverlayNonInteractiveProps,\n} from './types';\nimport styles from './ImageBaseOverlay.module.css';\n\nexport type ImageBaseOverlayProps =\n | ImageBaseOverlayInteractiveProps\n | ImageBaseOverlayNonInteractiveProps;\n\nconst ImageBaseOverlayInteractive = ({\n children,\n className,\n getRootRef,\n disableInteractive,\n overlayShown,\n ...restProps\n}: ImageBaseOverlayInteractiveProps & { overlayShown?: boolean }) => {\n const { focusVisible, ...focusEvents } = useFocusVisible();\n const focusVisibleClassNames = useFocusVisibleClassName({ focusVisible, mode: 'inside' });\n const keyboardHandlers = useKeyboard();\n\n if (process.env.NODE_ENV === 'development') {\n if (children) {\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const { size } = React.useContext(ImageBaseContext);\n validateOverlayIcon(size, { name: 'children', value: children });\n }\n }\n\n return (\n <div\n {...restProps}\n tabIndex={0}\n role=\"button\"\n className={classNames(\n styles['ImageBaseOverlay--clickable'],\n (focusVisible || overlayShown) && styles['ImageBaseOverlay--visible'],\n focusVisibleClassNames,\n className,\n )}\n ref={getRootRef}\n {...focusEvents}\n {...keyboardHandlers}\n >\n {children}\n </div>\n );\n};\n\nconst ImageBaseOverlayNonInteractive = ({\n className,\n getRootRef,\n disableInteractive,\n overlayShown: overlayShownProps,\n ...restProps\n}: ImageBaseOverlayNonInteractiveProps & { overlayShown?: boolean }) => {\n const rootRef = useExternRef(getRootRef);\n const { shown: overlayShown, onClick: onOverlayClick } = useNonInteractiveOverlayProps(rootRef);\n\n return (\n <div\n {...restProps}\n ref={rootRef}\n className={classNames(\n (overlayShown || overlayShownProps) && styles['ImageBaseOverlay--visible'],\n className,\n )}\n onClick={onOverlayClick}\n />\n );\n};\n\n/**\n * Оверлей над картинкой.\n */\nexport const ImageBaseOverlay: React.FC<ImageBaseOverlayProps> = ({\n className,\n theme: themeProp,\n visibility: visibilityProp,\n ...restProps\n}: ImageBaseOverlayProps) => {\n const appearance = useAppearance();\n const hasPointer = useAdaptivityHasPointer();\n const theme = themeProp ?? appearance;\n const visibility = visibilityProp ?? (hasPointer ? 'on-hover' : 'always');\n\n const commonClassNames = classNames(\n styles['ImageBaseOverlay'],\n theme === 'light' && styles['ImageBaseOverlay--theme-light'],\n theme === 'dark' && styles['ImageBaseOverlay--theme-dark'],\n className,\n );\n\n const commonProps = {\n className: commonClassNames,\n overlayShown: visibility === 'always',\n };\n\n // Не делаем деструктуризацию пропа, потому что Typescript не вывозит\n if (restProps.disableInteractive) {\n return <ImageBaseOverlayNonInteractive {...restProps} {...commonProps} />;\n }\n\n return <ImageBaseOverlayInteractive {...restProps} {...commonProps} />;\n};\n\nImageBaseOverlay.displayName = 'ImageBaseOverlay';\n"],"names":["React","classNames","useKeyboard","useAdaptivityHasPointer","useAppearance","useExternRef","useFocusVisible","useFocusVisibleClassName","ImageBaseContext","validateOverlayIcon","useNonInteractiveOverlayProps","styles","ImageBaseOverlayInteractive","children","className","getRootRef","disableInteractive","overlayShown","restProps","focusVisible","focusEvents","focusVisibleClassNames","mode","keyboardHandlers","process","env","NODE_ENV","size","useContext","name","value","div","tabIndex","role","ref","ImageBaseOverlayNonInteractive","overlayShownProps","rootRef","shown","onClick","onOverlayClick","ImageBaseOverlay","theme","themeProp","visibility","visibilityProp","appearance","hasPointer","commonClassNames","commonProps","displayName"],"mappings":";AAAA,YAAYA,WAAW,QAAQ;AAC/B,SAASC,UAAU,QAAQ,kBAAkB;AAC7C,SAASC,WAAW,QAAQ,4CAA4C;AACxE,SAASC,uBAAuB,QAAQ,yCAAyC;AACjF,SAASC,aAAa,QAAQ,+BAA+B;AAC7D,SAASC,YAAY,QAAQ,8BAA8B;AAC3D,SAASC,eAAe,QAAQ,iCAAiC;AACjE,SAASC,wBAAwB,QAAQ,0CAA0C;AACnF,SAASC,gBAAgB,QAAQ,aAAa;AAC9C,SAASC,mBAAmB,QAAQ,gBAAgB;AACpD,SAASC,6BAA6B,QAAQ,UAAU;AAKxD,OAAOC,YAAY,gCAAgC;AAMnD,MAAMC,8BAA8B,CAAC,EACnCC,QAAQ,EACRC,SAAS,EACTC,UAAU,EACVC,kBAAkB,EAClBC,YAAY,EACZ,GAAGC,WAC2D;IAC9D,MAAM,EAAEC,YAAY,EAAE,GAAGC,aAAa,GAAGd;IACzC,MAAMe,yBAAyBd,yBAAyB;QAAEY;QAAcG,MAAM;IAAS;IACvF,MAAMC,mBAAmBrB;IAEzB,IAAIsB,QAAQC,GAAG,CAACC,QAAQ,KAAK,eAAe;QAC1C,IAAIb,UAAU;YACZ,sDAAsD;YACtD,MAAM,EAAEc,IAAI,EAAE,GAAG3B,MAAM4B,UAAU,CAACpB;YAClCC,oBAAoBkB,MAAM;gBAAEE,MAAM;gBAAYC,OAAOjB;YAAS;QAChE;IACF;IAEA,qBACE,KAACkB;QACE,GAAGb,SAAS;QACbc,UAAU;QACVC,MAAK;QACLnB,WAAWb,WACTU,MAAM,CAAC,8BAA8B,EACrC,AAACQ,CAAAA,gBAAgBF,YAAW,KAAMN,MAAM,CAAC,4BAA4B,EACrEU,wBACAP;QAEFoB,KAAKnB;QACJ,GAAGK,WAAW;QACd,GAAGG,gBAAgB;kBAEnBV;;AAGP;AAEA,MAAMsB,iCAAiC,CAAC,EACtCrB,SAAS,EACTC,UAAU,EACVC,kBAAkB,EAClBC,cAAcmB,iBAAiB,EAC/B,GAAGlB,WAC8D;IACjE,MAAMmB,UAAUhC,aAAaU;IAC7B,MAAM,EAAEuB,OAAOrB,YAAY,EAAEsB,SAASC,cAAc,EAAE,GAAG9B,8BAA8B2B;IAEvF,qBACE,KAACN;QACE,GAAGb,SAAS;QACbgB,KAAKG;QACLvB,WAAWb,WACT,AAACgB,CAAAA,gBAAgBmB,iBAAgB,KAAMzB,MAAM,CAAC,4BAA4B,EAC1EG;QAEFyB,SAASC;;AAGf;AAEA;;CAEC,GACD,OAAO,MAAMC,mBAAoD,CAAC,EAChE3B,SAAS,EACT4B,OAAOC,SAAS,EAChBC,YAAYC,cAAc,EAC1B,GAAG3B,WACmB;IACtB,MAAM4B,aAAa1C;IACnB,MAAM2C,aAAa5C;IACnB,MAAMuC,QAAQC,aAAaG;IAC3B,MAAMF,aAAaC,kBAAmBE,CAAAA,aAAa,aAAa,QAAO;IAEvE,MAAMC,mBAAmB/C,WACvBU,MAAM,CAAC,mBAAmB,EAC1B+B,UAAU,WAAW/B,MAAM,CAAC,gCAAgC,EAC5D+B,UAAU,UAAU/B,MAAM,CAAC,+BAA+B,EAC1DG;IAGF,MAAMmC,cAAc;QAClBnC,WAAWkC;QACX/B,cAAc2B,eAAe;IAC/B;IAEA,qEAAqE;IACrE,IAAI1B,UAAUF,kBAAkB,EAAE;QAChC,qBAAO,KAACmB;YAAgC,GAAGjB,SAAS;YAAG,GAAG+B,WAAW;;IACvE;IAEA,qBAAO,KAACrC;QAA6B,GAAGM,SAAS;QAAG,GAAG+B,WAAW;;AACpE,EAAE;AAEFR,iBAAiBS,WAAW,GAAG"}
@@ -20,6 +20,16 @@
20
20
  opacity: 1;
21
21
  }
22
22
 
23
+ @media (hover: hover) and (pointer: fine) {
24
+ .ImageBaseOverlay:hover {
25
+ opacity: 1;
26
+ }
27
+ }
28
+
29
+ .ImageBaseOverlay--clickable {
30
+ cursor: pointer;
31
+ }
32
+
23
33
  .ImageBaseOverlay--theme-light {
24
34
  color: var(--vkui--color_icon_accent);
25
35
  background-color: var(--vkui--color_avatar_overlay_inverse_alpha);
@@ -0,0 +1,6 @@
1
+ import * as React from 'react';
2
+ export declare function useNonInteractiveOverlayProps(rootRef: React.MutableRefObject<HTMLElement | null>): {
3
+ shown: boolean;
4
+ onClick: (event: React.MouseEvent) => void;
5
+ };
6
+ //# sourceMappingURL=hooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../../../../src/components/ImageBase/ImageBaseOverlay/hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,wBAAgB,6BAA6B,CAAC,OAAO,EAAE,KAAK,CAAC,gBAAgB,CAAC,WAAW,GAAG,IAAI,CAAC;;qBAIvE,KAAK,CAAC,UAAU;EAiBzC"}