UNPKG

nishant-design-system

Version:
118 lines (105 loc) 2.9 kB
// @flow strict import * as React from 'react'; import * as SPACES from '../../styles/variables/_space'; import classify from '../../utils/classify'; import {capitalize} from '../../utils/string'; import css from './Card.module.css'; type ClassNames = $ReadOnly<{wrapper?: string}>; export const PADDING_SIZES = Object.freeze({ small: 'small', medium: 'medium', large: 'large', }); export type PaddingSizeType = $Values<typeof PADDING_SIZES>; export type CardProps = { classNames?: ClassNames, children: React.Node, paddingTop?: PaddingSizeType, paddingRight?: PaddingSizeType, paddingBottom?: PaddingSizeType, paddingLeft?: PaddingSizeType, ... }; export type ClickableCardProps = { ...CardProps, onClick?: ?(SyntheticEvent<HTMLElement>) => mixed, disabled?: boolean, ... }; const getPaddingValue = (size: PaddingSizeType): string => { const spaceKey = 'space' + capitalize(size); return SPACES[spaceKey] || SPACES['spaceNone']; }; export const Card: React$AbstractComponent<CardProps, HTMLDivElement> = React.forwardRef<CardProps, HTMLDivElement>( ( { children, classNames, paddingTop = 'medium', paddingRight = 'medium', paddingBottom = 'medium', paddingLeft = 'medium', ...props }: CardProps, ref, ): React.Node => ( <div {...props} style={{ '--card-padding-top': getPaddingValue(paddingTop), '--card-padding-right': getPaddingValue(paddingRight), '--card-padding-bottom': getPaddingValue(paddingBottom), '--card-padding-left': getPaddingValue(paddingLeft), }} data-testid="Card" className={classify(css.cardWrapper, classNames?.wrapper)} ref={ref} > {children} </div> ), ); export const ClickableCard: React$AbstractComponent< ClickableCardProps, HTMLDivElement, > = React.forwardRef<ClickableCardProps, HTMLDivElement>( ( {classNames, onClick, disabled = false, ...props}: ClickableCardProps, ref, ): React.Node => { const componentRef = React.useRef(null); React.useImperativeHandle(ref, () => componentRef.current); React.useEffect(() => { if (disabled) { componentRef.current?.blur(); } }, [disabled]); const onClickHandler = (e) => { if (!disabled) { onClick && onClick(e); } }; const onKeyDownHandler = (e) => { if (e.key === 'Enter') { onClickHandler(e); } }; return ( <Card {...props} classNames={{ wrapper: classify( css.clickableCard, {[css.disabled]: disabled}, classNames?.wrapper, ), }} tabIndex={disabled ? -1 : 0} onClick={onClickHandler} onKeyDown={onKeyDownHandler} ref={ref} /> ); }, );