feat: Adding className as a prop (#2847)

* Adding className as a prop to use emotion

* Adding className to feedback and input components
This commit is contained in:
Matheus Sanchez
2023-12-07 14:48:37 -03:00
committed by GitHub
parent d70f8deeec
commit 590912b30f
21 changed files with 125 additions and 65 deletions

View File

@ -14,13 +14,15 @@ const StyledContainer = styled.div`
width: 20px; width: 20px;
`; `;
export type CheckmarkProps = React.ComponentPropsWithoutRef<'div'>; export type CheckmarkProps = React.ComponentPropsWithoutRef<'div'> & {
className?: string;
};
export const Checkmark = (_props: CheckmarkProps) => { export const Checkmark = ({ className }: CheckmarkProps) => {
const theme = useTheme(); const theme = useTheme();
return ( return (
<StyledContainer> <StyledContainer className={className}>
<IconCheck color={theme.grayScale.gray0} size={14} /> <IconCheck color={theme.grayScale.gray0} size={14} />
</StyledContainer> </StyledContainer>
); );

View File

@ -16,6 +16,7 @@ export type EntityChipProps = {
avatarType?: AvatarType; avatarType?: AvatarType;
variant?: EntityChipVariant; variant?: EntityChipVariant;
LeftIcon?: IconComponent; LeftIcon?: IconComponent;
className?: string;
}; };
export enum EntityChipVariant { export enum EntityChipVariant {
@ -31,6 +32,7 @@ export const EntityChip = ({
avatarType = 'rounded', avatarType = 'rounded',
variant = EntityChipVariant.Regular, variant = EntityChipVariant.Regular,
LeftIcon, LeftIcon,
className,
}: EntityChipProps) => { }: EntityChipProps) => {
const navigate = useNavigate(); const navigate = useNavigate();
@ -69,6 +71,7 @@ export const EntityChip = ({
} }
clickable={!!linkToEntity} clickable={!!linkToEntity}
onClick={handleLinkClick} onClick={handleLinkClick}
className={className}
/> />
) : ( ) : (
<></> <></>

View File

@ -21,8 +21,10 @@ const StyledOverflowingText = styled.div<{ cursorPointer: boolean }>`
export const OverflowingTextWithTooltip = ({ export const OverflowingTextWithTooltip = ({
text, text,
className,
}: { }: {
text: string | null | undefined; text: string | null | undefined;
className?: string;
}) => { }) => {
const textElementId = `title-id-${uuidV4()}`; const textElementId = `title-id-${uuidV4()}`;
@ -51,6 +53,7 @@ export const OverflowingTextWithTooltip = ({
<> <>
<StyledOverflowingText <StyledOverflowingText
data-testid="tooltip" data-testid="tooltip"
className={className}
ref={textRef} ref={textRef}
id={textElementId} id={textElementId}
cursorPointer={isTitleOverflowing} cursorPointer={isTitleOverflowing}

View File

@ -4,6 +4,7 @@ type H2TitleProps = {
title: string; title: string;
description?: string; description?: string;
addornment?: React.ReactNode; addornment?: React.ReactNode;
className?: string;
}; };
const StyledContainer = styled.div` const StyledContainer = styled.div`
@ -33,8 +34,13 @@ const StyledDescription = styled.h3`
margin-top: ${({ theme }) => theme.spacing(3)}; margin-top: ${({ theme }) => theme.spacing(3)};
`; `;
export const H2Title = ({ title, description, addornment }: H2TitleProps) => ( export const H2Title = ({
<StyledContainer> title,
description,
addornment,
className,
}: H2TitleProps) => (
<StyledContainer className={className}>
<StyledTitleContainer> <StyledTitleContainer>
<StyledTitle>{title}</StyledTitle> <StyledTitle>{title}</StyledTitle>
{addornment} {addornment}

View File

@ -69,6 +69,7 @@ export type DialogProps = React.ComponentPropsWithoutRef<typeof motion.div> & {
buttons?: DialogButtonOptions[]; buttons?: DialogButtonOptions[];
allowDismiss?: boolean; allowDismiss?: boolean;
children?: React.ReactNode; children?: React.ReactNode;
className?: string;
onClose?: () => void; onClose?: () => void;
}; };
@ -78,6 +79,7 @@ export const Dialog = ({
buttons = [], buttons = [],
allowDismiss = true, allowDismiss = true,
children, children,
className,
onClose, onClose,
id, id,
}: DialogProps) => { }: DialogProps) => {
@ -133,6 +135,7 @@ export const Dialog = ({
closeSnackbar(); closeSnackbar();
} }
}} }}
className={className}
> >
<StyledDialogContainer <StyledDialogContainer
variants={containerVariants} variants={containerVariants}

View File

@ -16,6 +16,12 @@ export type ProgressBarProps = {
barHeight?: number; barHeight?: number;
barColor?: string; barColor?: string;
autoStart?: boolean; autoStart?: boolean;
className?: string;
};
export type StyledBarProps = {
barHeight?: number;
className?: string;
}; };
export type ProgressBarControls = AnimationControls & { export type ProgressBarControls = AnimationControls & {
@ -23,7 +29,7 @@ export type ProgressBarControls = AnimationControls & {
pause: () => Promise<any>; pause: () => Promise<any>;
}; };
const StyledBar = styled.div<Pick<ProgressBarProps, 'barHeight'>>` const StyledBar = styled.div<StyledBarProps>`
height: ${({ barHeight }) => barHeight}px; height: ${({ barHeight }) => barHeight}px;
overflow: hidden; overflow: hidden;
width: 100%; width: 100%;
@ -43,6 +49,7 @@ export const ProgressBar = forwardRef<ProgressBarControls, ProgressBarProps>(
barHeight = 24, barHeight = 24,
barColor, barColor,
autoStart = true, autoStart = true,
className,
}, },
ref, ref,
) => { ) => {
@ -86,7 +93,7 @@ export const ProgressBar = forwardRef<ProgressBarControls, ProgressBarProps>(
}, [controls, delay, duration, easing, autoStart, start]); }, [controls, delay, duration, easing, autoStart, start]);
return ( return (
<StyledBar barHeight={barHeight}> <StyledBar className={className} barHeight={barHeight}>
<StyledBarFilling <StyledBarFilling
style={{ style={{
originX: 0, originX: 0,

View File

@ -99,6 +99,7 @@ export interface SnackBarProps extends React.ComponentPropsWithoutRef<'div'> {
duration?: number; duration?: number;
variant?: SnackbarVariant; variant?: SnackbarVariant;
children?: React.ReactNode; children?: React.ReactNode;
className?: string;
onClose?: () => void; onClose?: () => void;
} }
@ -113,6 +114,7 @@ export const SnackBar = ({
onClose, onClose,
id, id,
title, title,
className,
}: SnackBarProps) => { }: SnackBarProps) => {
const theme = useTheme(); const theme = useTheme();
@ -157,6 +159,7 @@ export const SnackBar = ({
return ( return (
<StyledMotionContainer <StyledMotionContainer
className={className}
aria-live={role === 'alert' ? 'assertive' : 'polite'} aria-live={role === 'alert' ? 'assertive' : 'polite'}
{...{ id, onMouseEnter, onMouseLeave, role, title, variant }} {...{ id, onMouseEnter, onMouseLeave, role, title, variant }}
> >

View File

@ -13,13 +13,15 @@ const StyledFloatingButtonGroupContainer = styled.div`
export type FloatingButtonGroupProps = Pick<FloatingButtonProps, 'size'> & { export type FloatingButtonGroupProps = Pick<FloatingButtonProps, 'size'> & {
children: React.ReactElement[]; children: React.ReactElement[];
className?: string;
}; };
export const FloatingButtonGroup = ({ export const FloatingButtonGroup = ({
children, children,
size, size,
className,
}: FloatingButtonGroupProps) => ( }: FloatingButtonGroupProps) => (
<StyledFloatingButtonGroupContainer> <StyledFloatingButtonGroupContainer className={className}>
{React.Children.map(children, (child, index) => { {React.Children.map(children, (child, index) => {
let position: FloatingButtonPosition; let position: FloatingButtonPosition;

View File

@ -18,6 +18,7 @@ export type IconButtonGroupProps = Pick<
Icon: IconComponent; Icon: IconComponent;
onClick?: (event: MouseEvent<any>) => void; onClick?: (event: MouseEvent<any>) => void;
}[]; }[];
className?: string;
}; };
export const IconButtonGroup = ({ export const IconButtonGroup = ({
@ -25,8 +26,9 @@ export const IconButtonGroup = ({
iconButtons, iconButtons,
size, size,
variant, variant,
className,
}: IconButtonGroupProps) => ( }: IconButtonGroupProps) => (
<StyledIconButtonGroupContainer> <StyledIconButtonGroupContainer className={className}>
{iconButtons.map(({ Icon, onClick }, index) => { {iconButtons.map(({ Icon, onClick }, index) => {
const position: IconButtonPosition = const position: IconButtonPosition =
index === 0 index === 0

View File

@ -106,10 +106,14 @@ export const MainButton = ({
type, type,
onClick, onClick,
disabled, disabled,
className,
}: MainButtonProps) => { }: MainButtonProps) => {
const theme = useTheme(); const theme = useTheme();
return ( return (
<StyledButton {...{ disabled, fullWidth, onClick, type, variant }}> <StyledButton
className={className}
{...{ disabled, fullWidth, onClick, type, variant }}
>
{Icon && <Icon size={theme.icon.size.sm} />} {Icon && <Icon size={theme.icon.size.sm} />}
{title} {title}
</StyledButton> </StyledButton>

View File

@ -37,11 +37,12 @@ export const RoundedIconButton = ({
Icon, Icon,
onClick, onClick,
disabled, disabled,
className,
}: RoundedIconButtonProps) => { }: RoundedIconButtonProps) => {
const theme = useTheme(); const theme = useTheme();
return ( return (
<StyledIconButton {...{ disabled, onClick }}> <StyledIconButton className={className} {...{ disabled, onClick }}>
{<Icon size={theme.icon.size.md} />} {<Icon size={theme.icon.size.md} />}
</StyledIconButton> </StyledIconButton>
); );

View File

@ -96,17 +96,20 @@ const StyledColorSchemeContent = styled(motion.div)<
export type ColorSchemeSegmentProps = { export type ColorSchemeSegmentProps = {
variant: ColorScheme; variant: ColorScheme;
controls: AnimationControls; controls: AnimationControls;
className?: string;
} & React.ComponentPropsWithoutRef<'div'>; } & React.ComponentPropsWithoutRef<'div'>;
const ColorSchemeSegment = ({ const ColorSchemeSegment = ({
variant, variant,
controls, controls,
style, style,
className,
onClick, onClick,
onMouseEnter, onMouseEnter,
onMouseLeave, onMouseLeave,
}: ColorSchemeSegmentProps) => ( }: ColorSchemeSegmentProps) => (
<StyledColorSchemeBackground <StyledColorSchemeBackground
className={className}
{...{ variant, style, onClick, onMouseEnter, onMouseLeave }} {...{ variant, style, onClick, onMouseEnter, onMouseLeave }}
> >
<StyledColorSchemeContent animate={controls} variant={variant}> <StyledColorSchemeContent animate={controls} variant={variant}>

View File

@ -27,14 +27,16 @@ const StyledLabel = styled.span`
export type ColorSchemePickerProps = { export type ColorSchemePickerProps = {
value: ColorScheme; value: ColorScheme;
className?: string;
onChange: (value: ColorScheme) => void; onChange: (value: ColorScheme) => void;
}; };
export const ColorSchemePicker = ({ export const ColorSchemePicker = ({
value, value,
onChange, onChange,
className,
}: ColorSchemePickerProps) => ( }: ColorSchemePickerProps) => (
<StyledContainer> <StyledContainer className={className}>
<StyledCardContainer> <StyledCardContainer>
<ColorSchemeCard <ColorSchemeCard
onClick={() => onChange('Light')} onClick={() => onChange('Light')}

View File

@ -26,6 +26,7 @@ type AutosizeTextInputProps = {
variant?: AutosizeTextInputVariant; variant?: AutosizeTextInputVariant;
buttonTitle?: string; buttonTitle?: string;
value?: string; value?: string;
className?: string;
}; };
const StyledContainer = styled.div` const StyledContainer = styled.div`
@ -117,6 +118,7 @@ export const AutosizeTextInput = ({
variant = AutosizeTextInputVariant.Default, variant = AutosizeTextInputVariant.Default,
buttonTitle, buttonTitle,
value = '', value = '',
className,
}: AutosizeTextInputProps) => { }: AutosizeTextInputProps) => {
const [isFocused, setIsFocused] = useState(false); const [isFocused, setIsFocused] = useState(false);
const [isHidden, setIsHidden] = useState( const [isHidden, setIsHidden] = useState(
@ -183,7 +185,7 @@ export const AutosizeTextInput = ({
return ( return (
<> <>
<StyledContainer> <StyledContainer className={className}>
<StyledInputContainer> <StyledInputContainer>
{!isHidden && ( {!isHidden && (
<StyledTextArea <StyledTextArea

View File

@ -28,6 +28,7 @@ type CheckboxProps = {
variant?: CheckboxVariant; variant?: CheckboxVariant;
size?: CheckboxSize; size?: CheckboxSize;
shape?: CheckboxShape; shape?: CheckboxShape;
className?: string;
}; };
const StyledInputContainer = styled.div` const StyledInputContainer = styled.div`
@ -117,6 +118,7 @@ export const Checkbox = ({
variant = CheckboxVariant.Primary, variant = CheckboxVariant.Primary,
size = CheckboxSize.Small, size = CheckboxSize.Small,
shape = CheckboxShape.Squared, shape = CheckboxShape.Squared,
className,
}: CheckboxProps) => { }: CheckboxProps) => {
const [isInternalChecked, setIsInternalChecked] = const [isInternalChecked, setIsInternalChecked] =
React.useState<boolean>(false); React.useState<boolean>(false);
@ -134,7 +136,7 @@ export const Checkbox = ({
const checkboxId = 'checkbox' + v4(); const checkboxId = 'checkbox' + v4();
return ( return (
<StyledInputContainer> <StyledInputContainer className={className}>
<StyledInput <StyledInput
autoComplete="off" autoComplete="off"
type="checkbox" type="checkbox"

View File

@ -13,6 +13,7 @@ export type EntityTitleDoubleTextInputProps = {
firstValuePlaceholder: string; firstValuePlaceholder: string;
secondValuePlaceholder: string; secondValuePlaceholder: string;
onChange: (firstValue: string, secondValue: string) => void; onChange: (firstValue: string, secondValue: string) => void;
className?: string;
}; };
const StyledDoubleTextContainer = styled.div` const StyledDoubleTextContainer = styled.div`
@ -41,6 +42,7 @@ export const EntityTitleDoubleTextInput = ({
firstValuePlaceholder, firstValuePlaceholder,
secondValuePlaceholder, secondValuePlaceholder,
onChange, onChange,
className,
}: EntityTitleDoubleTextInputProps) => { }: EntityTitleDoubleTextInputProps) => {
const { const {
goBackToPreviousHotkeyScope, goBackToPreviousHotkeyScope,
@ -54,7 +56,7 @@ export const EntityTitleDoubleTextInput = ({
}; };
return ( return (
<StyledDoubleTextContainer> <StyledDoubleTextContainer className={className}>
<ComputeNodeDimensions node={firstValue || firstValuePlaceholder}> <ComputeNodeDimensions node={firstValue || firstValuePlaceholder}>
{(nodeDimensions) => ( {(nodeDimensions) => (
<StyledTextInput <StyledTextInput

View File

@ -26,6 +26,7 @@ type IconPickerProps = {
onClose?: () => void; onClose?: () => void;
onOpen?: () => void; onOpen?: () => void;
variant?: IconButtonVariant; variant?: IconButtonVariant;
className?: string;
}; };
const StyledMenuIconItemsContainer = styled.div` const StyledMenuIconItemsContainer = styled.div`
@ -52,6 +53,7 @@ export const IconPicker = ({
onClose, onClose,
onOpen, onOpen,
variant = 'secondary', variant = 'secondary',
className,
}: IconPickerProps) => { }: IconPickerProps) => {
const [searchString, setSearchString] = useState(''); const [searchString, setSearchString] = useState('');
@ -79,55 +81,57 @@ export const IconPicker = ({
return ( return (
<DropdownScope dropdownScopeId={dropdownScopeId}> <DropdownScope dropdownScopeId={dropdownScopeId}>
<Dropdown <div className={className}>
dropdownHotkeyScope={{ scope: IconPickerHotkeyScope.IconPicker }} <Dropdown
clickableComponent={ dropdownHotkeyScope={{ scope: IconPickerHotkeyScope.IconPicker }}
<IconButton clickableComponent={
disabled={disabled} <IconButton
Icon={selectedIconKey ? icons[selectedIconKey] : IconApps} disabled={disabled}
variant={variant} Icon={selectedIconKey ? icons[selectedIconKey] : IconApps}
/> variant={variant}
}
dropdownMenuWidth={176}
dropdownComponents={
<DropdownMenu width={176}>
<DropdownMenuSearchInput
placeholder="Search icon"
autoFocus
onChange={(event) => setSearchString(event.target.value)}
/> />
<DropdownMenuSeparator /> }
<DropdownMenuItemsContainer> dropdownMenuWidth={176}
{isLoading ? ( dropdownComponents={
<DropdownMenuSkeletonItem /> <DropdownMenu width={176}>
) : ( <DropdownMenuSearchInput
<StyledMenuIconItemsContainer> placeholder="Search icon"
{iconKeys.map((iconKey) => ( autoFocus
<StyledLightIconButton onChange={(event) => setSearchString(event.target.value)}
key={iconKey} />
aria-label={convertIconKeyToLabel(iconKey)} <DropdownMenuSeparator />
isSelected={selectedIconKey === iconKey} <DropdownMenuItemsContainer>
size="medium" {isLoading ? (
title={iconKey} <DropdownMenuSkeletonItem />
Icon={icons[iconKey]} ) : (
onClick={() => { <StyledMenuIconItemsContainer>
onChange({ iconKey, Icon: icons[iconKey] }); {iconKeys.map((iconKey) => (
closeDropdown(); <StyledLightIconButton
}} key={iconKey}
/> aria-label={convertIconKeyToLabel(iconKey)}
))} isSelected={selectedIconKey === iconKey}
</StyledMenuIconItemsContainer> size="medium"
)} title={iconKey}
</DropdownMenuItemsContainer> Icon={icons[iconKey]}
</DropdownMenu> onClick={() => {
} onChange({ iconKey, Icon: icons[iconKey] });
onClickOutside={onClickOutside} closeDropdown();
onClose={() => { }}
onClose?.(); />
setSearchString(''); ))}
}} </StyledMenuIconItemsContainer>
onOpen={onOpen} )}
/> </DropdownMenuItemsContainer>
</DropdownMenu>
}
onClickOutside={onClickOutside}
onClose={() => {
onClose?.();
setSearchString('');
}}
onOpen={onOpen}
/>
</div>
</DropdownScope> </DropdownScope>
); );
}; };

View File

@ -90,6 +90,7 @@ type ImageInputProps = Omit<React.ComponentProps<'div'>, 'children'> & {
isUploading?: boolean; isUploading?: boolean;
errorMessage?: string | null; errorMessage?: string | null;
disabled?: boolean; disabled?: boolean;
className?: string;
}; };
export const ImageInput = ({ export const ImageInput = ({
@ -100,6 +101,7 @@ export const ImageInput = ({
isUploading = false, isUploading = false,
errorMessage, errorMessage,
disabled = false, disabled = false,
className,
}: ImageInputProps) => { }: ImageInputProps) => {
const theme = useTheme(); const theme = useTheme();
const hiddenFileInput = React.useRef<HTMLInputElement>(null); const hiddenFileInput = React.useRef<HTMLInputElement>(null);
@ -108,7 +110,7 @@ export const ImageInput = ({
}; };
return ( return (
<StyledContainer> <StyledContainer className={className}>
<StyledPicture <StyledPicture
withPicture={!!picture} withPicture={!!picture}
disabled={disabled} disabled={disabled}

View File

@ -118,6 +118,7 @@ export const Radio = ({
size = RadioSize.Small, size = RadioSize.Small,
labelPosition = LabelPosition.Right, labelPosition = LabelPosition.Right,
disabled = false, disabled = false,
className,
}: RadioProps) => { }: RadioProps) => {
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => { const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
onChange?.(event); onChange?.(event);
@ -125,7 +126,7 @@ export const Radio = ({
}; };
return ( return (
<StyledContainer labelPosition={labelPosition}> <StyledContainer className={className} labelPosition={labelPosition}>
<StyledRadioInput <StyledRadioInput
type="radio" type="radio"
id="input-radio" id="input-radio"

View File

@ -14,6 +14,7 @@ export type TextAreaProps = {
onChange?: (value: string) => void; onChange?: (value: string) => void;
placeholder?: string; placeholder?: string;
value?: string; value?: string;
className?: string;
}; };
const StyledTextArea = styled(TextareaAutosize)` const StyledTextArea = styled(TextareaAutosize)`
@ -51,6 +52,7 @@ export const TextArea = ({
placeholder, placeholder,
minRows = 1, minRows = 1,
value = '', value = '',
className,
onChange, onChange,
}: TextAreaProps) => { }: TextAreaProps) => {
const computedMinRows = Math.min(minRows, MAX_ROWS); const computedMinRows = Math.min(minRows, MAX_ROWS);
@ -78,6 +80,7 @@ export const TextArea = ({
onFocus={handleFocus} onFocus={handleFocus}
onBlur={handleBlur} onBlur={handleBlur}
disabled={disabled} disabled={disabled}
className={className}
/> />
); );
}; };

View File

@ -36,6 +36,7 @@ export type ToggleProps = {
onChange?: (value: boolean) => void; onChange?: (value: boolean) => void;
color?: string; color?: string;
toggleSize?: ToggleSize; toggleSize?: ToggleSize;
className?: string;
}; };
export const Toggle = ({ export const Toggle = ({
@ -43,6 +44,7 @@ export const Toggle = ({
onChange, onChange,
color, color,
toggleSize = 'medium', toggleSize = 'medium',
className,
}: ToggleProps) => { }: ToggleProps) => {
const [isOn, setIsOn] = useState(value ?? false); const [isOn, setIsOn] = useState(value ?? false);
@ -72,6 +74,7 @@ export const Toggle = ({
isOn={isOn} isOn={isOn}
color={color} color={color}
toggleSize={toggleSize} toggleSize={toggleSize}
className={className}
> >
<StyledCircle <StyledCircle
animate={isOn ? 'on' : 'off'} animate={isOn ? 'on' : 'off'}