Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1141x 1141x 1141x 1141x 1141x 573x 573x 573x 573x 573x 1141x 1141x 1141x 1141x 1142x 1142x 1142x 1142x 1142x 1142x 1142x 1142x 1142x 1142x 1142x 1142x 1142x 1142x 1142x 1142x 1142x 1142x 1142x 1142x 1142x 1142x 1142x 1142x 1142x 1142x 1142x 1142x 1142x 1141x 1141x 1141x 1140x 1x 1x 1x 1141x 1141x 1x | import React, { memo, MouseEventHandler, useMemo, ButtonHTMLAttributes } from 'react'; import classNames from 'classnames'; import { useFallbackTranslation } from '@/hooks/useFallbackTranslation'; export type TypeButton = 'button' | 'submit' | 'reset'; export type IButtonVariantTypes = 'primary' | 'secondary' | 'tertiary' | 'round'; export enum ButtonVariant { PRIMARY = 'primary', SECONDARY = 'secondary', TERTIARY = 'tertiary', ROUND = 'round', } const { PRIMARY, SECONDARY, TERTIARY, ROUND } = ButtonVariant; export interface IButtonComponent extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'type'> { id?: string; key?: string; name?: string; type?: TypeButton; children?: React.ReactNode; handleClick?: MouseEventHandler<HTMLButtonElement>; active?: boolean; className?: string; tooltip?: string; variant?: IButtonVariantTypes; buttonsConfig?: IButtonComponent[]; configCustomClass?: string; size?: 'xs' | 'sm' | 'lg'; selected?: boolean; } const Button: React.FC<IButtonComponent> = (props) => { const { buttonsConfig, configCustomClass } = props || {}; const { t } = useFallbackTranslation(); const baseClasses = 'button-component'; const variantClasses = useMemo( () => ({ primary: PRIMARY, secondary: SECONDARY, tertiary: TERTIARY, round: 'round rounded-full', }), [] ); const disabledClasses = 'bg-gray text-disabled cursor-not-allowed'; const buttonRender = (btn: IButtonComponent): React.JSX.Element => { const { handleClick, className, name, children, size = 'sm', variant = PRIMARY, disabled, active, ...rest } = btn; const sizeClasses = { xs: variant === ROUND ? 'text-sm h-6 w-6' : 'text-xs px-1 py-1', sm: variant === ROUND ? 'text-base h-8 w-8' : 'text-sm px-3 py-2', lg: variant === ROUND ? 'text-xl h-12 w-12' : 'text-base px-4 py-3', }; const buttonVariantClass = classNames( baseClasses, variantClasses[variant], sizeClasses[size], disabled ? disabledClasses : '', className, { active: active, } ); const shouldUseAriaLabelledBy = 'aria-labelledby' in btn && !!btn['aria-labelledby']; const fallbackAriaLabel = name ? t(name) : 'Unnamed Button'; return ( <button {...rest} type={btn.type || 'button'} onClick={handleClick} aria-label={!shouldUseAriaLabelledBy ? (btn['aria-label'] ?? fallbackAriaLabel) : undefined} className={buttonVariantClass} disabled={disabled ?? false} > {name ? t(name) : children} </button> ); }; return ( <> {!buttonsConfig?.length ? ( buttonRender(props) ) : ( <div className={configCustomClass ?? 'flex gap-8'}> {buttonsConfig?.map((btn, i) => <React.Fragment key={btn.id ?? btn.name ?? `btn-${i}`}>{buttonRender(btn)}</React.Fragment>)} </div> )} </> ); }; export default memo(Button); |