@vkontakte/vkui 5.5.2 → 5.5.4

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 (111) hide show
  1. package/dist/cjs/components/ChipsSelect/ChipsSelect.js +13 -9
  2. package/dist/cjs/components/ChipsSelect/ChipsSelect.js.map +1 -1
  3. package/dist/cjs/components/CustomSelect/CustomSelect.js +23 -17
  4. package/dist/cjs/components/CustomSelect/CustomSelect.js.map +1 -1
  5. package/dist/cjs/components/FixedLayout/FixedLayout.d.ts +6 -1
  6. package/dist/cjs/components/FixedLayout/FixedLayout.js +11 -4
  7. package/dist/cjs/components/FixedLayout/FixedLayout.js.map +1 -1
  8. package/dist/cjs/components/Group/Group.js +7 -5
  9. package/dist/cjs/components/Group/Group.js.map +1 -1
  10. package/dist/cjs/components/Header/Header.js +2 -2
  11. package/dist/cjs/components/Header/Header.js.map +1 -1
  12. package/dist/cjs/components/HorizontalScroll/HorizontalScroll.js +7 -7
  13. package/dist/cjs/components/HorizontalScroll/HorizontalScroll.js.map +1 -1
  14. package/dist/cjs/components/ImageBase/ImageBase.d.ts +2 -2
  15. package/dist/cjs/components/ImageBase/ImageBase.js.map +1 -1
  16. package/dist/cjs/components/PullToRefresh/PullToRefresh.js +2 -1
  17. package/dist/cjs/components/PullToRefresh/PullToRefresh.js.map +1 -1
  18. package/dist/cjs/components/ScreenSpinner/ScreenSpinner.js +3 -3
  19. package/dist/cjs/components/ScreenSpinner/ScreenSpinner.js.map +1 -1
  20. package/dist/cjs/components/Select/Select.d.ts +1 -1
  21. package/dist/cjs/components/Select/Select.js +22 -11
  22. package/dist/cjs/components/Select/Select.js.map +1 -1
  23. package/dist/cjs/components/Spinner/Spinner.d.ts +1 -1
  24. package/dist/cjs/components/Spinner/Spinner.js +14 -4
  25. package/dist/cjs/components/Spinner/Spinner.js.map +1 -1
  26. package/dist/cjs/components/Tappable/Tappable.d.ts +4 -4
  27. package/dist/cjs/components/Tappable/Tappable.js.map +1 -1
  28. package/dist/cjs/hooks/useAutoDetectAppearance.js +9 -13
  29. package/dist/cjs/hooks/useAutoDetectAppearance.js.map +1 -1
  30. package/dist/cjs/lib/platform.d.ts +2 -1
  31. package/dist/cjs/lib/platform.js.map +1 -1
  32. package/dist/cjs/types.d.ts +12 -0
  33. package/dist/cjs/types.js.map +1 -1
  34. package/dist/components/ChipsSelect/ChipsSelect.js +13 -9
  35. package/dist/components/ChipsSelect/ChipsSelect.js.map +1 -1
  36. package/dist/components/CustomSelect/CustomSelect.js +23 -17
  37. package/dist/components/CustomSelect/CustomSelect.js.map +1 -1
  38. package/dist/components/FixedLayout/FixedLayout.d.ts +6 -1
  39. package/dist/components/FixedLayout/FixedLayout.js +11 -4
  40. package/dist/components/FixedLayout/FixedLayout.js.map +1 -1
  41. package/dist/components/Group/Group.js +7 -5
  42. package/dist/components/Group/Group.js.map +1 -1
  43. package/dist/components/Header/Header.js +2 -2
  44. package/dist/components/Header/Header.js.map +1 -1
  45. package/dist/components/HorizontalScroll/HorizontalScroll.js +7 -7
  46. package/dist/components/HorizontalScroll/HorizontalScroll.js.map +1 -1
  47. package/dist/components/ImageBase/ImageBase.d.ts +2 -2
  48. package/dist/components/ImageBase/ImageBase.js.map +1 -1
  49. package/dist/components/PullToRefresh/PullToRefresh.js +2 -1
  50. package/dist/components/PullToRefresh/PullToRefresh.js.map +1 -1
  51. package/dist/components/ScreenSpinner/ScreenSpinner.js +3 -3
  52. package/dist/components/ScreenSpinner/ScreenSpinner.js.map +1 -1
  53. package/dist/components/Select/Select.d.ts +1 -1
  54. package/dist/components/Select/Select.js +22 -11
  55. package/dist/components/Select/Select.js.map +1 -1
  56. package/dist/components/Spinner/Spinner.d.ts +1 -1
  57. package/dist/components/Spinner/Spinner.js +14 -4
  58. package/dist/components/Spinner/Spinner.js.map +1 -1
  59. package/dist/components/Tappable/Tappable.d.ts +4 -4
  60. package/dist/components/Tappable/Tappable.js.map +1 -1
  61. package/dist/components.css +6 -6
  62. package/dist/components.css.map +1 -1
  63. package/dist/components.js.tmp +751 -739
  64. package/dist/cssm/components/ChipsSelect/ChipsSelect.js +13 -9
  65. package/dist/cssm/components/ChipsSelect/ChipsSelect.js.map +1 -1
  66. package/dist/cssm/components/CustomSelect/CustomSelect.js +22 -16
  67. package/dist/cssm/components/CustomSelect/CustomSelect.js.map +1 -1
  68. package/dist/cssm/components/FixedLayout/FixedLayout.d.ts +6 -1
  69. package/dist/cssm/components/FixedLayout/FixedLayout.js +8 -3
  70. package/dist/cssm/components/FixedLayout/FixedLayout.js.map +1 -1
  71. package/dist/cssm/components/Group/Group.js +6 -4
  72. package/dist/cssm/components/Group/Group.js.map +1 -1
  73. package/dist/cssm/components/Group/Group.module.css +34 -30
  74. package/dist/cssm/components/Header/Header.js +2 -2
  75. package/dist/cssm/components/Header/Header.js.map +1 -1
  76. package/dist/cssm/components/Header/Header.module.css +7 -9
  77. package/dist/cssm/components/HorizontalScroll/HorizontalScroll.js +7 -7
  78. package/dist/cssm/components/HorizontalScroll/HorizontalScroll.js.map +1 -1
  79. package/dist/cssm/components/HorizontalScroll/HorizontalScroll.module.css +2 -0
  80. package/dist/cssm/components/ImageBase/ImageBase.d.ts +2 -2
  81. package/dist/cssm/components/ImageBase/ImageBase.js.map +1 -1
  82. package/dist/cssm/components/PullToRefresh/PullToRefresh.js +2 -1
  83. package/dist/cssm/components/PullToRefresh/PullToRefresh.js.map +1 -1
  84. package/dist/cssm/components/ScreenSpinner/ScreenSpinner.js +3 -3
  85. package/dist/cssm/components/ScreenSpinner/ScreenSpinner.js.map +1 -1
  86. package/dist/cssm/components/ScreenSpinner/ScreenSpinner.module.css +4 -4
  87. package/dist/cssm/components/Select/Select.d.ts +1 -1
  88. package/dist/cssm/components/Select/Select.js +4 -9
  89. package/dist/cssm/components/Select/Select.js.map +1 -1
  90. package/dist/cssm/components/Spinner/Spinner.d.ts +1 -1
  91. package/dist/cssm/components/Spinner/Spinner.js +12 -3
  92. package/dist/cssm/components/Spinner/Spinner.js.map +1 -1
  93. package/dist/cssm/components/Tappable/Tappable.d.ts +4 -4
  94. package/dist/cssm/components/Tappable/Tappable.js.map +1 -1
  95. package/dist/cssm/hooks/useAutoDetectAppearance.js +9 -13
  96. package/dist/cssm/hooks/useAutoDetectAppearance.js.map +1 -1
  97. package/dist/cssm/lib/platform.d.ts +2 -1
  98. package/dist/cssm/lib/platform.js.map +1 -1
  99. package/dist/cssm/styles/constants.css +3 -0
  100. package/dist/cssm/types.d.ts +12 -0
  101. package/dist/cssm/types.js.map +1 -1
  102. package/dist/hooks/useAutoDetectAppearance.js +9 -13
  103. package/dist/hooks/useAutoDetectAppearance.js.map +1 -1
  104. package/dist/lib/platform.d.ts +2 -1
  105. package/dist/lib/platform.js.map +1 -1
  106. package/dist/types.d.ts +12 -0
  107. package/dist/types.js.map +1 -1
  108. package/dist/vkui.css +6 -6
  109. package/dist/vkui.css.map +1 -1
  110. package/dist/vkui.js.tmp +751 -739
  111. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/Tappable/Tappable.tsx"],"sourcesContent":["import * as React from 'react';\nimport { classNames, noop } from '@vkontakte/vkjs';\nimport mitt from 'mitt';\nimport { useAdaptivity } from '../../hooks/useAdaptivity';\nimport { useAdaptivityHasHover } from '../../hooks/useAdaptivityHasHover';\nimport { useAdaptivityHasPointer } from '../../hooks/useAdaptivityHasPointer';\nimport { useBooleanState } from '../../hooks/useBooleanState';\nimport { useExternRef } from '../../hooks/useExternRef';\nimport { useFocusVisible } from '../../hooks/useFocusVisible';\nimport { usePlatform } from '../../hooks/usePlatform';\nimport { useTimeout } from '../../hooks/useTimeout';\nimport { shouldTriggerClickOnEnterOrSpace } from '../../lib/accessibility';\nimport { SizeType } from '../../lib/adaptivity';\nimport { callMultiple } from '../../lib/callMultiple';\nimport { getOffsetRect } from '../../lib/offset';\nimport { Platform } from '../../lib/platform';\nimport { coordX, coordY } from '../../lib/touch';\nimport { useIsomorphicLayoutEffect } from '../../lib/useIsomorphicLayoutEffect';\nimport { AnchorHTMLAttributesOnly, HasChildren, HasComponent, HasRootRef } from '../../types';\nimport { FocusVisible, FocusVisibleMode } from '../FocusVisible/FocusVisible';\nimport { Touch, TouchEvent, TouchProps } from '../Touch/Touch';\nimport TouchRootContext from '../Touch/TouchContext';\nimport styles from './Tappable.module.css';\n\nconst sizeXClassNames = {\n none: styles['Tappable--sizeX-none'],\n compact: styles['Tappable--sizeX-compact'],\n};\n\ntype StateMode = 'opacity' | 'background';\n\nconst WAVE_LIVE = 225;\n\nexport type TappableElementProps = Omit<\n React.AllHTMLAttributes<HTMLElement>,\n | 'onTouchStart'\n | 'onTouchMove'\n | 'onTouchEnd'\n | 'onTouchCancel'\n | 'onMouseDown'\n | 'onMouseMove'\n | 'onMouseUp'\n | 'onMouseLeave'\n> &\n AnchorHTMLAttributesOnly; // В AllHTMLAttributes не хватает типов для ссылок\n\nexport interface TappableProps\n extends TappableElementProps,\n HasRootRef<HTMLElement>,\n HasComponent,\n HasChildren,\n Pick<TouchProps, 'onStart' | 'onEnd' | 'onMove'> {\n /**\n * Длительность показа active-состояния\n */\n activeEffectDelay?: number;\n stopPropagation?: boolean;\n /**\n * Указывает, должен ли компонент реагировать на hover-состояние\n */\n hasHover?: boolean;\n /**\n * Позволяет управлять hovered-состоянием извне\n */\n hovered?: boolean;\n /**\n * Указывает, должен ли компонент реагировать на active-состояние\n */\n hasActive?: boolean;\n /**\n * Стиль подсветки active-состояния. Если передать произвольную строку, она добавится как css-класс во время active\n */\n activeMode?: StateMode | string;\n /**\n * Стиль подсветки hover-состояния. Если передать произвольную строку, она добавится как css-класс во время hover\n */\n hoverMode?: StateMode | string;\n /**\n * Стиль аутлайна focus visible. Если передать произвольную строку, она добавится как css-класс во время focus-visible\n */\n focusVisibleMode?: FocusVisibleMode | string;\n onEnter?(outputEvent: MouseEvent): void;\n onLeave?(outputEvent: MouseEvent): void;\n}\n\ninterface Wave {\n x: number;\n y: number;\n id: number;\n}\n\nexport interface RootComponentProps extends TouchProps {\n ref?: React.Ref<HTMLElement>;\n}\n\nexport const ACTIVE_DELAY = 70;\nexport const ACTIVE_EFFECT_DELAY = 600;\n\nconst activeBus = mitt<{ active: string }>();\nconst TapState = { none: 0, pending: 1, active: 2, exiting: 3 } as const;\n\ntype TappableContextInterface = { onHoverChange: (s: boolean) => void };\nconst TappableContext = React.createContext<TappableContextInterface>({\n onHoverChange: noop,\n});\n\nfunction isPresetStateMode(stateMode: StateMode | string): stateMode is StateMode {\n switch (stateMode) {\n case 'opacity':\n case 'background':\n return true;\n default:\n return false;\n }\n}\n\nfunction useActivity(hasActive: boolean, stopDelay: number) {\n const id = React.useMemo(() => Math.round(Math.random() * 1e8).toString(16), []);\n\n const [activity, setActivity] = React.useState<(typeof TapState)[keyof typeof TapState]>(\n TapState.none,\n );\n const _stop = () => setActivity(TapState.none);\n const start = () => hasActive && setActivity(TapState.active);\n const delayStart = () => {\n hasActive && setActivity(TapState.pending);\n };\n\n const activeTimeout = useTimeout(start, ACTIVE_DELAY);\n const stopTimeout = useTimeout(_stop, stopDelay);\n\n useIsomorphicLayoutEffect(() => {\n if (activity === TapState.pending) {\n activeTimeout.set();\n return activeTimeout.clear;\n }\n if (activity === TapState.exiting) {\n return stopTimeout.clear;\n }\n if (activity === TapState.active) {\n activeBus.emit('active', id);\n }\n return noop;\n }, [activity]);\n\n useIsomorphicLayoutEffect(() => {\n if (activity === TapState.none) {\n return noop;\n }\n const onActiveChange = (activeId: string) => {\n activeId !== id && _stop();\n };\n activeBus.on('active', onActiveChange);\n return () => activeBus.off('active', onActiveChange);\n }, [activity === TapState.none]);\n\n useIsomorphicLayoutEffect(() => {\n !hasActive && _stop();\n }, [hasActive]);\n\n const stop = (delay?: number) => {\n if (delay) {\n setActivity(TapState.exiting);\n return stopTimeout.set(delay);\n }\n _stop();\n };\n\n return [activity, { delayStart, start, stop }] as const;\n}\n\n/**\n * @see https://vkcom.github.io/VKUI/#/Tappable\n */\nexport const Tappable = ({\n children,\n Component,\n onClick,\n onKeyDown: _onKeyDown,\n activeEffectDelay = ACTIVE_EFFECT_DELAY,\n stopPropagation = false,\n getRootRef,\n hasHover: _hasHover = true,\n hoverMode = 'background',\n hasActive: _hasActive = true,\n activeMode = 'background',\n focusVisibleMode = 'inside',\n onEnter,\n onLeave,\n className,\n hovered: hoveredProp,\n ...props\n}: TappableProps) => {\n Component = Component || ((props.href ? 'a' : 'div') as React.ElementType);\n\n const { onHoverChange } = React.useContext(TappableContext);\n const insideTouchRoot = React.useContext(TouchRootContext);\n const platform = usePlatform();\n const { focusVisible, onBlur, onFocus } = useFocusVisible();\n const { sizeX = 'none' } = useAdaptivity();\n const hasPointerContext = useAdaptivityHasPointer();\n const hasHoverContext = useAdaptivityHasHover();\n\n const [clicks, setClicks] = React.useState<Wave[]>([]);\n const [childHover, setChildHover] = React.useState(false);\n const {\n value: _hovered,\n setTrue: setHoveredTrue,\n setFalse: setHoveredFalse,\n } = useBooleanState(false);\n\n const hovered = (_hovered || hoveredProp) && !props.disabled;\n const hasActive = _hasActive && !childHover && !props.disabled;\n const hasHover = hasHoverContext && _hasHover && !childHover;\n const isCustomElement =\n Component !== 'a' && Component !== 'button' && Component !== 'label' && !props.contentEditable;\n const isPresetHoverMode = isPresetStateMode(hoverMode);\n const isPresetActiveMode = isPresetStateMode(activeMode);\n const isPresetFocusVisibleMode = ['inside', 'outside'].includes(focusVisibleMode);\n\n const [activity, { start, stop, delayStart }] = useActivity(hasActive, activeEffectDelay);\n const active = activity === TapState.active || activity === TapState.exiting;\n\n const containerRef = useExternRef(getRootRef);\n\n // hover propagation\n const childContext = React.useRef({ onHoverChange: setChildHover }).current;\n useIsomorphicLayoutEffect(() => {\n if (!hovered) {\n return noop;\n }\n onHoverChange(true);\n return () => onHoverChange(false);\n }, [hovered]);\n\n /*\n * [a11y]\n * Обрабатывает событие onkeydown\n * для кастомных доступных элементов:\n * - role=\"link\" (активация по Enter)\n * - role=\"button\" (активация по Space и Enter)\n */\n function onKeyDown(e: React.KeyboardEvent<HTMLElement>) {\n if (isCustomElement && shouldTriggerClickOnEnterOrSpace(e)) {\n e.preventDefault();\n containerRef.current?.click();\n }\n }\n\n const needWaves =\n platform === Platform.ANDROID && !hasPointerContext && hasActive && activeMode === 'background';\n\n const clearClicks = useTimeout(() => setClicks([]), WAVE_LIVE);\n\n function addClick(x: number, y: number) {\n const dateNow = Date.now();\n const filteredClicks = clicks.filter((click) => click.id + WAVE_LIVE > dateNow);\n\n setClicks([...filteredClicks, { x, y, id: dateNow }]);\n clearClicks.set();\n }\n\n function onStart({ originalEvent }: TouchEvent) {\n if (hasActive) {\n if (originalEvent.touches && originalEvent.touches.length > 1) {\n // r сожалению я так и не понял, что это делает и можно ли упихнуть его в Touch\n return stop();\n }\n\n if (needWaves) {\n const { top, left } = getOffsetRect(containerRef.current);\n const x = coordX(originalEvent) - (left ?? 0);\n const y = coordY(originalEvent) - (top ?? 0);\n addClick(x, y);\n }\n\n delayStart();\n }\n }\n\n function onMove({ isSlide }: TouchEvent) {\n if (isSlide) {\n stop();\n }\n }\n\n function onEnd({ duration }: TouchEvent) {\n if (activity === TapState.none) {\n return;\n }\n if (activity === TapState.pending) {\n // активировать при коротком тапе\n start();\n }\n\n // отключить без задержки при длинном тапе\n const activeDuration = duration - ACTIVE_DELAY;\n stop(activeDuration >= 100 ? 0 : activeEffectDelay - activeDuration);\n }\n\n const classes = classNames(\n className,\n styles['Tappable'],\n 'vkuiInternalTappable',\n platform === Platform.IOS && styles['Tappable--ios'],\n sizeX !== SizeType.REGULAR && sizeXClassNames[sizeX],\n hasHover && styles['Tappable--hasHover'],\n hasActive && styles['Tappable--hasActive'],\n hasHover && hovered && !isPresetHoverMode && hoverMode,\n hasActive && active && !isPresetActiveMode && activeMode,\n focusVisible && !isPresetFocusVisibleMode && focusVisibleMode,\n hasHover &&\n hovered &&\n isPresetHoverMode &&\n {\n background: styles['Tappable--hover-background'],\n opacity: styles['Tappable--hover-opacity'],\n }[hoverMode],\n hasActive &&\n active &&\n isPresetActiveMode &&\n {\n background: styles['Tappable--active-background'],\n opacity: styles['Tappable--active-opacity'],\n }[activeMode],\n focusVisible && styles['Tappable--focus-visible'],\n );\n\n const handlers: RootComponentProps = {\n onStart: callMultiple(onStart, props.onStart),\n onMove: callMultiple(onMove, props.onMove),\n onEnd: callMultiple(onEnd, props.onEnd),\n onClick,\n onKeyDown: callMultiple(onKeyDown, _onKeyDown),\n };\n const role = props.href ? 'link' : 'button';\n\n return (\n <Touch\n onEnter={callMultiple(setHoveredTrue, onEnter)}\n onLeave={callMultiple(setHoveredFalse, onLeave)}\n type={Component === 'button' ? 'button' : undefined}\n tabIndex={isCustomElement && !props.disabled ? 0 : undefined}\n role={isCustomElement ? role : undefined}\n aria-disabled={isCustomElement ? props.disabled : undefined}\n stopPropagation={stopPropagation && !insideTouchRoot && !props.disabled}\n {...props}\n slideThreshold={20}\n usePointerHover\n className={classes}\n Component={Component}\n getRootRef={containerRef}\n onBlur={callMultiple(onBlur, props.onBlur)}\n onFocus={callMultiple(onFocus, props.onFocus)}\n {...(props.disabled ? {} : handlers)}\n >\n <TappableContext.Provider value={childContext}>{children}</TappableContext.Provider>\n {needWaves && (\n <span aria-hidden className={styles.Tappable__waves}>\n {clicks.map((wave) => (\n <span\n key={wave.id}\n className={styles.Tappable__wave}\n style={{ top: wave.y, left: wave.x }}\n />\n ))}\n </span>\n )}\n {((hasHover && hoverMode === 'background') || (hasActive && activeMode === 'background')) && (\n <span aria-hidden className={styles.Tappable__stateLayer} />\n )}\n {!props.disabled && isPresetFocusVisibleMode && (\n <FocusVisible visible={focusVisible} mode={focusVisibleMode as FocusVisibleMode} />\n )}\n </Touch>\n );\n};\n"],"names":["ACTIVE_DELAY","ACTIVE_EFFECT_DELAY","Tappable","sizeXClassNames","none","compact","WAVE_LIVE","activeBus","mitt","TapState","pending","active","exiting","TappableContext","React","createContext","onHoverChange","noop","isPresetStateMode","stateMode","useActivity","hasActive","stopDelay","id","useMemo","Math","round","random","toString","useState","activity","setActivity","_stop","start","delayStart","activeTimeout","useTimeout","stopTimeout","useIsomorphicLayoutEffect","set","clear","emit","onActiveChange","activeId","on","off","stop","delay","onKeyDown","e","isCustomElement","shouldTriggerClickOnEnterOrSpace","containerRef","preventDefault","current","click","addClick","x","y","dateNow","Date","now","filteredClicks","clicks","filter","setClicks","clearClicks","onStart","originalEvent","touches","length","needWaves","getOffsetRect","top","left","coordX","coordY","onMove","isSlide","onEnd","duration","activeDuration","activeEffectDelay","children","Component","onClick","_onKeyDown","stopPropagation","getRootRef","_hasHover","hasHover","hoverMode","_hasActive","activeMode","focusVisibleMode","onEnter","onLeave","className","hovered","hoveredProp","props","href","useContext","insideTouchRoot","TouchRootContext","platform","usePlatform","useFocusVisible","focusVisible","onBlur","onFocus","useAdaptivity","sizeX","hasPointerContext","useAdaptivityHasPointer","hasHoverContext","useAdaptivityHasHover","childHover","setChildHover","useBooleanState","value","_hovered","setTrue","setHoveredTrue","setFalse","setHoveredFalse","disabled","contentEditable","isPresetHoverMode","isPresetActiveMode","isPresetFocusVisibleMode","includes","useExternRef","childContext","useRef","Platform","ANDROID","classes","classNames","IOS","SizeType","REGULAR","background","opacity","handlers","callMultiple","role","Touch","type","undefined","tabIndex","aria-disabled","slideThreshold","usePointerHover","Provider","span","aria-hidden","map","wave","key","style","FocusVisible","visible","mode"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../src/components/Tappable/Tappable.tsx"],"sourcesContent":["import * as React from 'react';\nimport { classNames, noop } from '@vkontakte/vkjs';\nimport mitt from 'mitt';\nimport { useAdaptivity } from '../../hooks/useAdaptivity';\nimport { useAdaptivityHasHover } from '../../hooks/useAdaptivityHasHover';\nimport { useAdaptivityHasPointer } from '../../hooks/useAdaptivityHasPointer';\nimport { useBooleanState } from '../../hooks/useBooleanState';\nimport { useExternRef } from '../../hooks/useExternRef';\nimport { useFocusVisible } from '../../hooks/useFocusVisible';\nimport { usePlatform } from '../../hooks/usePlatform';\nimport { useTimeout } from '../../hooks/useTimeout';\nimport { shouldTriggerClickOnEnterOrSpace } from '../../lib/accessibility';\nimport { SizeType } from '../../lib/adaptivity';\nimport { callMultiple } from '../../lib/callMultiple';\nimport { getOffsetRect } from '../../lib/offset';\nimport { Platform } from '../../lib/platform';\nimport { coordX, coordY } from '../../lib/touch';\nimport { useIsomorphicLayoutEffect } from '../../lib/useIsomorphicLayoutEffect';\nimport {\n AnchorHTMLAttributesOnly,\n HasChildren,\n HasComponent,\n HasRootRef,\n LiteralUnion,\n} from '../../types';\nimport { FocusVisible, FocusVisibleMode } from '../FocusVisible/FocusVisible';\nimport { Touch, TouchEvent, TouchProps } from '../Touch/Touch';\nimport TouchRootContext from '../Touch/TouchContext';\nimport styles from './Tappable.module.css';\n\nconst sizeXClassNames = {\n none: styles['Tappable--sizeX-none'],\n compact: styles['Tappable--sizeX-compact'],\n};\n\ntype StateMode = 'opacity' | 'background';\n\nconst WAVE_LIVE = 225;\n\nexport type TappableElementProps = Omit<\n React.AllHTMLAttributes<HTMLElement>,\n | 'onTouchStart'\n | 'onTouchMove'\n | 'onTouchEnd'\n | 'onTouchCancel'\n | 'onMouseDown'\n | 'onMouseMove'\n | 'onMouseUp'\n | 'onMouseLeave'\n> &\n AnchorHTMLAttributesOnly; // В AllHTMLAttributes не хватает типов для ссылок\n\nexport interface TappableProps\n extends TappableElementProps,\n HasRootRef<HTMLElement>,\n HasComponent,\n HasChildren,\n Pick<TouchProps, 'onStart' | 'onEnd' | 'onMove'> {\n /**\n * Длительность показа active-состояния\n */\n activeEffectDelay?: number;\n stopPropagation?: boolean;\n /**\n * Указывает, должен ли компонент реагировать на hover-состояние\n */\n hasHover?: boolean;\n /**\n * Позволяет управлять hovered-состоянием извне\n */\n hovered?: boolean;\n /**\n * Указывает, должен ли компонент реагировать на active-состояние\n */\n hasActive?: boolean;\n /**\n * Стиль подсветки active-состояния. Если передать произвольную строку, она добавится как css-класс во время active\n */\n activeMode?: LiteralUnion<StateMode, string>;\n /**\n * Стиль подсветки hover-состояния. Если передать произвольную строку, она добавится как css-класс во время hover\n */\n hoverMode?: LiteralUnion<StateMode, string>;\n /**\n * Стиль аутлайна focus visible. Если передать произвольную строку, она добавится как css-класс во время focus-visible\n */\n focusVisibleMode?: LiteralUnion<FocusVisibleMode, string>;\n onEnter?(outputEvent: MouseEvent): void;\n onLeave?(outputEvent: MouseEvent): void;\n}\n\ninterface Wave {\n x: number;\n y: number;\n id: number;\n}\n\nexport interface RootComponentProps extends TouchProps {\n ref?: React.Ref<HTMLElement>;\n}\n\nexport const ACTIVE_DELAY = 70;\nexport const ACTIVE_EFFECT_DELAY = 600;\n\nconst activeBus = mitt<{ active: string }>();\nconst TapState = { none: 0, pending: 1, active: 2, exiting: 3 } as const;\n\ntype TappableContextInterface = { onHoverChange: (s: boolean) => void };\nconst TappableContext = React.createContext<TappableContextInterface>({\n onHoverChange: noop,\n});\n\nfunction isPresetStateMode(stateMode: LiteralUnion<StateMode, string>): stateMode is StateMode {\n switch (stateMode) {\n case 'opacity':\n case 'background':\n return true;\n default:\n return false;\n }\n}\n\nfunction useActivity(hasActive: boolean, stopDelay: number) {\n const id = React.useMemo(() => Math.round(Math.random() * 1e8).toString(16), []);\n\n const [activity, setActivity] = React.useState<(typeof TapState)[keyof typeof TapState]>(\n TapState.none,\n );\n const _stop = () => setActivity(TapState.none);\n const start = () => hasActive && setActivity(TapState.active);\n const delayStart = () => {\n hasActive && setActivity(TapState.pending);\n };\n\n const activeTimeout = useTimeout(start, ACTIVE_DELAY);\n const stopTimeout = useTimeout(_stop, stopDelay);\n\n useIsomorphicLayoutEffect(() => {\n if (activity === TapState.pending) {\n activeTimeout.set();\n return activeTimeout.clear;\n }\n if (activity === TapState.exiting) {\n return stopTimeout.clear;\n }\n if (activity === TapState.active) {\n activeBus.emit('active', id);\n }\n return noop;\n }, [activity]);\n\n useIsomorphicLayoutEffect(() => {\n if (activity === TapState.none) {\n return noop;\n }\n const onActiveChange = (activeId: string) => {\n activeId !== id && _stop();\n };\n activeBus.on('active', onActiveChange);\n return () => activeBus.off('active', onActiveChange);\n }, [activity === TapState.none]);\n\n useIsomorphicLayoutEffect(() => {\n !hasActive && _stop();\n }, [hasActive]);\n\n const stop = (delay?: number) => {\n if (delay) {\n setActivity(TapState.exiting);\n return stopTimeout.set(delay);\n }\n _stop();\n };\n\n return [activity, { delayStart, start, stop }] as const;\n}\n\n/**\n * @see https://vkcom.github.io/VKUI/#/Tappable\n */\nexport const Tappable = ({\n children,\n Component,\n onClick,\n onKeyDown: _onKeyDown,\n activeEffectDelay = ACTIVE_EFFECT_DELAY,\n stopPropagation = false,\n getRootRef,\n hasHover: _hasHover = true,\n hoverMode = 'background',\n hasActive: _hasActive = true,\n activeMode = 'background',\n focusVisibleMode = 'inside',\n onEnter,\n onLeave,\n className,\n hovered: hoveredProp,\n ...props\n}: TappableProps) => {\n Component = Component || ((props.href ? 'a' : 'div') as React.ElementType);\n\n const { onHoverChange } = React.useContext(TappableContext);\n const insideTouchRoot = React.useContext(TouchRootContext);\n const platform = usePlatform();\n const { focusVisible, onBlur, onFocus } = useFocusVisible();\n const { sizeX = 'none' } = useAdaptivity();\n const hasPointerContext = useAdaptivityHasPointer();\n const hasHoverContext = useAdaptivityHasHover();\n\n const [clicks, setClicks] = React.useState<Wave[]>([]);\n const [childHover, setChildHover] = React.useState(false);\n const {\n value: _hovered,\n setTrue: setHoveredTrue,\n setFalse: setHoveredFalse,\n } = useBooleanState(false);\n\n const hovered = (_hovered || hoveredProp) && !props.disabled;\n const hasActive = _hasActive && !childHover && !props.disabled;\n const hasHover = hasHoverContext && _hasHover && !childHover;\n const isCustomElement =\n Component !== 'a' && Component !== 'button' && Component !== 'label' && !props.contentEditable;\n const isPresetHoverMode = isPresetStateMode(hoverMode);\n const isPresetActiveMode = isPresetStateMode(activeMode);\n const isPresetFocusVisibleMode = ['inside', 'outside'].includes(focusVisibleMode);\n\n const [activity, { start, stop, delayStart }] = useActivity(hasActive, activeEffectDelay);\n const active = activity === TapState.active || activity === TapState.exiting;\n\n const containerRef = useExternRef(getRootRef);\n\n // hover propagation\n const childContext = React.useRef({ onHoverChange: setChildHover }).current;\n useIsomorphicLayoutEffect(() => {\n if (!hovered) {\n return noop;\n }\n onHoverChange(true);\n return () => onHoverChange(false);\n }, [hovered]);\n\n /*\n * [a11y]\n * Обрабатывает событие onkeydown\n * для кастомных доступных элементов:\n * - role=\"link\" (активация по Enter)\n * - role=\"button\" (активация по Space и Enter)\n */\n function onKeyDown(e: React.KeyboardEvent<HTMLElement>) {\n if (isCustomElement && shouldTriggerClickOnEnterOrSpace(e)) {\n e.preventDefault();\n containerRef.current?.click();\n }\n }\n\n const needWaves =\n platform === Platform.ANDROID && !hasPointerContext && hasActive && activeMode === 'background';\n\n const clearClicks = useTimeout(() => setClicks([]), WAVE_LIVE);\n\n function addClick(x: number, y: number) {\n const dateNow = Date.now();\n const filteredClicks = clicks.filter((click) => click.id + WAVE_LIVE > dateNow);\n\n setClicks([...filteredClicks, { x, y, id: dateNow }]);\n clearClicks.set();\n }\n\n function onStart({ originalEvent }: TouchEvent) {\n if (hasActive) {\n if (originalEvent.touches && originalEvent.touches.length > 1) {\n // r сожалению я так и не понял, что это делает и можно ли упихнуть его в Touch\n return stop();\n }\n\n if (needWaves) {\n const { top, left } = getOffsetRect(containerRef.current);\n const x = coordX(originalEvent) - (left ?? 0);\n const y = coordY(originalEvent) - (top ?? 0);\n addClick(x, y);\n }\n\n delayStart();\n }\n }\n\n function onMove({ isSlide }: TouchEvent) {\n if (isSlide) {\n stop();\n }\n }\n\n function onEnd({ duration }: TouchEvent) {\n if (activity === TapState.none) {\n return;\n }\n if (activity === TapState.pending) {\n // активировать при коротком тапе\n start();\n }\n\n // отключить без задержки при длинном тапе\n const activeDuration = duration - ACTIVE_DELAY;\n stop(activeDuration >= 100 ? 0 : activeEffectDelay - activeDuration);\n }\n\n const classes = classNames(\n className,\n styles['Tappable'],\n 'vkuiInternalTappable',\n platform === Platform.IOS && styles['Tappable--ios'],\n sizeX !== SizeType.REGULAR && sizeXClassNames[sizeX],\n hasHover && styles['Tappable--hasHover'],\n hasActive && styles['Tappable--hasActive'],\n hasHover && hovered && !isPresetHoverMode && hoverMode,\n hasActive && active && !isPresetActiveMode && activeMode,\n focusVisible && !isPresetFocusVisibleMode && focusVisibleMode,\n hasHover &&\n hovered &&\n isPresetHoverMode &&\n {\n background: styles['Tappable--hover-background'],\n opacity: styles['Tappable--hover-opacity'],\n }[hoverMode],\n hasActive &&\n active &&\n isPresetActiveMode &&\n {\n background: styles['Tappable--active-background'],\n opacity: styles['Tappable--active-opacity'],\n }[activeMode],\n focusVisible && styles['Tappable--focus-visible'],\n );\n\n const handlers: RootComponentProps = {\n onStart: callMultiple(onStart, props.onStart),\n onMove: callMultiple(onMove, props.onMove),\n onEnd: callMultiple(onEnd, props.onEnd),\n onClick,\n onKeyDown: callMultiple(onKeyDown, _onKeyDown),\n };\n const role = props.href ? 'link' : 'button';\n\n return (\n <Touch\n onEnter={callMultiple(setHoveredTrue, onEnter)}\n onLeave={callMultiple(setHoveredFalse, onLeave)}\n type={Component === 'button' ? 'button' : undefined}\n tabIndex={isCustomElement && !props.disabled ? 0 : undefined}\n role={isCustomElement ? role : undefined}\n aria-disabled={isCustomElement ? props.disabled : undefined}\n stopPropagation={stopPropagation && !insideTouchRoot && !props.disabled}\n {...props}\n slideThreshold={20}\n usePointerHover\n className={classes}\n Component={Component}\n getRootRef={containerRef}\n onBlur={callMultiple(onBlur, props.onBlur)}\n onFocus={callMultiple(onFocus, props.onFocus)}\n {...(props.disabled ? {} : handlers)}\n >\n <TappableContext.Provider value={childContext}>{children}</TappableContext.Provider>\n {needWaves && (\n <span aria-hidden className={styles.Tappable__waves}>\n {clicks.map((wave) => (\n <span\n key={wave.id}\n className={styles.Tappable__wave}\n style={{ top: wave.y, left: wave.x }}\n />\n ))}\n </span>\n )}\n {((hasHover && hoverMode === 'background') || (hasActive && activeMode === 'background')) && (\n <span aria-hidden className={styles.Tappable__stateLayer} />\n )}\n {!props.disabled && isPresetFocusVisibleMode && (\n <FocusVisible visible={focusVisible} mode={focusVisibleMode as FocusVisibleMode} />\n )}\n </Touch>\n );\n};\n"],"names":["ACTIVE_DELAY","ACTIVE_EFFECT_DELAY","Tappable","sizeXClassNames","none","compact","WAVE_LIVE","activeBus","mitt","TapState","pending","active","exiting","TappableContext","React","createContext","onHoverChange","noop","isPresetStateMode","stateMode","useActivity","hasActive","stopDelay","id","useMemo","Math","round","random","toString","useState","activity","setActivity","_stop","start","delayStart","activeTimeout","useTimeout","stopTimeout","useIsomorphicLayoutEffect","set","clear","emit","onActiveChange","activeId","on","off","stop","delay","onKeyDown","e","isCustomElement","shouldTriggerClickOnEnterOrSpace","containerRef","preventDefault","current","click","addClick","x","y","dateNow","Date","now","filteredClicks","clicks","filter","setClicks","clearClicks","onStart","originalEvent","touches","length","needWaves","getOffsetRect","top","left","coordX","coordY","onMove","isSlide","onEnd","duration","activeDuration","activeEffectDelay","children","Component","onClick","_onKeyDown","stopPropagation","getRootRef","_hasHover","hasHover","hoverMode","_hasActive","activeMode","focusVisibleMode","onEnter","onLeave","className","hovered","hoveredProp","props","href","useContext","insideTouchRoot","TouchRootContext","platform","usePlatform","useFocusVisible","focusVisible","onBlur","onFocus","useAdaptivity","sizeX","hasPointerContext","useAdaptivityHasPointer","hasHoverContext","useAdaptivityHasHover","childHover","setChildHover","useBooleanState","value","_hovered","setTrue","setHoveredTrue","setFalse","setHoveredFalse","disabled","contentEditable","isPresetHoverMode","isPresetActiveMode","isPresetFocusVisibleMode","includes","useExternRef","childContext","useRef","Platform","ANDROID","classes","classNames","IOS","SizeType","REGULAR","background","opacity","handlers","callMultiple","role","Touch","type","undefined","tabIndex","aria-disabled","slideThreshold","usePointerHover","Provider","span","aria-hidden","map","wave","key","style","FocusVisible","visible","mode"],"mappings":"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"}
