import React, { ButtonHTMLAttributes, forwardRef, useMemo } from 'react';
import { isFragment, isElement } from 'react-is';
import { type TStyle, useClassnames } from '../../../hooks/use-classnames';
import { Loader } from '../../loader';
import style from './index.module.pcss';
type TNative = ButtonHTMLAttributes;
export interface IProps {
/**
* CSS класс или классы, которые будут применены к кнопке.
**/
readonly className?: TStyle | string,
/**
* Устанавливает размер кнопки.
**/
readonly presetSize?: 'large' | 'medium' | 'small',
/**
* Устанавливает стиль кнопки.
**/
readonly presetStyle?: 'primary' | 'default' | 'dashed' | 'ghost' | 'negative' | 'success' | 'deprecated',
/**
* Если установлен в true, то кнопка будет в состоянии загрузки.
**/
readonly isLoading?: boolean,
/**
* Если установлен в true, то кнопка будет компактной.
**/
readonly isCompact?: boolean,
/**
* Уникальный идентификатор для кнопки.
**/
readonly id?: TNative['id'],
/**
* Устанавливает тип кнопки.
**/
readonly type?: TNative['type'],
/**
* Устанавливает порядок перехода по кнопке с помощью клавиши `Tab`.
**/
readonly tabIndex?: TNative['tabIndex'],
/**
* Определяет функцию обратного вызова, которая будет вызвана при фокусировке на кнопке.
**/
readonly onFocus?: TNative['onFocus'],
/**
* Определяет функцию обратного вызова, которая будет выполнена при нажатии на кнопку.
**/
readonly onClick?: TNative['onClick'],
/**
* Содержимое кнопки.
**/
readonly children?: TNative['children'],
/**
* Устанавливает горячую клавишу для кнопки.
**/
readonly accessKey?: TNative['accessKey'],
/**
* Если установлен в true, то кнопка будет заблокирована.
**/
readonly disabled?: TNative['disabled']
}
const LOADER_STYLE_MAP = {
primary : 'white',
default : 'rich-grey',
dashed : 'rich-grey',
ghost : 'rich-grey',
negative : 'red',
success : 'rich-grey',
deprecated: 'white'
} as const;
const isValidCompact = (element: IProps['children']) => {
// @ts-expect-error Непонятно как быть с типом
return isElement(element) && !!(element.type === 'svg' || !isFragment(element) && element.type.name?.startsWith('Icon'));
};
const isCompact = (element: IProps['children']) => {
return Array.isArray(element) ? element.every(isValidCompact) : isValidCompact(element);
};
/**
* Компонент `Button` представляет собой кнопку, которая может использоваться для выполнения каких-либо действий в приложении.
**/
export const Button = forwardRef(({ presetSize = 'medium', presetStyle = 'default', type = 'button', ...props }, ref) => {
const cn = useClassnames(style, props.className);
const elChildren = useMemo(() => {
if(props.isLoading) {
return (
);
}
return props.children;
}, [props.children, props.isLoading, presetStyle]);
return (
);
});