import styles from './styles/rt-button.module.css'; import config from './styles/component-values-button.module.css'; import classnames from 'classnames/bind'; import { RtButtonProps } from './rt-button.types'; import { ElementRef, ElementType, ForwardedRef, forwardRef, ReactNode, useMemo, } from 'react'; import { RtText } from '@dpa/react-text'; import { RtFrame } from '@dpa/react-frame-intro'; import { useRtBaseProps } from '@dpa/react-hoc'; import { useGridChild } from '@dpa/react-grid'; import { RtSpinner } from '@dpa/react-loaders'; import { getSurfaceState } from './utils/getSurfaceState'; import { getSpinnerSize } from './utils/getSpinnerSize'; import { mapIconSize } from './utils/map-icon-size'; const cn = classnames.bind(styles); /** * Примечание: * - кнопка не должна содержать одновременно leadingIcon и leadingSlot * - кнопка не должна содержать одновременно trailingIcon и trailingSlot * - кнопка не должна содержать одновременно topIcon и prependSlot * - кнопка не должна содержать одновременно bottomIcon и appendSlot * */ export const RtInternalButton = ( props: RtButtonProps, ref: ForwardedRef ) => { const { modifier, use = 'primary', label, subLabel, leadingIcon: LeadingIcon, trailingIcon: TrailingIcon, prependIcon: TopIcon, appendIcon: BottomIcon, leadingSlot, trailingSlot, prependSlot, appendSlot, height = 'hug', width = 'hug', textWidth = 'hug', textHeight = 'hug', textJustify = 'center', disabled, size = 'sm', radius = 'primary', textWrap = false, name, type, tabIndex, loading, textDecorationLine = 'none', as: renderAs, className: __cn__, style: __style__, ...otherProps } = props; const showLabels = [ label, subLabel, prependSlot, TopIcon, appendSlot, BottomIcon, ].some((item) => item !== undefined); const showLabelsGroup = [label, subLabel].some((item) => item !== undefined); const baseProps = useRtBaseProps(otherProps, '0.2.2'); const { gridChildClassname, gridAttributes } = useGridChild({ size: size === 'xl' ? 'lg' : size, radius, }); const surfaceState = getSurfaceState({ disabled, loading }); const spinnerSize = getSpinnerSize(size); const iconTypography = `symbol-${mapIconSize(size)}-primary`; const Component = renderAs ?? 'button'; const buttonProps = useMemo(() => { if (Component === 'button') { return { name, type, tabIndex, disabled: disabled || loading, }; } return {}; }, [name, type, tabIndex, disabled, loading, Component]); return ( {!!LeadingIcon && } {leadingSlot !== undefined && leadingSlot} {showLabels && ( {!!TopIcon && } {prependSlot !== undefined && prependSlot} {showLabelsGroup && ( {label !== undefined && ( {label} )} {subLabel !== undefined && ( {subLabel} )} )} {appendSlot !== undefined && appendSlot} {!!BottomIcon && } )} {TrailingIcon && } {trailingSlot !== undefined && trailingSlot} {loading && ( )} ); }; export const RtButton = forwardRef(RtInternalButton) as < T extends ElementType = 'button' >( props: RtButtonProps & { ref?: ForwardedRef>; } ) => ReactNode; RtButton.displayName = 'RtButton';