@@ -17,23 +17,23 @@ var _vkjs = require("@vkontakte/vkjs");
17
17
  var _appearance = require("../helpers/appearance");
18
18
  var _dom = require("../lib/dom");
19
19
  var _matchMedia = require("../lib/matchMedia");
20
- var initialAppearance = null;
21
- _vkbridge.default.send("VKWebAppGetConfig").then(function(data) {
22
- initialAppearance = (0, _appearance.resolveAppearance)(data);
23
- }).catch(console.error);
24
20
  function autoDetectAppearanceByBridge(setAppearance, onDetectAppearanceByBridge) {
21
+ var updateAppearance = function updateAppearance(data) {
22
+ var initialAppearance = (0, _appearance.resolveAppearance)(data);
23
+ if (initialAppearance) {
24
+ onDetectAppearanceByBridge();
25
+ setAppearance(initialAppearance);
26
+ }
27
+ };
25
28
  var bridgeListener = function bridgeListener(e) {
26
29
  var _e_detail = e.detail, type = _e_detail.type, data = _e_detail.data;
27
30
  if (type !== "VKWebAppUpdateConfig") {
28
31
  return;
29
32
  }
30
- initialAppearance = (0, _appearance.resolveAppearance)(data);
31
- if (initialAppearance) {
32
- onDetectAppearanceByBridge();
33
- setAppearance(initialAppearance);
34
- }
33
+ updateAppearance(data);
35
34
  };
36
35
  _vkbridge.default.subscribe(bridgeListener);
36
+ _vkbridge.default.send("VKWebAppGetConfig").then(updateAppearance).catch(console.error);
37
37
  return function() {
38
38
  return _vkbridge.default.unsubscribe(bridgeListener);
39
39
  };
@@ -63,10 +63,6 @@ var useAutoDetectAppearance = function(appearanceProp, onDetectAppearanceByBridg
63
63
  if (appearanceProp) {
64
64
  return appearanceProp;
65
65
  }
66
- if (initialAppearance) {
67
- onceDetectAppearanceByBridge.current();
68
- return initialAppearance;
69
- }
70
66
  var mediaQuery = window && window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)");
71
67
  // eslint-disable-next-line no-restricted-properties
72
68
  return (mediaQuery === null || mediaQuery === void 0 ? void 0 : mediaQuery.matches) ? "dark" : "light";
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/hooks/useAutoDetectAppearance.tsx"],"sourcesContent":["import * as React from 'react';\nimport vkBridge, {\n AnyReceiveMethodName,\n AppearanceType,\n VKBridgeEvent,\n} from '@vkontakte/vk-bridge';\nimport { noop } from '@vkontakte/vkjs';\nimport { resolveAppearance, VKBridgeConfigData } from '../helpers/appearance';\nimport { useDOM } from '../lib/dom';\nimport { matchMediaListAddListener, matchMediaListRemoveListener } from '../lib/matchMedia';\n\nlet initialAppearance: AppearanceType | null = null;\n\nvkBridge\n .send('VKWebAppGetConfig')\n .then((data) => {\n initialAppearance = resolveAppearance(data);\n })\n .catch(console.error);\n\nfunction autoDetectAppearanceByBridge(\n setAppearance: (value: AppearanceType) => void,\n onDetectAppearanceByBridge: () => void,\n) {\n function bridgeListener(e: VKBridgeEvent<AnyReceiveMethodName>) {\n const { type, data } = e.detail;\n\n if (type !== 'VKWebAppUpdateConfig') {\n return;\n }\n\n initialAppearance = resolveAppearance(data as VKBridgeConfigData);\n\n if (initialAppearance) {\n onDetectAppearanceByBridge();\n setAppearance(initialAppearance);\n }\n }\n\n vkBridge.subscribe(bridgeListener);\n\n return () => vkBridge.unsubscribe(bridgeListener);\n}\n\nfunction autoDetectAppearance(\n window: Window | undefined,\n setAppearance: (value: AppearanceType) => void,\n): () => void {\n const mediaQuery =\n window && window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)');\n\n if (mediaQuery === undefined) {\n return noop;\n }\n\n const check = (event: MediaQueryList | MediaQueryListEvent) => {\n // eslint-disable-next-line no-restricted-properties\n setAppearance(event.matches ? 'dark' : 'light');\n };\n\n check(mediaQuery);\n matchMediaListAddListener(mediaQuery, check);\n\n return () => matchMediaListRemoveListener(mediaQuery, check);\n}\n\nexport const useAutoDetectAppearance = (\n appearanceProp?: AppearanceType,\n onDetectAppearanceByBridge?: () => void,\n): AppearanceType => {\n const { window } = useDOM();\n const onceDetectAppearanceByBridge = React.useRef(() => {\n onDetectAppearanceByBridge && onDetectAppearanceByBridge();\n onceDetectAppearanceByBridge.current = noop;\n });\n\n const [appearance, setAppearance] = React.useState<AppearanceType>(() => {\n if (appearanceProp) {\n return appearanceProp;\n }\n\n if (initialAppearance) {\n onceDetectAppearanceByBridge.current();\n return initialAppearance;\n }\n\n const mediaQuery =\n window && window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)');\n\n // eslint-disable-next-line no-restricted-properties\n return mediaQuery?.matches ? 'dark' : 'light';\n });\n\n React.useEffect(() => {\n if (appearanceProp) {\n setAppearance(appearanceProp);\n return noop;\n }\n\n if (vkBridge.isEmbedded()) {\n return autoDetectAppearanceByBridge(setAppearance, onceDetectAppearanceByBridge.current);\n }\n\n return autoDetectAppearance(window, setAppearance);\n }, [window, appearanceProp]);\n\n return appearance;\n};\n"],"names":["useAutoDetectAppearance","initialAppearance","vkBridge","send","then","data","resolveAppearance","catch","console","error","autoDetectAppearanceByBridge","setAppearance","onDetectAppearanceByBridge","bridgeListener","e","detail","type","subscribe","unsubscribe","autoDetectAppearance","window","mediaQuery","matchMedia","undefined","noop","check","event","matches","matchMediaListAddListener","matchMediaListRemoveListener","appearanceProp","useDOM","onceDetectAppearanceByBridge","React","useRef","current","useState","appearance","useEffect","isEmbedded"],"mappings":";;;;+BAkEaA;;;eAAAA;;;;;;+DAlEU;iEAKhB;oBACc;0BACiC;mBAC/B;0BACiD;AAExE,IAAIC,oBAA2C;AAE/CC,kBACGC,KAAK,qBACLC,KAAK,SAACC;IACLJ,oBAAoBK,IAAAA,+BAAkBD;AACxC,GACCE,MAAMC,QAAQC;AAEjB,SAASC,6BACPC,aAA8C,EAC9CC,0BAAsC;QAE7BC,iBAAT,SAASA,eAAeC,CAAsC;QAC5D,IAAuBA,YAAAA,EAAEC,QAAjBC,OAAeF,UAAfE,MAAMX,OAASS,UAATT;QAEd,IAAIW,SAAS,wBAAwB;YACnC;QACF;QAEAf,oBAAoBK,IAAAA,+BAAkBD;QAEtC,IAAIJ,mBAAmB;YACrBW;YACAD,cAAcV;QAChB;IACF;IAEAC,kBAASe,UAAUJ;IAEnB,OAAO;eAAMX,kBAASgB,YAAYL;;AACpC;AAEA,SAASM,qBACPC,MAA0B,EAC1BT,aAA8C;IAE9C,IAAMU,aACJD,UAAUA,OAAOE,cAAcF,OAAOE,WAAW;IAEnD,IAAID,eAAeE,WAAW;QAC5B,OAAOC;IACT;IAEA,IAAMC,QAAQ,SAACC;QACb,oDAAoD;QACpDf,cAAce,MAAMC,UAAU,SAAS;IACzC;IAEAF,MAAMJ;IACNO,IAAAA,uCAA0BP,YAAYI;IAEtC,OAAO;eAAMI,IAAAA,0CAA6BR,YAAYI;;AACxD;AAEO,IAAMzB,0BAA0B,SACrC8B,gBACAlB;IAEA,IAAM,AAAEQ,SAAWW,IAAAA,eAAXX;IACR,IAAMY,+BAA+BC,OAAMC,OAAO;QAChDtB,8BAA8BA;QAC9BoB,6BAA6BG,UAAUX;IACzC;IAEA,IAAoCS,qCAAAA,OAAMG,SAAyB;QACjE,IAAIN,gBAAgB;YAClB,OAAOA;QACT;QAEA,IAAI7B,mBAAmB;YACrB+B,6BAA6BG;YAC7B,OAAOlC;QACT;QAEA,IAAMoB,aACJD,UAAUA,OAAOE,cAAcF,OAAOE,WAAW;QAEnD,oDAAoD;QACpD,OAAOD,CAAAA,uBAAAA,wBAAAA,KAAAA,IAAAA,WAAYM,OAAM,IAAI,SAAS;IACxC,QAfOU,aAA6BJ,oBAAjBtB,gBAAiBsB;IAiBpCA,OAAMK,UAAU;QACd,IAAIR,gBAAgB;YAClBnB,cAAcmB;YACd,OAAON;QACT;QAEA,IAAItB,kBAASqC,cAAc;YACzB,OAAO7B,6BAA6BC,eAAeqB,6BAA6BG;QAClF;QAEA,OAAOhB,qBAAqBC,QAAQT;IACtC,GAAG;QAACS;QAAQU;KAAe;IAE3B,OAAOO;AACT"}
1
+ {"version":3,"sources":["../../../src/hooks/useAutoDetectAppearance.tsx"],"sourcesContent":["import * as React from 'react';\nimport vkBridge, {\n AnyReceiveMethodName,\n AppearanceType,\n VKBridgeEvent,\n} from '@vkontakte/vk-bridge';\nimport { noop } from '@vkontakte/vkjs';\nimport { resolveAppearance, VKBridgeConfigData } from '../helpers/appearance';\nimport { useDOM } from '../lib/dom';\nimport { matchMediaListAddListener, matchMediaListRemoveListener } from '../lib/matchMedia';\n\nfunction autoDetectAppearanceByBridge(\n setAppearance: (value: AppearanceType) => void,\n onDetectAppearanceByBridge: () => void,\n) {\n function updateAppearance(data: VKBridgeConfigData) {\n const initialAppearance = resolveAppearance(data);\n\n if (initialAppearance) {\n onDetectAppearanceByBridge();\n setAppearance(initialAppearance);\n }\n }\n\n function bridgeListener(e: VKBridgeEvent<AnyReceiveMethodName>) {\n const { type, data } = e.detail;\n\n if (type !== 'VKWebAppUpdateConfig') {\n return;\n }\n\n updateAppearance(data as VKBridgeConfigData);\n }\n\n vkBridge.subscribe(bridgeListener);\n vkBridge.send('VKWebAppGetConfig').then(updateAppearance).catch(console.error);\n\n return () => vkBridge.unsubscribe(bridgeListener);\n}\n\nfunction autoDetectAppearance(\n window: Window | undefined,\n setAppearance: (value: AppearanceType) => void,\n): () => void {\n const mediaQuery =\n window && window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)');\n\n if (mediaQuery === undefined) {\n return noop;\n }\n\n const check = (event: MediaQueryList | MediaQueryListEvent) => {\n // eslint-disable-next-line no-restricted-properties\n setAppearance(event.matches ? 'dark' : 'light');\n };\n\n check(mediaQuery);\n matchMediaListAddListener(mediaQuery, check);\n\n return () => matchMediaListRemoveListener(mediaQuery, check);\n}\n\nexport const useAutoDetectAppearance = (\n appearanceProp?: AppearanceType,\n onDetectAppearanceByBridge?: () => void,\n): AppearanceType => {\n const { window } = useDOM();\n const onceDetectAppearanceByBridge = React.useRef(() => {\n onDetectAppearanceByBridge && onDetectAppearanceByBridge();\n onceDetectAppearanceByBridge.current = noop;\n });\n\n const [appearance, setAppearance] = React.useState<AppearanceType>(() => {\n if (appearanceProp) {\n return appearanceProp;\n }\n\n const mediaQuery =\n window && window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)');\n\n // eslint-disable-next-line no-restricted-properties\n return mediaQuery?.matches ? 'dark' : 'light';\n });\n\n React.useEffect(() => {\n if (appearanceProp) {\n setAppearance(appearanceProp);\n return noop;\n }\n\n if (vkBridge.isEmbedded()) {\n return autoDetectAppearanceByBridge(setAppearance, onceDetectAppearanceByBridge.current);\n }\n\n return autoDetectAppearance(window, setAppearance);\n }, [window, appearanceProp]);\n\n return appearance;\n};\n"],"names":["useAutoDetectAppearance","autoDetectAppearanceByBridge","setAppearance","onDetectAppearanceByBridge","updateAppearance","data","initialAppearance","resolveAppearance","bridgeListener","e","detail","type","vkBridge","subscribe","send","then","catch","console","error","unsubscribe","autoDetectAppearance","window","mediaQuery","matchMedia","undefined","noop","check","event","matches","matchMediaListAddListener","matchMediaListRemoveListener","appearanceProp","useDOM","onceDetectAppearanceByBridge","React","useRef","current","useState","appearance","useEffect","isEmbedded"],"mappings":";;;;+BA8DaA;;;eAAAA;;;;;;+DA9DU;iEAKhB;oBACc;0BACiC;mBAC/B;0BACiD;AAExE,SAASC,6BACPC,aAA8C,EAC9CC,0BAAsC;QAE7BC,mBAAT,SAASA,iBAAiBC,IAAwB;QAChD,IAAMC,oBAAoBC,IAAAA,+BAAkBF;QAE5C,IAAIC,mBAAmB;YACrBH;YACAD,cAAcI;QAChB;IACF;QAESE,iBAAT,SAASA,eAAeC,CAAsC;QAC5D,IAAuBA,YAAAA,EAAEC,QAAjBC,OAAeF,UAAfE,MAAMN,OAASI,UAATJ;QAEd,IAAIM,SAAS,wBAAwB;YACnC;QACF;QAEAP,iBAAiBC;IACnB;IAEAO,kBAASC,UAAUL;IACnBI,kBAASE,KAAK,qBAAqBC,KAAKX,kBAAkBY,MAAMC,QAAQC;IAExE,OAAO;eAAMN,kBAASO,YAAYX;;AACpC;AAEA,SAASY,qBACPC,MAA0B,EAC1BnB,aAA8C;IAE9C,IAAMoB,aACJD,UAAUA,OAAOE,cAAcF,OAAOE,WAAW;IAEnD,IAAID,eAAeE,WAAW;QAC5B,OAAOC;IACT;IAEA,IAAMC,QAAQ,SAACC;QACb,oDAAoD;QACpDzB,cAAcyB,MAAMC,UAAU,SAAS;IACzC;IAEAF,MAAMJ;IACNO,IAAAA,uCAA0BP,YAAYI;IAEtC,OAAO;eAAMI,IAAAA,0CAA6BR,YAAYI;;AACxD;AAEO,IAAM1B,0BAA0B,SACrC+B,gBACA5B;IAEA,IAAM,AAAEkB,SAAWW,IAAAA,eAAXX;IACR,IAAMY,+BAA+BC,OAAMC,OAAO;QAChDhC,8BAA8BA;QAC9B8B,6BAA6BG,UAAUX;IACzC;IAEA,IAAoCS,qCAAAA,OAAMG,SAAyB;QACjE,IAAIN,gBAAgB;YAClB,OAAOA;QACT;QAEA,IAAMT,aACJD,UAAUA,OAAOE,cAAcF,OAAOE,WAAW;QAEnD,oDAAoD;QACpD,OAAOD,CAAAA,uBAAAA,wBAAAA,KAAAA,IAAAA,WAAYM,OAAM,IAAI,SAAS;IACxC,QAVOU,aAA6BJ,oBAAjBhC,gBAAiBgC;IAYpCA,OAAMK,UAAU;QACd,IAAIR,gBAAgB;YAClB7B,cAAc6B;YACd,OAAON;QACT;QAEA,IAAIb,kBAAS4B,cAAc;YACzB,OAAOvC,6BAA6BC,eAAe+B,6BAA6BG;QAClF;QAEA,OAAOhB,qBAAqBC,QAAQnB;IACtC,GAAG;QAACmB;QAAQU;KAAe;IAE3B,OAAOO;AACT"}
@@ -1,8 +1,9 @@
1
+ import { LiteralUnion } from '../types';
1
2
  import { BrowserInfo } from './browser';
