'use client'; import * as React from 'react'; import { classNames, hasReactNode } from '@vkontakte/vkjs'; import { useAdaptivity } from '../../hooks/useAdaptivity'; import { usePlatform } from '../../hooks/usePlatform'; import type { HasAlign } from '../../types'; import { Spinner } from '../Spinner/Spinner'; import { Tappable, type TappableOmitProps } from '../Tappable/Tappable'; import '../Tappable/Tappable.module.css'; import '../Spinner/Spinner.module.css'; import styles from './Button.module.css'; const stylesSize = { s: styles.sizeS, m: styles.sizeM, l: styles.sizeL, }; const stylesMode = { primary: styles.modePrimary, secondary: styles.modeSecondary, tertiary: styles.modeTertiary, outline: styles.modeOutline, link: styles.modeLink, }; const stylesAppearance = { 'accent': styles.appearanceAccent, 'positive': styles.appearancePositive, 'negative': styles.appearanceNegative, 'neutral': styles.appearanceNeutral, 'overlay': styles.appearanceOverlay, 'accent-invariable': styles.appearanceAccentInvariable, }; const stylesAlign = { left: styles.alignLeft, right: styles.alignRight, }; const sizeYClassNames = { none: styles.sizeYNone, regular: styles.sizeYRegular, }; export interface VKUIButtonProps extends HasAlign { /** * Режим отображения кнопки. */ mode?: 'primary' | 'secondary' | 'tertiary' | 'outline' | 'link'; /** * Цветовая схема кнопки. */ appearance?: 'accent' | 'positive' | 'negative' | 'neutral' | 'overlay' | 'accent-invariable'; /** * Размер кнопки. */ size?: 's' | 'm' | 'l'; /** * Растягивает кнопку на всю ширину контейнера. */ stretched?: boolean; /** * Контент, отображаемый перед основным содержимым кнопки. */ before?: React.ReactNode; /** * Контент, отображаемый после основного содержимого кнопки. */ after?: React.ReactNode; /** * Включает состояние загрузки (отображает спиннер). */ loading?: boolean; /** * Отключает анимацию спиннера загрузки. */ disableSpinnerAnimation?: boolean; /** * Добавляет скругленные углы кнопке. */ rounded?: boolean; } export interface ButtonProps extends Omit, VKUIButtonProps {} /** * @see https://vkui.io/components/button */ export const Button = ({ size = 's', mode = 'primary', appearance = 'accent', stretched = false, align = 'center', children, before, after, getRootRef, loading, onClick, disableSpinnerAnimation, rounded, disabled, ...restProps }: ButtonProps): React.ReactNode => { const hasIconOnly = !children && Boolean(after) !== Boolean(before); const { sizeY = 'none' } = useAdaptivity(); const platform = usePlatform(); return ( {loading && ( )} {hasReactNode(before) && ( {before} )} {hasReactNode(children) && ( {children} )} {hasReactNode(after) && ( {after} )} ); };