'use client'; import { classNames } from '@vkontakte/vkjs'; import { useAdaptivity } from '../../hooks/useAdaptivity'; import { type SizeTypeValues, ViewWidth, type ViewWidthType } from '../../lib/adaptivity'; import { mergeCalls } from '../../lib/mergeCalls'; import { checkClickable, Clickable, type ClickableProps } from '../Clickable/Clickable'; import { Ripple, useMaybeNeedRipple, useRipple } from './Ripple'; import { activeClass, DEFAULT_STATE_MODE, hoverClass, type StateProps } from './state'; import styles from './Tappable.module.css'; function getViewWidthClassName( viewWidth: ViewWidthType | 'none', legacySizeX: SizeTypeValues | undefined, ) { // TODO [>=10]: #9015 Удалить это условие if (legacySizeX !== undefined && legacySizeX === 'compact') { return styles.withBorder; } if (viewWidth === 'none') { return styles.withBorderOnSmallTabletMinus; } if (viewWidth < ViewWidth.SMALL_TABLET) { return styles.withBorder; } return; } function hasPointerClassName(hasPointer: boolean | undefined) { switch (hasPointer) { case undefined: return styles.hasPointerNone; case false: return styles.hasPointerFalse; } return undefined; } export interface TappableProps extends ClickableProps, StateProps { /** * Задает border-radius элементу * В режиме `auto` на маленьких экранах `border-radius: 0`, иначе определяется токеном `--vkui--size_border_radius--regular`. */ borderRadiusMode?: 'auto' | 'inherit' | undefined; /** * @deprecated Since 7.3.0. Будет удалeно в **VKUI v9**. * * Используйте свойство `activeMode`. */ activeClassName?: string | undefined; // TODO [>=9]: удалить неиспользуемое свойство. /** * @deprecated Since 7.3.0. Будет удалeно в **VKUI v9**. * * Используйте свойство `hoverMode`. */ hoverClassName?: string | undefined; // TODO [>=9]: удалить неиспользуемое свойство. } /** * @deprecated Не наследуйтесь от этого типа и от TappableProps. * * Компонентам не нужны лишние свойства Tappable компонента. */ export type TappableOmitProps = Omit< TappableProps, 'DefaultComponent' | 'baseClassName' | 'baseStyle' >; export const Tappable = ({ baseClassName, borderRadiusMode = 'auto', children, hoverMode = DEFAULT_STATE_MODE, activeMode = DEFAULT_STATE_MODE, onPointerDown, onPointerCancel, ...restProps }: TappableProps): React.ReactNode => { const isClickable = checkClickable(restProps); const { sizeX: legacySizeX, viewWidth = 'none', hasPointer } = useAdaptivity(); const needRipple = useMaybeNeedRipple(activeMode, hasPointer); const { clicks, ...rippleEvents } = useRipple(needRipple, hasPointer); const handlers = mergeCalls(rippleEvents, { onPointerDown, onPointerCancel, }); const typeProps = restProps.Component === 'button' ? { type: 'button' } : {}; return ( {children} {isClickable && (hoverMode === 'background' || activeMode === 'background') && ( )} ); };