2
3
  export declare enum Platform {
3
4
  ANDROID = "android",
4
5
  IOS = "ios",
5
6
  VKCOM = "vkcom"
6
7
  }
7
- export type PlatformType = Platform.ANDROID | Platform.IOS | Platform.VKCOM | string;
8
+ export type PlatformType = LiteralUnion<'android' | 'ios' | 'vkcom', string>;
8
9
  export declare function platform(browserInfo?: BrowserInfo): PlatformType;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/lib/platform.ts"],"sourcesContent":["import { querystring } from '@vkontakte/vkjs';\nimport { BrowserInfo, computeBrowserInfo } from './browser';\nimport { canUseDOM } from './dom';\n\nexport enum Platform {\n ANDROID = 'android',\n IOS = 'ios',\n VKCOM = 'vkcom',\n}\n\nconst PLATFORM_ALIAS = {\n desktop_web: Platform.VKCOM,\n};\n\nfunction isPlatformAlias(platformAlias: string): platformAlias is keyof typeof PLATFORM_ALIAS {\n return platformAlias in PLATFORM_ALIAS;\n}\n\n/**\n * Значение, которое передаётся в качестве query-параметра при открытии VK Mini Apps\n * @see {@link https://dev.vk.com/mini-apps/development/launch-params#vk_platform vk_platform}\n */\nfunction getPlatformByQueryString(queryString: string): Platform | undefined {\n try {\n const parsedQuery = querystring.parse(queryString);\n const platformAliasByQuery = parsedQuery['vk_platform'];\n\n return typeof platformAliasByQuery === 'string' && isPlatformAlias(platformAliasByQuery)\n ? PLATFORM_ALIAS[platformAliasByQuery]\n : undefined;\n } catch (e) {\n console.warn(e);\n\n return undefined;\n }\n}\n\nconst platformByQueryString = canUseDOM ? getPlatformByQueryString(location.search) : undefined;\n\nexport type PlatformType = Platform.ANDROID | Platform.IOS | Platform.VKCOM | string;\n\nexport function platform(browserInfo?: BrowserInfo): PlatformType {\n if (platformByQueryString) {\n return platformByQueryString;\n }\n\n if (!browserInfo) {\n browserInfo = computeBrowserInfo();\n }\n\n return browserInfo.system === 'ios' ? Platform.IOS : Platform.ANDROID;\n}\n"],"names":["platform","Platform","ANDROID","IOS","VKCOM","PLATFORM_ALIAS","desktop_web","isPlatformAlias","platformAlias","getPlatformByQueryString","queryString","parsedQuery","querystring","parse","platformAliasByQuery","undefined","e","console","warn","platformByQueryString","canUseDOM","location","search","browserInfo","computeBrowserInfo","system"],"mappings":";;;;;;;;;;;;;;IAyCgBA,QAAQ;eAARA;;;oBAzCY;uBACoB;mBACtB;IAEnB;UAAKC,QAAQ;IAARA,SACVC,aAAU;IADAD,SAEVE,SAAM;IAFIF,SAGVG,WAAQ;GAHEH,aAAAA;AAMZ,IAAMI,iBAAiB;IACrBC,aAAaL,SAASG;AACxB;AAEA,SAASG,gBAAgBC,aAAqB;IAC5C,OAAOA,iBAAiBH;AAC1B;AAEA;;;CAGC,GACD,SAASI,yBAAyBC,WAAmB;IACnD,IAAI;QACF,IAAMC,cAAcC,kBAAYC,MAAMH;QACtC,IAAMI,uBAAuBH,WAAW,CAAC,cAAc;QAEvD,OAAO,OAAOG,yBAAyB,YAAYP,gBAAgBO,wBAC/DT,cAAc,CAACS,qBAAqB,GACpCC;IACN,EAAE,OAAOC,GAAG;QACVC,QAAQC,KAAKF;QAEb,OAAOD;IACT;AACF;AAEA,IAAMI,wBAAwBC,iBAAYX,yBAAyBY,SAASC,UAAUP;AAI/E,SAASf,SAASuB,WAAyB;IAChD,IAAIJ,uBAAuB;QACzB,OAAOA;IACT;IAEA,IAAI,CAACI,aAAa;QAChBA,cAAcC,IAAAA;IAChB;IAEA,OAAOD,YAAYE,WAAW,QAAQxB,SAASE,MAAMF,SAASC;AAChE"}
1
+ {"version":3,"sources":["../../../src/lib/platform.ts"],"sourcesContent":["import { querystring } from '@vkontakte/vkjs';\nimport { LiteralUnion } from '../types';\nimport { BrowserInfo, computeBrowserInfo } from './browser';\nimport { canUseDOM } from './dom';\n\nexport enum Platform {\n ANDROID = 'android',\n IOS = 'ios',\n VKCOM = 'vkcom',\n}\n\nconst PLATFORM_ALIAS = {\n desktop_web: Platform.VKCOM,\n};\n\nfunction isPlatformAlias(platformAlias: string): platformAlias is keyof typeof PLATFORM_ALIAS {\n return platformAlias in PLATFORM_ALIAS;\n}\n\n/**\n * Значение, которое передаётся в качестве query-параметра при открытии VK Mini Apps\n * @see {@link https://dev.vk.com/mini-apps/development/launch-params#vk_platform vk_platform}\n */\nfunction getPlatformByQueryString(queryString: string): Platform | undefined {\n try {\n const parsedQuery = querystring.parse(queryString);\n const platformAliasByQuery = parsedQuery['vk_platform'];\n\n return typeof platformAliasByQuery === 'string' && isPlatformAlias(platformAliasByQuery)\n ? PLATFORM_ALIAS[platformAliasByQuery]\n : undefined;\n } catch (e) {\n console.warn(e);\n\n return undefined;\n }\n}\n\nconst platformByQueryString = canUseDOM ? getPlatformByQueryString(location.search) : undefined;\n\nexport type PlatformType = LiteralUnion<'android' | 'ios' | 'vkcom', string>;\n\nexport function platform(browserInfo?: BrowserInfo): PlatformType {\n if (platformByQueryString) {\n return platformByQueryString;\n }\n\n if (!browserInfo) {\n browserInfo = computeBrowserInfo();\n }\n\n return browserInfo.system === 'ios' ? Platform.IOS : Platform.ANDROID;\n}\n"],"names":["platform","Platform","ANDROID","IOS","VKCOM","PLATFORM_ALIAS","desktop_web","isPlatformAlias","platformAlias","getPlatformByQueryString","queryString","parsedQuery","querystring","parse","platformAliasByQuery","undefined","e","console","warn","platformByQueryString","canUseDOM","location","search","browserInfo","computeBrowserInfo","system"],"mappings":";;;;;;;;;;;;;;IA0CgBA,QAAQ;eAARA;;;oBA1CY;uBAEoB;mBACtB;IAEnB;UAAKC,QAAQ;IAARA,SACVC,aAAU;IADAD,SAEVE,SAAM;IAFIF,SAGVG,WAAQ;GAHEH,aAAAA;AAMZ,IAAMI,iBAAiB;IACrBC,aAAaL,SAASG;AACxB;AAEA,SAASG,gBAAgBC,aAAqB;IAC5C,OAAOA,iBAAiBH;AAC1B;AAEA;;;CAGC,GACD,SAASI,yBAAyBC,WAAmB;IACnD,IAAI;QACF,IAAMC,cAAcC,kBAAYC,MAAMH;QACtC,IAAMI,uBAAuBH,WAAW,CAAC,cAAc;QAEvD,OAAO,OAAOG,yBAAyB,YAAYP,gBAAgBO,wBAC/DT,cAAc,CAACS,qBAAqB,GACpCC;IACN,EAAE,OAAOC,GAAG;QACVC,QAAQC,KAAKF;QAEb,OAAOD;IACT;AACF;AAEA,IAAMI,wBAAwBC,iBAAYX,yBAAyBY,SAASC,UAAUP;AAI/E,SAASf,SAASuB,WAAyB;IAChD,IAAIJ,uBAAuB;QACzB,OAAOA;IACT;IAEA,IAAI,CAACI,aAAa;QAChBA,cAAcC,IAAAA;IAChB;IAEA,OAAOD,YAAYE,WAAW,QAAQxB,SAASE,MAAMF,SAASC;AAChE"}
@@ -54,3 +54,15 @@ export type Exact<A, B> = A extends B ? B : never;
54
54
  * Для возможности указывать css custom properties
55
55
  */
56
56
  export type CSSCustomProperties<T extends string | undefined = string> = Record<`--${string}`, T>;
57
+ interface Nothing {
58
+ }
59
+ /**
60
+ * Автозаполнение для типов
61
+ *
62
+ * @example
63
+ * LiteralUnion<'foo' | 'bar', string>
64
+ *
65
+ * @see {@link https://github.com/microsoft/TypeScript/issues/29729}
66
+ */
67
+ export type LiteralUnion<Union, Type> = Union | (Type & Nothing);
68
+ export {};
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/types.ts"],"sourcesContent":["import * as React from 'react';\nimport { Insets } from '@vkontakte/vk-bridge';\nimport { PlatformType } from './lib/platform';\n\nexport type AnyFunction = (...args: any[]) => any;\n\nexport type AlignType = 'left' | 'center' | 'right';\n\nexport interface HasChildren {\n children?: React.ReactNode;\n}\n\nexport type HasDataAttribute = Record<\n `data-${string}`,\n string | number | boolean | undefined | null\n>;\n\nexport interface HasRootRef<T> {\n getRootRef?: React.Ref<T>;\n}\n\nexport interface HasRef<T> {\n getRef?: React.Ref<T>;\n}\n\nexport interface HasComponent {\n Component?: React.ElementType;\n}\n\nexport interface HasAlign {\n align?: AlignType;\n}\n\nexport interface HasPlatform {\n /**\n * @ignore\n */\n platform?: PlatformType;\n}\n\nexport interface HasInsets {\n /**\n * @ignore\n */\n insets?: Partial<Insets>;\n}\n\nexport interface Version {\n major: number;\n minor?: number;\n patch?: number;\n}\n\n/**\n * Тип содержит атрибуты, которые применяются только для `<a>`\n *\n * @see {@link https://developer.mozilla.org/ru/docs/Web/HTML/Element/A &lt;a&gt; - HTML | MDN}\n */\nexport type AnchorHTMLAttributesOnly = Omit<\n React.AnchorHTMLAttributes<HTMLAnchorElement>,\n keyof React.HTMLAttributes<HTMLAnchorElement>\n>;\n\n/**\n * Проверяет, является ли тип подтипом другого.\n *\n * В TS не реализовано.\n *\n * @see {@link https://github.com/microsoft/TypeScript/issues/12936}\n */\nexport type Exact<A, B> = A extends B ? B : never;\n\n/**\n * Для возможности указывать css custom properties\n */\nexport type CSSCustomProperties<T extends string | undefined = string> = Record<`--${string}`, T>;\n"],"names":[],"mappings":";;;;;+DAAuB"}
1
+ {"version":3,"sources":["../../src/types.ts"],"sourcesContent":["import * as React from 'react';\nimport { Insets } from '@vkontakte/vk-bridge';\nimport { PlatformType } from './lib/platform';\n\nexport type AnyFunction = (...args: any[]) => any;\n\nexport type AlignType = 'left' | 'center' | 'right';\n\nexport interface HasChildren {\n children?: React.ReactNode;\n}\n\nexport type HasDataAttribute = Record<\n `data-${string}`,\n string | number | boolean | undefined | null\n>;\n\nexport interface HasRootRef<T> {\n getRootRef?: React.Ref<T>;\n}\n\nexport interface HasRef<T> {\n getRef?: React.Ref<T>;\n}\n\nexport interface HasComponent {\n Component?: React.ElementType;\n}\n\nexport interface HasAlign {\n align?: AlignType;\n}\n\nexport interface HasPlatform {\n /**\n * @ignore\n */\n platform?: PlatformType;\n}\n\nexport interface HasInsets {\n /**\n * @ignore\n */\n insets?: Partial<Insets>;\n}\n\nexport interface Version {\n major: number;\n minor?: number;\n patch?: number;\n}\n\n/**\n * Тип содержит атрибуты, которые применяются только для `<a>`\n *\n * @see {@link https://developer.mozilla.org/ru/docs/Web/HTML/Element/A &lt;a&gt; - HTML | MDN}\n */\nexport type AnchorHTMLAttributesOnly = Omit<\n React.AnchorHTMLAttributes<HTMLAnchorElement>,\n keyof React.HTMLAttributes<HTMLAnchorElement>\n>;\n\n/**\n * Проверяет, является ли тип подтипом другого.\n *\n * В TS не реализовано.\n *\n * @see {@link https://github.com/microsoft/TypeScript/issues/12936}\n */\nexport type Exact<A, B> = A extends B ? B : never;\n\n/**\n * Для возможности указывать css custom properties\n */\nexport type CSSCustomProperties<T extends string | undefined = string> = Record<`--${string}`, T>;\n\n// eslint-disable-next-line @typescript-eslint/no-empty-interface\ninterface Nothing {}\n\n/**\n * Автозаполнение для типов\n *\n * @example\n * LiteralUnion<'foo' | 'bar', string>\n *\n * @see {@link https://github.com/microsoft/TypeScript/issues/29729}\n */\nexport type LiteralUnion<Union, Type> = Union | (Type & Nothing);\n"],"names":[],"mappings":";;;;;+DAAuB"}
@@ -147,15 +147,19 @@ var chipsSelectDefaultProps = _object_spread_props(_object_spread({}, chipsInput
147
147
  focusOption(focusedOptionIndex, FOCUS_ACTION_NEXT);
148
148
  }
149
149
  }
150
- if (e.key === "Enter" && !e.defaultPrevented && opened && focusedOptionIndex != null) {
151
- var option = filteredOptions[focusedOptionIndex];
152
- if (option) {
153
- onChangeStart(e, option);
154
- if (!e.defaultPrevented) {
155
- addOption(option);
156
- setFocusedOptionIndex(null);
157
- clearInput();
158
- closeAfterSelect && setOpened(false);
150
+ if (e.key === "Enter" && !e.defaultPrevented && opened) {
151
+ if (focusedOptionIndex != null) {
152
+ var option = filteredOptions[focusedOptionIndex];
153
+ if (option) {
154
+ onChangeStart(e, option);
155
+ if (!e.defaultPrevented) {
156
+ addOption(option);
157
+ setFocusedOptionIndex(null);
158
+ clearInput();
159
+ closeAfterSelect && setOpened(false);
160
+ e.preventDefault();
161
+ }
162
+ } else if (!creatable) {
159
163
  e.preventDefault();
160
164
  }
161
165
  } else if (!creatable) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/ChipsSelect/ChipsSelect.tsx"],"sourcesContent":["import * as React from 'react';\nimport { classNames, noop } from '@vkontakte/vkjs';\nimport { useChipsSelect } from '../../hooks/useChipsSelect';\nimport { useExternRef } from '../../hooks/useExternRef';\nimport { useGlobalEventListener } from '../../hooks/useGlobalEventListener';\nimport { useDOM } from '../../lib/dom';\nimport type { Placement } from '../../lib/floating';\nimport { defaultFilterFn } from '../../lib/select';\nimport { ChipOption, ChipValue, RenderChip } from '../Chip/Chip';\nimport { ChipsInputProps } from '../ChipsInput/ChipsInput';\nimport { ChipsInputBase, chipsInputDefaultProps } from '../ChipsInputBase/ChipsInputBase';\nimport { CustomSelectDropdown } from '../CustomSelectDropdown/CustomSelectDropdown';\nimport {\n CustomSelectOption,\n CustomSelectOptionProps,\n} from '../CustomSelectOption/CustomSelectOption';\nimport { DropdownIcon } from '../DropdownIcon/DropdownIcon';\nimport { FormField } from '../FormField/FormField';\nimport { IconButton } from '../IconButton/IconButton';\nimport { Footnote } from '../Typography/Footnote/Footnote';\nimport styles from './ChipsSelect.module.css';\n\nexport interface ChipsSelectProps<Option extends ChipOption>\n extends Omit<ChipsInputProps<Option>, 'after'> {\n popupDirection?: 'top' | 'bottom';\n options?: Option[];\n filterFn?:\n | false\n | ((\n value?: string,\n option?: Option,\n getOptionLabel?: Pick<ChipsInputProps<Option>, 'getOptionLabel'>['getOptionLabel'],\n ) => boolean);\n /**\n * Возможность создавать чипы которых нет в списке (по enter или с помощью пункта в меню, см creatableText)\n */\n creatable?: boolean;\n /**\n * Отрисовка лоадера вместо списка опций в выпадающем списке\n */\n fetching?: boolean;\n renderOption?: (props: CustomSelectOptionProps) => React.ReactNode;\n /**\n * Показывать или скрывать уже выбранные опции\n */\n showSelected?: boolean;\n /**\n * Текст для пункта создающего чипы при клике, так же отвечает за то будет ли показан этот пункт (показывается после того как в списке не отсанется опций)\n */\n creatableText?: string;\n /**\n * Текст который показывается если список опций пуст\n */\n emptyText?: string;\n /**\n * Событие срабатывающее перед onChange\n */\n onChangeStart?: (e: React.MouseEvent | React.KeyboardEvent, option: Option) => void;\n /**\n * Закрытие выпадающего списка после выбора элемента\n */\n closeAfterSelect?: boolean;\n fixDropdownWidth?: boolean;\n forceDropdownPortal?: boolean;\n /**\n * Иконка раскрывающегося списка\n */\n icon?: React.ReactNode;\n}\n\ntype FocusActionType = 'next' | 'prev';\n\nconst FOCUS_ACTION_NEXT: FocusActionType = 'next';\nconst FOCUS_ACTION_PREV: FocusActionType = 'prev';\n\nconst chipsSelectDefaultProps: ChipsSelectProps<any> = {\n ...chipsInputDefaultProps,\n emptyText: 'Ничего не найдено',\n creatableText: 'Создать значение',\n onChangeStart: noop,\n creatable: false,\n fetching: false,\n showSelected: true,\n closeAfterSelect: true,\n options: [],\n filterFn: defaultFilterFn,\n renderOption(props) {\n return <CustomSelectOption {...props} />;\n },\n};\n\n/**\n * @see https://vkcom.github.io/VKUI/#/ChipsSelect\n */\nexport const ChipsSelect = <Option extends ChipOption>(props: ChipsSelectProps<Option>) => {\n const propsWithDefault = { ...chipsSelectDefaultProps, ...props };\n const {\n style,\n onFocus,\n onKeyDown,\n className,\n fetching,\n renderOption,\n emptyText,\n getRef,\n getRootRef,\n disabled,\n placeholder,\n tabIndex,\n getOptionValue,\n getOptionLabel,\n showSelected,\n getNewOptionData,\n renderChip,\n popupDirection,\n creatable,\n filterFn,\n inputValue,\n creatableText,\n closeAfterSelect,\n onChangeStart,\n before,\n icon,\n options,\n fixDropdownWidth,\n forceDropdownPortal,\n ...restProps\n } = propsWithDefault;\n\n const { document } = useDOM();\n\n const [popperPlacement, setPopperPlacement] = React.useState<Placement | undefined>(undefined);\n\n const scrollBoxRef = React.useRef<HTMLDivElement>(null);\n const rootRef = useExternRef(getRef);\n const {\n fieldValue,\n selectedOptions = [],\n opened,\n setOpened,\n addOptionFromInput,\n filteredOptions,\n addOption,\n handleInputChange,\n clearInput,\n focusedOption,\n setFocusedOption,\n focusedOptionIndex,\n setFocusedOptionIndex,\n } = useChipsSelect(propsWithDefault);\n\n const showCreatable = Boolean(\n creatable && creatableText && !filteredOptions.length && fieldValue,\n );\n\n const handleFocus = (e: React.FocusEvent<HTMLInputElement>) => {\n setOpened(true);\n setFocusedOptionIndex(null);\n onFocus!(e);\n };\n\n const handleClickOutside = (e: MouseEvent) => {\n if (e.target !== rootRef.current && !rootRef.current?.contains(e.target as Node)) {\n setOpened(false);\n }\n };\n\n const chipsSelectOptions = React.useRef<HTMLElement[]>([]).current;\n\n const scrollToElement = (index: number, center = false) => {\n const dropdown = scrollBoxRef.current;\n const item = chipsSelectOptions[index];\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 = (index: number, oldIndex: number | null) => {\n const { length } = filteredOptions;\n\n if (index < 0) {\n index = length - 1;\n } else if (index >= length) {\n index = 0;\n }\n\n if (index === oldIndex) {\n return;\n }\n\n scrollToElement(index);\n setFocusedOptionIndex(index);\n };\n\n const focusOption = (nextIndex: number | null, type: FocusActionType) => {\n let index = nextIndex === null ? -1 : nextIndex;\n\n if (type === FOCUS_ACTION_NEXT) {\n index = index + 1;\n } else if (type === FOCUS_ACTION_PREV) {\n index = index - 1;\n }\n\n focusOptionByIndex(index, focusedOptionIndex);\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n onKeyDown!(e);\n\n if (e.key === 'ArrowUp' && !e.defaultPrevented) {\n e.preventDefault();\n\n if (!opened) {\n setOpened(true);\n setFocusedOptionIndex(0);\n } else {\n focusOption(focusedOptionIndex, FOCUS_ACTION_PREV);\n }\n }\n\n if (e.key === 'ArrowDown' && !e.defaultPrevented) {\n e.preventDefault();\n\n if (!opened) {\n setOpened(true);\n setFocusedOptionIndex(0);\n } else {\n focusOption(focusedOptionIndex, FOCUS_ACTION_NEXT);\n }\n }\n\n if (e.key === 'Enter' && !e.defaultPrevented && opened && focusedOptionIndex != null) {\n const option = filteredOptions[focusedOptionIndex];\n\n if (option) {\n onChangeStart!(e, option);\n\n if (!e.defaultPrevented) {\n addOption(option);\n setFocusedOptionIndex(null);\n clearInput();\n closeAfterSelect && setOpened(false);\n e.preventDefault();\n }\n } else if (!creatable) {\n e.preventDefault();\n }\n }\n\n if (['Escape', 'Tab'].includes(e.key) && !e.defaultPrevented && opened) {\n setOpened(false);\n }\n };\n\n React.useEffect(() => {\n if (focusedOptionIndex != null && filteredOptions[focusedOptionIndex]) {\n setFocusedOption(filteredOptions[focusedOptionIndex]);\n } else if (focusedOptionIndex === null || focusedOptionIndex === 0) {\n setFocusedOption(null);\n }\n }, [focusedOptionIndex, filteredOptions, setFocusedOption]);\n\n useGlobalEventListener(document, 'click', handleClickOutside);\n\n const renderChipWrapper = (renderChipProps: RenderChip<Option> | undefined) => {\n if (renderChipProps === undefined) {\n return null;\n }\n const onRemoveWrapper = (e: React.MouseEvent | undefined, value: ChipValue | undefined) => {\n e?.preventDefault();\n e?.stopPropagation();\n\n renderChipProps.onRemove?.(e, value);\n };\n\n return renderChip!({\n ...renderChipProps,\n onRemove: onRemoveWrapper,\n });\n };\n\n const isPopperDirectionTop = popperPlacement?.includes('top');\n\n const onPlacementChange = React.useCallback(\n (placement?: Placement) => {\n setPopperPlacement(placement);\n },\n [setPopperPlacement],\n );\n\n const onDropdownMouseLeave = React.useCallback(() => {\n setFocusedOptionIndex(null);\n }, [setFocusedOptionIndex]);\n\n const toggleOpened = () => {\n setOpened((prevOpened) => !prevOpened);\n };\n\n return (\n <>\n <FormField\n getRootRef={rootRef}\n style={style}\n className={classNames(\n styles['ChipsSelect'],\n opened &&\n (isPopperDirectionTop\n ? styles['ChipsSelect--pop-up']\n : styles['ChipsSelect--pop-down']),\n className,\n )}\n disabled={disabled}\n role=\"application\"\n aria-disabled={disabled}\n aria-readonly={restProps.readOnly}\n after={\n <IconButton\n className={styles['ChipsSelect__dropdown']}\n activeMode=\"\"\n hoverMode=\"\"\n // TODO: add label customization\n aria-label={opened ? 'Скрыть' : 'Развернуть'}\n onClick={toggleOpened}\n >\n {icon ?? <DropdownIcon className={styles['ChipsSelect__icon']} opened={opened} />}\n </IconButton>\n }\n before={before}\n >\n <ChipsInputBase\n {...restProps}\n tabIndex={tabIndex}\n value={selectedOptions}\n inputValue={fieldValue}\n getNewOptionData={getNewOptionData}\n getOptionLabel={getOptionLabel}\n getOptionValue={getOptionValue}\n renderChip={renderChipWrapper}\n onFocus={handleFocus}\n onKeyDown={handleKeyDown}\n placeholder={placeholder}\n getRef={getRef}\n disabled={disabled}\n onInputChange={handleInputChange}\n />\n </FormField>\n {opened && (\n <CustomSelectDropdown\n targetRef={rootRef}\n placement={popupDirection}\n scrollBoxRef={scrollBoxRef}\n onPlacementChange={onPlacementChange}\n onMouseLeave={onDropdownMouseLeave}\n fetching={fetching}\n sameWidth={fixDropdownWidth}\n forcePortal={forceDropdownPortal}\n >\n {showCreatable && (\n <CustomSelectOption\n hovered={focusedOptionIndex === 0}\n onMouseDown={addOptionFromInput}\n onMouseEnter={() => setFocusedOptionIndex(0)}\n >\n {creatableText}\n </CustomSelectOption>\n )}\n {!filteredOptions?.length && !showCreatable && emptyText ? (\n <Footnote className={styles['ChipsSelect__empty']}>{emptyText}</Footnote>\n ) : (\n filteredOptions.map((option: Option, index: number) => {\n const label = getOptionLabel!(option);\n const hovered =\n focusedOption && getOptionValue!(option) === getOptionValue!(focusedOption);\n const selected = selectedOptions.find((selectedOption: Option) => {\n return getOptionValue!(selectedOption) === getOptionValue!(option);\n });\n const value = getOptionValue!(option);\n\n return (\n <React.Fragment key={`${typeof value}-${value}`}>\n {renderOption!({\n option,\n hovered: Boolean(hovered),\n children: label,\n selected: !!selected,\n getRootRef: (e) => {\n if (e) {\n return (chipsSelectOptions[index] = e);\n }\n return undefined;\n },\n onMouseDown: (e: React.MouseEvent<HTMLDivElement>) => {\n onChangeStart?.(e, option);\n\n if (!e.defaultPrevented) {\n closeAfterSelect && setOpened(false);\n addOption(option);\n clearInput();\n }\n },\n onMouseEnter: () => setFocusedOptionIndex(index),\n })}\n </React.Fragment>\n );\n })\n )}\n </CustomSelectDropdown>\n )}\n </>\n );\n};\n"],"names":["React","classNames","noop","useChipsSelect","useExternRef","useGlobalEventListener","useDOM","defaultFilterFn","ChipsInputBase","chipsInputDefaultProps","CustomSelectDropdown","CustomSelectOption","DropdownIcon","FormField","IconButton","Footnote","FOCUS_ACTION_NEXT","FOCUS_ACTION_PREV","chipsSelectDefaultProps","emptyText","creatableText","onChangeStart","creatable","fetching","showSelected","closeAfterSelect","options","filterFn","renderOption","props","ChipsSelect","propsWithDefault","style","onFocus","onKeyDown","className","getRef","getRootRef","disabled","placeholder","tabIndex","getOptionValue","getOptionLabel","getNewOptionData","renderChip","popupDirection","inputValue","before","icon","fixDropdownWidth","forceDropdownPortal","restProps","document","useState","undefined","popperPlacement","setPopperPlacement","scrollBoxRef","useRef","rootRef","fieldValue","selectedOptions","opened","setOpened","addOptionFromInput","filteredOptions","addOption","handleInputChange","clearInput","focusedOption","setFocusedOption","focusedOptionIndex","setFocusedOptionIndex","showCreatable","Boolean","length","handleFocus","e","handleClickOutside","target","current","contains","chipsSelectOptions","scrollToElement","index","center","dropdown","item","dropdownHeight","offsetHeight","scrollTop","itemTop","offsetTop","itemHeight","focusOptionByIndex","oldIndex","focusOption","nextIndex","type","handleKeyDown","key","defaultPrevented","preventDefault","option","includes","useEffect","renderChipWrapper","renderChipProps","onRemoveWrapper","value","stopPropagation","onRemove","isPopperDirectionTop","onPlacementChange","useCallback","placement","onDropdownMouseLeave","toggleOpened","prevOpened","role","aria-disabled","aria-readonly","readOnly","after","activeMode","hoverMode","aria-label","onClick","onInputChange","targetRef","onMouseLeave","sameWidth","forcePortal","hovered","onMouseDown","onMouseEnter","map","label","selected","find","selectedOption","Fragment","children"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/components/ChipsSelect/ChipsSelect.tsx"],"sourcesContent":["import * as React from 'react';\nimport { classNames, noop } from '@vkontakte/vkjs';\nimport { useChipsSelect } from '../../hooks/useChipsSelect';\nimport { useExternRef } from '../../hooks/useExternRef';\nimport { useGlobalEventListener } from '../../hooks/useGlobalEventListener';\nimport { useDOM } from '../../lib/dom';\nimport type { Placement } from '../../lib/floating';\nimport { defaultFilterFn } from '../../lib/select';\nimport { ChipOption, ChipValue, RenderChip } from '../Chip/Chip';\nimport { ChipsInputProps } from '../ChipsInput/ChipsInput';\nimport { ChipsInputBase, chipsInputDefaultProps } from '../ChipsInputBase/ChipsInputBase';\nimport { CustomSelectDropdown } from '../CustomSelectDropdown/CustomSelectDropdown';\nimport {\n CustomSelectOption,\n CustomSelectOptionProps,\n} from '../CustomSelectOption/CustomSelectOption';\nimport { DropdownIcon } from '../DropdownIcon/DropdownIcon';\nimport { FormField } from '../FormField/FormField';\nimport { IconButton } from '../IconButton/IconButton';\nimport { Footnote } from '../Typography/Footnote/Footnote';\nimport styles from './ChipsSelect.module.css';\n\nexport interface ChipsSelectProps<Option extends ChipOption>\n extends Omit<ChipsInputProps<Option>, 'after'> {\n popupDirection?: 'top' | 'bottom';\n options?: Option[];\n filterFn?:\n | false\n | ((\n value?: string,\n option?: Option,\n getOptionLabel?: Pick<ChipsInputProps<Option>, 'getOptionLabel'>['getOptionLabel'],\n ) => boolean);\n /**\n * Возможность создавать чипы которых нет в списке (по enter или с помощью пункта в меню, см creatableText)\n */\n creatable?: boolean;\n /**\n * Отрисовка лоадера вместо списка опций в выпадающем списке\n */\n fetching?: boolean;\n renderOption?: (props: CustomSelectOptionProps) => React.ReactNode;\n /**\n * Показывать или скрывать уже выбранные опции\n */\n showSelected?: boolean;\n /**\n * Текст для пункта создающего чипы при клике, так же отвечает за то будет ли показан этот пункт (показывается после того как в списке не отсанется опций)\n */\n creatableText?: string;\n /**\n * Текст который показывается если список опций пуст\n */\n emptyText?: string;\n /**\n * Событие срабатывающее перед onChange\n */\n onChangeStart?: (e: React.MouseEvent | React.KeyboardEvent, option: Option) => void;\n /**\n * Закрытие выпадающего списка после выбора элемента\n */\n closeAfterSelect?: boolean;\n fixDropdownWidth?: boolean;\n forceDropdownPortal?: boolean;\n /**\n * Иконка раскрывающегося списка\n */\n icon?: React.ReactNode;\n}\n\ntype FocusActionType = 'next' | 'prev';\n\nconst FOCUS_ACTION_NEXT: FocusActionType = 'next';\nconst FOCUS_ACTION_PREV: FocusActionType = 'prev';\n\nconst chipsSelectDefaultProps: ChipsSelectProps<any> = {\n ...chipsInputDefaultProps,\n emptyText: 'Ничего не найдено',\n creatableText: 'Создать значение',\n onChangeStart: noop,\n creatable: false,\n fetching: false,\n showSelected: true,\n closeAfterSelect: true,\n options: [],\n filterFn: defaultFilterFn,\n renderOption(props) {\n return <CustomSelectOption {...props} />;\n },\n};\n\n/**\n * @see https://vkcom.github.io/VKUI/#/ChipsSelect\n */\nexport const ChipsSelect = <Option extends ChipOption>(props: ChipsSelectProps<Option>) => {\n const propsWithDefault = { ...chipsSelectDefaultProps, ...props };\n const {\n style,\n onFocus,\n onKeyDown,\n className,\n fetching,\n renderOption,\n emptyText,\n getRef,\n getRootRef,\n disabled,\n placeholder,\n tabIndex,\n getOptionValue,\n getOptionLabel,\n showSelected,\n getNewOptionData,\n renderChip,\n popupDirection,\n creatable,\n filterFn,\n inputValue,\n creatableText,\n closeAfterSelect,\n onChangeStart,\n before,\n icon,\n options,\n fixDropdownWidth,\n forceDropdownPortal,\n ...restProps\n } = propsWithDefault;\n\n const { document } = useDOM();\n\n const [popperPlacement, setPopperPlacement] = React.useState<Placement | undefined>(undefined);\n\n const scrollBoxRef = React.useRef<HTMLDivElement>(null);\n const rootRef = useExternRef(getRef);\n const {\n fieldValue,\n selectedOptions = [],\n opened,\n setOpened,\n addOptionFromInput,\n filteredOptions,\n addOption,\n handleInputChange,\n clearInput,\n focusedOption,\n setFocusedOption,\n focusedOptionIndex,\n setFocusedOptionIndex,\n } = useChipsSelect(propsWithDefault);\n\n const showCreatable = Boolean(\n creatable && creatableText && !filteredOptions.length && fieldValue,\n );\n\n const handleFocus = (e: React.FocusEvent<HTMLInputElement>) => {\n setOpened(true);\n setFocusedOptionIndex(null);\n onFocus!(e);\n };\n\n const handleClickOutside = (e: MouseEvent) => {\n if (e.target !== rootRef.current && !rootRef.current?.contains(e.target as Node)) {\n setOpened(false);\n }\n };\n\n const chipsSelectOptions = React.useRef<HTMLElement[]>([]).current;\n\n const scrollToElement = (index: number, center = false) => {\n const dropdown = scrollBoxRef.current;\n const item = chipsSelectOptions[index];\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 = (index: number, oldIndex: number | null) => {\n const { length } = filteredOptions;\n\n if (index < 0) {\n index = length - 1;\n } else if (index >= length) {\n index = 0;\n }\n\n if (index === oldIndex) {\n return;\n }\n\n scrollToElement(index);\n setFocusedOptionIndex(index);\n };\n\n const focusOption = (nextIndex: number | null, type: FocusActionType) => {\n let index = nextIndex === null ? -1 : nextIndex;\n\n if (type === FOCUS_ACTION_NEXT) {\n index = index + 1;\n } else if (type === FOCUS_ACTION_PREV) {\n index = index - 1;\n }\n\n focusOptionByIndex(index, focusedOptionIndex);\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n onKeyDown!(e);\n\n if (e.key === 'ArrowUp' && !e.defaultPrevented) {\n e.preventDefault();\n\n if (!opened) {\n setOpened(true);\n setFocusedOptionIndex(0);\n } else {\n focusOption(focusedOptionIndex, FOCUS_ACTION_PREV);\n }\n }\n\n if (e.key === 'ArrowDown' && !e.defaultPrevented) {\n e.preventDefault();\n\n if (!opened) {\n setOpened(true);\n setFocusedOptionIndex(0);\n } else {\n focusOption(focusedOptionIndex, FOCUS_ACTION_NEXT);\n }\n }\n\n if (e.key === 'Enter' && !e.defaultPrevented && opened) {\n if (focusedOptionIndex != null) {\n const option = filteredOptions[focusedOptionIndex];\n\n if (option) {\n onChangeStart!(e, option);\n\n if (!e.defaultPrevented) {\n addOption(option);\n setFocusedOptionIndex(null);\n clearInput();\n closeAfterSelect && setOpened(false);\n e.preventDefault();\n }\n } else if (!creatable) {\n e.preventDefault();\n }\n } else if (!creatable) {\n e.preventDefault();\n }\n }\n\n if (['Escape', 'Tab'].includes(e.key) && !e.defaultPrevented && opened) {\n setOpened(false);\n }\n };\n\n React.useEffect(() => {\n if (focusedOptionIndex != null && filteredOptions[focusedOptionIndex]) {\n setFocusedOption(filteredOptions[focusedOptionIndex]);\n } else if (focusedOptionIndex === null || focusedOptionIndex === 0) {\n setFocusedOption(null);\n }\n }, [focusedOptionIndex, filteredOptions, setFocusedOption]);\n\n useGlobalEventListener(document, 'click', handleClickOutside);\n\n const renderChipWrapper = (renderChipProps: RenderChip<Option> | undefined) => {\n if (renderChipProps === undefined) {\n return null;\n }\n const onRemoveWrapper = (e: React.MouseEvent | undefined, value: ChipValue | undefined) => {\n e?.preventDefault();\n e?.stopPropagation();\n\n renderChipProps.onRemove?.(e, value);\n };\n\n return renderChip!({\n ...renderChipProps,\n onRemove: onRemoveWrapper,\n });\n };\n\n const isPopperDirectionTop = popperPlacement?.includes('top');\n\n const onPlacementChange = React.useCallback(\n (placement?: Placement) => {\n setPopperPlacement(placement);\n },\n [setPopperPlacement],\n );\n\n const onDropdownMouseLeave = React.useCallback(() => {\n setFocusedOptionIndex(null);\n }, [setFocusedOptionIndex]);\n\n const toggleOpened = () => {\n setOpened((prevOpened) => !prevOpened);\n };\n\n return (\n <>\n <FormField\n getRootRef={rootRef}\n style={style}\n className={classNames(\n styles['ChipsSelect'],\n opened &&\n (isPopperDirectionTop\n ? styles['ChipsSelect--pop-up']\n : styles['ChipsSelect--pop-down']),\n className,\n )}\n disabled={disabled}\n role=\"application\"\n aria-disabled={disabled}\n aria-readonly={restProps.readOnly}\n after={\n <IconButton\n className={styles['ChipsSelect__dropdown']}\n activeMode=\"\"\n hoverMode=\"\"\n // TODO: add label customization\n aria-label={opened ? 'Скрыть' : 'Развернуть'}\n onClick={toggleOpened}\n >\n {icon ?? <DropdownIcon className={styles['ChipsSelect__icon']} opened={opened} />}\n </IconButton>\n }\n before={before}\n >\n <ChipsInputBase\n {...restProps}\n tabIndex={tabIndex}\n value={selectedOptions}\n inputValue={fieldValue}\n getNewOptionData={getNewOptionData}\n getOptionLabel={getOptionLabel}\n getOptionValue={getOptionValue}\n renderChip={renderChipWrapper}\n onFocus={handleFocus}\n onKeyDown={handleKeyDown}\n placeholder={placeholder}\n getRef={getRef}\n disabled={disabled}\n onInputChange={handleInputChange}\n />\n </FormField>\n {opened && (\n <CustomSelectDropdown\n targetRef={rootRef}\n placement={popupDirection}\n scrollBoxRef={scrollBoxRef}\n onPlacementChange={onPlacementChange}\n onMouseLeave={onDropdownMouseLeave}\n fetching={fetching}\n sameWidth={fixDropdownWidth}\n forcePortal={forceDropdownPortal}\n >\n {showCreatable && (\n <CustomSelectOption\n hovered={focusedOptionIndex === 0}\n onMouseDown={addOptionFromInput}\n onMouseEnter={() => setFocusedOptionIndex(0)}\n >\n {creatableText}\n </CustomSelectOption>\n )}\n {!filteredOptions?.length && !showCreatable && emptyText ? (\n <Footnote className={styles['ChipsSelect__empty']}>{emptyText}</Footnote>\n ) : (\n filteredOptions.map((option: Option, index: number) => {\n const label = getOptionLabel!(option);\n const hovered =\n focusedOption && getOptionValue!(option) === getOptionValue!(focusedOption);\n const selected = selectedOptions.find((selectedOption: Option) => {\n return getOptionValue!(selectedOption) === getOptionValue!(option);\n });\n const value = getOptionValue!(option);\n\n return (\n <React.Fragment key={`${typeof value}-${value}`}>\n {renderOption!({\n option,\n hovered: Boolean(hovered),\n children: label,\n selected: !!selected,\n getRootRef: (e) => {\n if (e) {\n return (chipsSelectOptions[index] = e);\n }\n return undefined;\n },\n onMouseDown: (e: React.MouseEvent<HTMLDivElement>) => {\n onChangeStart?.(e, option);\n\n if (!e.defaultPrevented) {\n closeAfterSelect && setOpened(false);\n addOption(option);\n clearInput();\n }\n },\n onMouseEnter: () => setFocusedOptionIndex(index),\n })}\n </React.Fragment>\n );\n })\n )}\n </CustomSelectDropdown>\n )}\n </>\n );\n};\n"],"names":["React","classNames","noop","useChipsSelect","useExternRef","useGlobalEventListener","useDOM","defaultFilterFn","ChipsInputBase","chipsInputDefaultProps","CustomSelectDropdown","CustomSelectOption","DropdownIcon","FormField","IconButton","Footnote","FOCUS_ACTION_NEXT","FOCUS_ACTION_PREV","chipsSelectDefaultProps","emptyText","creatableText","onChangeStart","creatable","fetching","showSelected","closeAfterSelect","options","filterFn","renderOption","props","ChipsSelect","propsWithDefault","style","onFocus","onKeyDown","className","getRef","getRootRef","disabled","placeholder","tabIndex","getOptionValue","getOptionLabel","getNewOptionData","renderChip","popupDirection","inputValue","before","icon","fixDropdownWidth","forceDropdownPortal","restProps","document","useState","undefined","popperPlacement","setPopperPlacement","scrollBoxRef","useRef","rootRef","fieldValue","selectedOptions","opened","setOpened","addOptionFromInput","filteredOptions","addOption","handleInputChange","clearInput","focusedOption","setFocusedOption","focusedOptionIndex","setFocusedOptionIndex","showCreatable","Boolean","length","handleFocus","e","handleClickOutside","target","current","contains","chipsSelectOptions","scrollToElement","index","center","dropdown","item","dropdownHeight","offsetHeight","scrollTop","itemTop","offsetTop","itemHeight","focusOptionByIndex","oldIndex","focusOption","nextIndex","type","handleKeyDown","key","defaultPrevented","preventDefault","option","includes","useEffect","renderChipWrapper","renderChipProps","onRemoveWrapper","value","stopPropagation","onRemove","isPopperDirectionTop","onPlacementChange","useCallback","placement","onDropdownMouseLeave","toggleOpened","prevOpened","role","aria-disabled","aria-readonly","readOnly","after","activeMode","hoverMode","aria-label","onClick","onInputChange","targetRef","onMouseLeave","sameWidth","forcePortal","hovered","onMouseDown","onMouseEnter","map","label","selected","find","selectedOption","Fragment","children"],"mappings":"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"}
@@ -264,30 +264,36 @@ var defaultOptions = [];
264
264
  onClose,
265
265
  resetKeyboardInput
266
266
  ]);
267
- var selectFocused = React.useCallback(function() {
268
- if (focusedOptionIndex !== undefined && isValidIndex(focusedOptionIndex)) {
269
- var item = options[focusedOptionIndex];
270
- setNativeSelectValue(item === null || item === void 0 ? void 0 : item.value);
271
- close();
272
- var shouldTriggerOnChangeWhenControlledAndInnerValueIsOutOfSync = isControlledOutside && props.value !== nativeSelectValue && nativeSelectValue === (item === null || item === void 0 ? void 0 : item.value);
273
- if (shouldTriggerOnChangeWhenControlledAndInnerValueIsOutOfSync) {
274
- var _selectElRef_current;
275
- var event = new Event("change", {
276
- bubbles: true
277
- });
278
- (_selectElRef_current = selectElRef.current) === null || _selectElRef_current === void 0 ? void 0 : _selectElRef_current.dispatchEvent(event);
279
- }
267
+ var selectOption = React.useCallback(function(index) {
268
+ var item = options[index];
269
+ setNativeSelectValue(item === null || item === void 0 ? void 0 : item.value);
270
+ close();
271
+ var shouldTriggerOnChangeWhenControlledAndInnerValueIsOutOfSync = isControlledOutside && props.value !== nativeSelectValue && nativeSelectValue === (item === null || item === void 0 ? void 0 : item.value);
272
+ if (shouldTriggerOnChangeWhenControlledAndInnerValueIsOutOfSync) {
273
+ var _selectElRef_current;
274
+ var event = new Event("change", {
275
+ bubbles: true
276
+ });
277
+ (_selectElRef_current = selectElRef.current) === null || _selectElRef_current === void 0 ? void 0 : _selectElRef_current.dispatchEvent(event);
280
278
  }
281
279
  }, [
282
280
  close,
283
- focusedOptionIndex,
284
- isValidIndex,
285
281
  options,
286
282
  selectElRef,
287
283
  isControlledOutside,
288
284
  props.value,
289
285
  nativeSelectValue
290
286
  ]);
287
+ var selectFocused = React.useCallback(function() {
288
+ if (focusedOptionIndex === undefined || !isValidIndex(focusedOptionIndex)) {
289
+ return;
290
+ }
291
+ selectOption(focusedOptionIndex);
292
+ }, [
293
+ focusedOptionIndex,
294
+ isValidIndex,
295
+ selectOption
296
+ ]);
291
297
  var open = React.useCallback(function() {
292
298
  setOpened(true);
293
299
  setFocusedOptionIndex(selectedOptionIndex);
@@ -486,11 +492,11 @@ var defaultOptions = [];
486
492
  var index = Array.prototype.indexOf.call((_e_currentTarget_parentNode = e.currentTarget.parentNode) === null || _e_currentTarget_parentNode === void 0 ? void 0 : _e_currentTarget_parentNode.children, e.currentTarget);
487
493
  var option = options[index];
488
494
  if (option && !option.disabled) {
489
- selectFocused();
495
+ selectOption(index);
490
496
  }
491
497
  }, [
492
498
  options,
493
- selectFocused
499
+ selectOption
494
500
  ]);
495
501
  var handleOptionHover = React.useCallback(function(e) {
496
502
  var _e_currentTarget_parentNode;