mirror of
https://github.com/twentyhq/twenty.git
synced 2025-01-06 03:45:15 +03:00
Update the frontend to adhere to the custom eslint rule twenty/no-spread-props
(#1958)
* Update the frontend to adhere to the custom eslint rule `twenty/no-spread-props` Co-authored-by: v1b3m <vibenjamin6@gmail.com> * Update the frontend to adhere to the custom eslint rule `twenty/no-spread-props` Co-authored-by: v1b3m <vibenjamin6@gmail.com> * resolve bug with data-testid --------- Co-authored-by: v1b3m <vibenjamin6@gmail.com> Co-authored-by: bosiraphael <raphael.bosi@gmail.com>
This commit is contained in:
parent
5dddd77eb3
commit
bf397bc6ec
@ -7,13 +7,12 @@ type CellCommentChipProps = CommentChipProps;
|
||||
// TODO: tie those fixed values to the other components in the cell
|
||||
const StyledCellWrapper = styled.div``;
|
||||
|
||||
export const CellCommentChip = (props: CellCommentChipProps) => {
|
||||
if (props.count === 0) return null;
|
||||
export const CellCommentChip = ({ count, onClick }: CellCommentChipProps) => {
|
||||
if (count === 0) return null;
|
||||
|
||||
return (
|
||||
<StyledCellWrapper>
|
||||
{/* eslint-disable-next-line twenty/no-spread-props */}
|
||||
<CommentChip {...props} />
|
||||
<CommentChip count={count} onClick={onClick} />
|
||||
</StyledCellWrapper>
|
||||
);
|
||||
};
|
||||
|
@ -2,7 +2,7 @@ import styled from '@emotion/styled';
|
||||
|
||||
import { getImageAbsoluteURIOrBase64 } from '@/users/utils/getProfilePictureAbsoluteURI';
|
||||
|
||||
type LogoProps = React.ComponentProps<'div'> & {
|
||||
type LogoProps = {
|
||||
workspaceLogo?: string | null;
|
||||
};
|
||||
|
||||
@ -47,19 +47,17 @@ const StyledMainLogo = styled.div<StyledMainLogoProps>`
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
export const Logo = ({ workspaceLogo, ...props }: LogoProps) => {
|
||||
export const Logo = ({ workspaceLogo }: LogoProps) => {
|
||||
if (!workspaceLogo) {
|
||||
return (
|
||||
// eslint-disable-next-line twenty/no-spread-props
|
||||
<StyledContainer {...props}>
|
||||
<StyledContainer>
|
||||
<StyledMainLogo logo="/icons/android/android-launchericon-192-192.png" />
|
||||
</StyledContainer>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
// eslint-disable-next-line twenty/no-spread-props
|
||||
<StyledContainer {...props}>
|
||||
<StyledContainer>
|
||||
<StyledMainLogo logo={getImageAbsoluteURIOrBase64(workspaceLogo)} />
|
||||
<StyledTwentyLogoContainer>
|
||||
<StyledTwentyLogo src="/icons/android/android-launchericon-192-192.png" />
|
||||
|
@ -8,11 +8,10 @@ const StyledContent = styled(UIModal.Content)`
|
||||
width: calc(400px - ${({ theme }) => theme.spacing(10 * 2)});
|
||||
`;
|
||||
|
||||
type AuthModalProps = React.ComponentProps<'div'>;
|
||||
type AuthModalProps = { children: React.ReactNode };
|
||||
|
||||
export const AuthModal = ({ children, ...restProps }: AuthModalProps) => (
|
||||
// eslint-disable-next-line twenty/no-spread-props
|
||||
<UIModal isOpen={true} {...restProps}>
|
||||
export const AuthModal = ({ children }: AuthModalProps) => (
|
||||
<UIModal isOpen={true}>
|
||||
<StyledContent>{children}</StyledContent>
|
||||
</UIModal>
|
||||
);
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import styled from '@emotion/styled';
|
||||
|
||||
type FooterNoteProps = React.ComponentProps<'div'>;
|
||||
type FooterNoteProps = { children: React.ReactNode };
|
||||
|
||||
const StyledContainer = styled.div`
|
||||
align-items: center;
|
||||
@ -11,7 +11,6 @@ const StyledContainer = styled.div`
|
||||
text-align: center;
|
||||
`;
|
||||
|
||||
export const FooterNote = (props: FooterNoteProps) => (
|
||||
// eslint-disable-next-line twenty/no-spread-props
|
||||
<StyledContainer {...props} />
|
||||
export const FooterNote = ({ children }: FooterNoteProps) => (
|
||||
<StyledContainer>{children}</StyledContainer>
|
||||
);
|
||||
|
@ -99,7 +99,7 @@ export const CompanyProgressPicker = ({
|
||||
) : (
|
||||
<>
|
||||
<DropdownMenuHeader
|
||||
data-testid="selected-pipeline-stage"
|
||||
testId="selected-pipeline-stage"
|
||||
EndIcon={IconChevronDown}
|
||||
onClick={() => setIsProgressSelectionUnfolded(true)}
|
||||
>
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import styled from '@emotion/styled';
|
||||
|
||||
export type HeadingProps = React.ComponentProps<'div'> & {
|
||||
export type HeadingProps = {
|
||||
title: string;
|
||||
description?: string;
|
||||
};
|
||||
@ -27,9 +27,8 @@ const StyledDescription = styled.span`
|
||||
text-align: center;
|
||||
`;
|
||||
|
||||
export const Heading = ({ title, description, ...props }: HeadingProps) => (
|
||||
// eslint-disable-next-line twenty/no-spread-props
|
||||
<StyledContainer {...props}>
|
||||
export const Heading = ({ title, description }: HeadingProps) => (
|
||||
<StyledContainer>
|
||||
<StyledTitle>{title}</StyledTitle>
|
||||
{description && <StyledDescription>{description}</StyledDescription>}
|
||||
</StyledContainer>
|
||||
|
@ -111,11 +111,36 @@ type TableProps<Data> = DataGridProps<Data> & {
|
||||
hiddenHeader?: boolean;
|
||||
};
|
||||
|
||||
export const Table = <Data,>(props: TableProps<Data>) => {
|
||||
export const Table = <Data,>({
|
||||
className,
|
||||
columns,
|
||||
components,
|
||||
headerRowHeight,
|
||||
rowKeyGetter,
|
||||
rows,
|
||||
onRowClick,
|
||||
onRowsChange,
|
||||
onSelectedRowsChange,
|
||||
selectedRows,
|
||||
}: TableProps<Data>) => {
|
||||
const { rtl } = useSpreadsheetImportInternal();
|
||||
|
||||
return (
|
||||
// eslint-disable-next-line twenty/no-spread-props
|
||||
<StyledDataGrid direction={rtl ? 'rtl' : 'ltr'} rowHeight={52} {...props} />
|
||||
<StyledDataGrid
|
||||
direction={rtl ? 'rtl' : 'ltr'}
|
||||
rowHeight={52}
|
||||
{...{
|
||||
className,
|
||||
columns,
|
||||
components,
|
||||
headerRowHeight,
|
||||
rowKeyGetter,
|
||||
rows,
|
||||
onRowClick,
|
||||
onRowsChange,
|
||||
onSelectedRowsChange,
|
||||
selectedRows,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
@ -103,12 +103,13 @@ export const MainButton = ({
|
||||
title,
|
||||
fullWidth = false,
|
||||
variant = 'primary',
|
||||
...props
|
||||
type,
|
||||
onClick,
|
||||
disabled,
|
||||
}: MainButtonProps) => {
|
||||
const theme = useTheme();
|
||||
return (
|
||||
// eslint-disable-next-line twenty/no-spread-props
|
||||
<StyledButton fullWidth={fullWidth} variant={variant} {...props}>
|
||||
<StyledButton {...{ disabled, fullWidth, onClick, type, variant }}>
|
||||
{Icon && <Icon size={theme.icon.size.sm} />}
|
||||
{title}
|
||||
</StyledButton>
|
||||
|
@ -35,13 +35,13 @@ type RoundedIconButtonProps = {
|
||||
|
||||
export const RoundedIconButton = ({
|
||||
Icon,
|
||||
...props
|
||||
onClick,
|
||||
disabled,
|
||||
}: RoundedIconButtonProps) => {
|
||||
const theme = useTheme();
|
||||
|
||||
return (
|
||||
// eslint-disable-next-line twenty/no-spread-props
|
||||
<StyledIconButton {...props}>
|
||||
<StyledIconButton {...{ disabled, onClick }}>
|
||||
{<Icon size={theme.icon.size.md} />}
|
||||
</StyledIconButton>
|
||||
);
|
||||
|
@ -15,7 +15,6 @@ export const AnimatedCheckmark = ({
|
||||
color,
|
||||
duration = 0.5,
|
||||
size = 28,
|
||||
...restProps
|
||||
}: AnimatedCheckmarkProps) => {
|
||||
const theme = useTheme();
|
||||
return (
|
||||
@ -26,8 +25,6 @@ export const AnimatedCheckmark = ({
|
||||
height={size}
|
||||
>
|
||||
<motion.path
|
||||
// eslint-disable-next-line twenty/no-spread-props
|
||||
{...restProps}
|
||||
fill="none"
|
||||
stroke={color ?? theme.grayScale.gray0}
|
||||
strokeWidth={4}
|
||||
|
@ -16,12 +16,11 @@ const StyledContainer = styled.div`
|
||||
|
||||
export type CheckmarkProps = React.ComponentPropsWithoutRef<'div'>;
|
||||
|
||||
export const Checkmark = (props: CheckmarkProps) => {
|
||||
export const Checkmark = (_props: CheckmarkProps) => {
|
||||
const theme = useTheme();
|
||||
|
||||
return (
|
||||
// eslint-disable-next-line twenty/no-spread-props
|
||||
<StyledContainer {...props}>
|
||||
<StyledContainer>
|
||||
<IconCheck color={theme.grayScale.gray0} size={14} />
|
||||
</StyledContainer>
|
||||
);
|
||||
|
@ -103,10 +103,14 @@ export type ColorSchemeSegmentProps = {
|
||||
const ColorSchemeSegment = ({
|
||||
variant,
|
||||
controls,
|
||||
...rest
|
||||
style,
|
||||
onClick,
|
||||
onMouseEnter,
|
||||
onMouseLeave,
|
||||
}: ColorSchemeSegmentProps) => (
|
||||
// eslint-disable-next-line twenty/no-spread-props
|
||||
<StyledColorSchemeBackground variant={variant} {...rest}>
|
||||
<StyledColorSchemeBackground
|
||||
{...{ variant, style, onClick, onMouseEnter, onMouseLeave }}
|
||||
>
|
||||
<StyledColorSchemeContent animate={controls} variant={variant}>
|
||||
Aa
|
||||
</StyledColorSchemeContent>
|
||||
@ -148,7 +152,7 @@ const checkmarkAnimationVariants = {
|
||||
export const ColorSchemeCard = ({
|
||||
variant,
|
||||
selected,
|
||||
...rest
|
||||
onClick,
|
||||
}: ColorSchemeCardProps) => {
|
||||
const controls = useAnimation();
|
||||
|
||||
@ -174,8 +178,7 @@ export const ColorSchemeCard = ({
|
||||
<StyledMixedColorSchemeSegment
|
||||
onMouseEnter={handleMouseEnter}
|
||||
onMouseLeave={handleMouseLeave}
|
||||
// eslint-disable-next-line twenty/no-spread-props
|
||||
{...rest}
|
||||
onClick={onClick}
|
||||
>
|
||||
<ColorSchemeSegment
|
||||
style={{ borderTopRightRadius: 0, borderBottomRightRadius: 0 }}
|
||||
@ -213,8 +216,7 @@ export const ColorSchemeCard = ({
|
||||
onMouseLeave={handleMouseLeave}
|
||||
controls={controls}
|
||||
variant={variant}
|
||||
// eslint-disable-next-line twenty/no-spread-props
|
||||
{...rest}
|
||||
onClick={onClick}
|
||||
/>
|
||||
<AnimatePresence>
|
||||
{selected && (
|
||||
|
@ -26,7 +26,6 @@ type DataTableHeaderPlusButtonProps = {
|
||||
export const DataTableHeaderPlusButton = ({
|
||||
onAddColumn,
|
||||
onClickOutside = () => undefined,
|
||||
...props
|
||||
}: DataTableHeaderPlusButtonProps) => {
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
|
||||
@ -51,8 +50,7 @@ export const DataTableHeaderPlusButton = ({
|
||||
);
|
||||
|
||||
return (
|
||||
// eslint-disable-next-line twenty/no-spread-props
|
||||
<StyledHeaderPlusButton {...props} ref={ref}>
|
||||
<StyledHeaderPlusButton ref={ref}>
|
||||
<DropdownMenuItemsContainer>
|
||||
{hiddenTableColumns.map((column) => (
|
||||
<MenuItem
|
||||
|
@ -79,7 +79,7 @@ export const Dialog = ({
|
||||
allowDismiss = true,
|
||||
children,
|
||||
onClose,
|
||||
...rootProps
|
||||
id,
|
||||
}: DialogProps) => {
|
||||
const closeSnackbar = useCallback(() => {
|
||||
onClose && onClose();
|
||||
@ -137,23 +137,20 @@ export const Dialog = ({
|
||||
<StyledDialogContainer
|
||||
variants={containerVariants}
|
||||
transition={{ damping: 15, stiffness: 100 }}
|
||||
// eslint-disable-next-line twenty/no-spread-props
|
||||
{...rootProps}
|
||||
id={id}
|
||||
>
|
||||
{title && <StyledDialogTitle>{title}</StyledDialogTitle>}
|
||||
{message && <StyledDialogMessage>{message}</StyledDialogMessage>}
|
||||
{children}
|
||||
{buttons.map((button) => (
|
||||
{buttons.map(({ accent, onClick, role, title: key, variant }) => (
|
||||
<StyledDialogButton
|
||||
key={button.title}
|
||||
onClick={(event) => {
|
||||
button?.onClick?.(event);
|
||||
onClick?.(event);
|
||||
closeSnackbar();
|
||||
}}
|
||||
fullWidth={true}
|
||||
variant={button.variant ?? 'secondary'}
|
||||
// eslint-disable-next-line twenty/no-spread-props
|
||||
{...button}
|
||||
variant={variant ?? 'secondary'}
|
||||
{...{ accent, key, role }}
|
||||
/>
|
||||
))}
|
||||
</StyledDialogContainer>
|
||||
|
@ -37,12 +37,11 @@ export const DialogProvider = ({ children }: React.PropsWithChildren) => {
|
||||
return (
|
||||
<>
|
||||
{children}
|
||||
{dialogInternal.queue.map((dialog) => (
|
||||
{dialogInternal.queue.map(({ buttons, children, id, message, title }) => (
|
||||
<Dialog
|
||||
key={dialog.id}
|
||||
// eslint-disable-next-line twenty/no-spread-props
|
||||
{...dialog}
|
||||
onClose={() => handleDialogClose(dialog.id)}
|
||||
key={id}
|
||||
{...{ title, message, buttons, id, children }}
|
||||
onClose={() => handleDialogClose(id)}
|
||||
/>
|
||||
))}
|
||||
</>
|
||||
|
@ -27,7 +27,6 @@ export const DropdownMenuContainer = ({
|
||||
children,
|
||||
onClose,
|
||||
width,
|
||||
...props
|
||||
}: DropdownMenuContainerProps) => {
|
||||
const dropdownRef = useRef(null);
|
||||
|
||||
@ -39,8 +38,7 @@ export const DropdownMenuContainer = ({
|
||||
});
|
||||
|
||||
return (
|
||||
// eslint-disable-next-line twenty/no-spread-props
|
||||
<StyledDropdownMenuContainer data-select-disable {...props} anchor={anchor}>
|
||||
<StyledDropdownMenuContainer data-select-disable anchor={anchor}>
|
||||
<StyledDropdownMenu ref={dropdownRef} width={width}>
|
||||
{children}
|
||||
</StyledDropdownMenu>
|
||||
|
@ -30,6 +30,7 @@ type DropdownMenuHeaderProps = ComponentProps<'li'> & {
|
||||
StartIcon?: IconComponent;
|
||||
EndIcon?: IconComponent;
|
||||
onClick?: (event: MouseEvent<HTMLButtonElement>) => void;
|
||||
testId?: string;
|
||||
};
|
||||
|
||||
export const DropdownMenuHeader = ({
|
||||
@ -37,14 +38,13 @@ export const DropdownMenuHeader = ({
|
||||
StartIcon,
|
||||
EndIcon,
|
||||
onClick,
|
||||
...props
|
||||
testId,
|
||||
}: DropdownMenuHeaderProps) => {
|
||||
return (
|
||||
// eslint-disable-next-line twenty/no-spread-props
|
||||
<StyledHeader {...props}>
|
||||
<StyledHeader data-testid={testId}>
|
||||
{StartIcon && (
|
||||
<LightIconButton
|
||||
data-testid="dropdown-menu-header-end-icon"
|
||||
testId="dropdown-menu-header-end-icon"
|
||||
Icon={StartIcon}
|
||||
onClick={onClick}
|
||||
accent="tertiary"
|
||||
|
@ -36,9 +36,12 @@ const StyledInput = styled.input`
|
||||
export const DropdownMenuSearchInput = forwardRef<
|
||||
HTMLInputElement,
|
||||
InputHTMLAttributes<HTMLInputElement>
|
||||
>((props, ref) => (
|
||||
>(({ value, onChange, autoFocus, placeholder = 'Search', type }, ref) => (
|
||||
<StyledDropdownMenuSearchInputContainer>
|
||||
{/* eslint-disable-next-line twenty/no-spread-props */}
|
||||
<StyledInput autoComplete="off" placeholder="Search" {...props} ref={ref} />
|
||||
<StyledInput
|
||||
autoComplete="off"
|
||||
{...{ autoFocus, onChange, placeholder, type, value }}
|
||||
ref={ref}
|
||||
/>
|
||||
</StyledDropdownMenuSearchInputContainer>
|
||||
));
|
||||
|
@ -118,7 +118,6 @@ export const Radio = ({
|
||||
size = RadioSize.Small,
|
||||
labelPosition = LabelPosition.Right,
|
||||
disabled = false,
|
||||
...restProps
|
||||
}: RadioProps) => {
|
||||
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
onChange?.(event);
|
||||
@ -126,8 +125,7 @@ export const Radio = ({
|
||||
};
|
||||
|
||||
return (
|
||||
// eslint-disable-next-line twenty/no-spread-props
|
||||
<StyledContainer {...restProps} labelPosition={labelPosition}>
|
||||
<StyledContainer labelPosition={labelPosition}>
|
||||
<StyledRadioInput
|
||||
type="radio"
|
||||
id="input-radio"
|
||||
|
@ -95,7 +95,6 @@ export const ImageInput = ({
|
||||
isUploading = false,
|
||||
errorMessage,
|
||||
disabled = false,
|
||||
...restProps
|
||||
}: ImageInputProps) => {
|
||||
const theme = useTheme();
|
||||
const hiddenFileInput = React.useRef<HTMLInputElement>(null);
|
||||
@ -104,8 +103,7 @@ export const ImageInput = ({
|
||||
};
|
||||
|
||||
return (
|
||||
// eslint-disable-next-line twenty/no-spread-props
|
||||
<StyledContainer {...restProps}>
|
||||
<StyledContainer>
|
||||
<StyledPicture
|
||||
withPicture={!!picture}
|
||||
disabled={disabled}
|
||||
|
@ -34,11 +34,16 @@ export type SingleEntitySelectProps<
|
||||
export const SingleEntitySelect = <
|
||||
CustomEntityForSelect extends EntityForSelect,
|
||||
>({
|
||||
EmptyIcon,
|
||||
disableBackgroundBlur = false,
|
||||
emptyLabel,
|
||||
entitiesToSelect,
|
||||
loading,
|
||||
onCancel,
|
||||
onCreate,
|
||||
onEntitySelected,
|
||||
selectedEntity,
|
||||
width,
|
||||
...props
|
||||
}: SingleEntitySelectProps<CustomEntityForSelect>) => {
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
@ -69,11 +74,17 @@ export const SingleEntitySelect = <
|
||||
/>
|
||||
<StyledDropdownMenuSeparator />
|
||||
<SingleEntitySelectBase
|
||||
// eslint-disable-next-line twenty/no-spread-props
|
||||
{...props}
|
||||
onCancel={onCancel}
|
||||
onCreate={onCreate}
|
||||
showCreateButton={showCreateButton}
|
||||
{...{
|
||||
EmptyIcon,
|
||||
emptyLabel,
|
||||
entitiesToSelect,
|
||||
loading,
|
||||
onCancel,
|
||||
onCreate,
|
||||
onEntitySelected,
|
||||
selectedEntity,
|
||||
showCreateButton,
|
||||
}}
|
||||
/>
|
||||
</StyledDropdownMenu>
|
||||
);
|
||||
|
@ -34,7 +34,17 @@ const meta: Meta<typeof SingleEntitySelect> = {
|
||||
),
|
||||
},
|
||||
},
|
||||
render: (args) => {
|
||||
render: ({
|
||||
EmptyIcon,
|
||||
disableBackgroundBlur = false,
|
||||
emptyLabel,
|
||||
loading,
|
||||
onCancel,
|
||||
onCreate,
|
||||
onEntitySelected,
|
||||
selectedEntity,
|
||||
width,
|
||||
}) => {
|
||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
const relationPickerSearchFilter = useRecoilScopedValue(
|
||||
relationPickerSearchFilterScopedState,
|
||||
@ -42,11 +52,20 @@ const meta: Meta<typeof SingleEntitySelect> = {
|
||||
|
||||
return (
|
||||
<SingleEntitySelect
|
||||
// eslint-disable-next-line twenty/no-spread-props
|
||||
{...args}
|
||||
{...{
|
||||
EmptyIcon,
|
||||
disableBackgroundBlur,
|
||||
emptyLabel,
|
||||
loading,
|
||||
onCancel,
|
||||
onCreate,
|
||||
onEntitySelected,
|
||||
selectedEntity,
|
||||
width,
|
||||
}}
|
||||
entitiesToSelect={entities.filter(
|
||||
(entity) =>
|
||||
entity.id !== args.selectedEntity?.id &&
|
||||
entity.id !== selectedEntity?.id &&
|
||||
entity.name.includes(relationPickerSearchFilter),
|
||||
)}
|
||||
/>
|
||||
|
@ -113,7 +113,10 @@ const TextInputComponent = (
|
||||
required,
|
||||
type,
|
||||
disableHotkeys = false,
|
||||
...props
|
||||
autoFocus,
|
||||
placeholder,
|
||||
disabled,
|
||||
tabIndex,
|
||||
}: TextInputComponentProps,
|
||||
// eslint-disable-next-line twenty/component-props-naming
|
||||
ref: ForwardedRef<HTMLInputElement>,
|
||||
@ -163,19 +166,14 @@ const TextInputComponent = (
|
||||
<StyledInput
|
||||
autoComplete="off"
|
||||
ref={combinedRef}
|
||||
tabIndex={props.tabIndex ?? 0}
|
||||
tabIndex={tabIndex ?? 0}
|
||||
onFocus={handleFocus}
|
||||
onBlur={handleBlur}
|
||||
value={value}
|
||||
required={required}
|
||||
type={passwordVisible ? 'text' : type}
|
||||
onChange={(event: ChangeEvent<HTMLInputElement>) => {
|
||||
if (onChange) {
|
||||
onChange(event.target.value);
|
||||
}
|
||||
onChange?.(event.target.value);
|
||||
}}
|
||||
// eslint-disable-next-line twenty/no-spread-props
|
||||
{...props}
|
||||
{...{ autoFocus, disabled, placeholder, required, value }}
|
||||
/>
|
||||
<StyledTrailingIconContainer>
|
||||
{error && (
|
||||
|
@ -21,15 +21,38 @@ export default meta;
|
||||
type Story = StoryObj<typeof TextInputSettings>;
|
||||
|
||||
const FakeTextInput = ({
|
||||
autoFocus,
|
||||
disableHotkeys = false,
|
||||
disabled,
|
||||
error,
|
||||
fullWidth,
|
||||
label,
|
||||
onBlur,
|
||||
onChange,
|
||||
onFocus,
|
||||
placeholder,
|
||||
required,
|
||||
tabIndex,
|
||||
type,
|
||||
value: initialValue,
|
||||
...props
|
||||
}: React.ComponentProps<typeof TextInputSettings>) => {
|
||||
const [value, setValue] = useState(initialValue);
|
||||
return (
|
||||
<TextInputSettings
|
||||
// eslint-disable-next-line twenty/no-spread-props
|
||||
{...props}
|
||||
{...{
|
||||
autoFocus,
|
||||
disableHotkeys,
|
||||
disabled,
|
||||
error,
|
||||
fullWidth,
|
||||
label,
|
||||
onBlur,
|
||||
onFocus,
|
||||
placeholder,
|
||||
required,
|
||||
tabIndex,
|
||||
type,
|
||||
}}
|
||||
value={value}
|
||||
onChange={(text) => {
|
||||
setValue(text);
|
||||
@ -42,8 +65,41 @@ const FakeTextInput = ({
|
||||
export const Default: Story = {
|
||||
argTypes: { value: { control: false } },
|
||||
args: { value: 'A good value ' },
|
||||
// eslint-disable-next-line twenty/no-spread-props
|
||||
render: (args) => <FakeTextInput {...args} />,
|
||||
render: ({
|
||||
autoFocus,
|
||||
disableHotkeys,
|
||||
disabled,
|
||||
error,
|
||||
fullWidth,
|
||||
label,
|
||||
onBlur,
|
||||
onChange,
|
||||
onFocus,
|
||||
placeholder,
|
||||
required,
|
||||
tabIndex,
|
||||
type,
|
||||
value,
|
||||
}) => (
|
||||
<FakeTextInput
|
||||
{...{
|
||||
autoFocus,
|
||||
disableHotkeys,
|
||||
disabled,
|
||||
error,
|
||||
fullWidth,
|
||||
label,
|
||||
onBlur,
|
||||
onChange,
|
||||
onFocus,
|
||||
placeholder,
|
||||
required,
|
||||
tabIndex,
|
||||
type,
|
||||
value,
|
||||
}}
|
||||
/>
|
||||
),
|
||||
play: async ({ canvasElement }) => {
|
||||
const canvas = within(canvasElement);
|
||||
|
||||
|
@ -81,7 +81,6 @@ export const PageHeader = ({
|
||||
hasBackButton,
|
||||
Icon,
|
||||
children,
|
||||
...props
|
||||
}: PageHeaderProps) => {
|
||||
const navigate = useNavigate();
|
||||
const navigateBack = useCallback(() => navigate(-1), [navigate]);
|
||||
@ -92,8 +91,7 @@ export const PageHeader = ({
|
||||
const theme = useTheme();
|
||||
|
||||
return (
|
||||
// eslint-disable-next-line twenty/no-spread-props
|
||||
<StyledTopBarContainer {...props}>
|
||||
<StyledTopBarContainer>
|
||||
<StyledLeftContainer>
|
||||
{!isNavbarOpened && (
|
||||
<StyledTopBarButtonContainer>
|
||||
|
@ -98,23 +98,20 @@ const StyledBackDrop = styled(motion.div)`
|
||||
*/
|
||||
type ModalHeaderProps = React.PropsWithChildren & React.ComponentProps<'div'>;
|
||||
|
||||
const ModalHeader = ({ children, ...restProps }: ModalHeaderProps) => (
|
||||
// eslint-disable-next-line twenty/no-spread-props
|
||||
<StyledHeader {...restProps}>{children}</StyledHeader>
|
||||
const ModalHeader = ({ children }: ModalHeaderProps) => (
|
||||
<StyledHeader>{children}</StyledHeader>
|
||||
);
|
||||
|
||||
type ModalContentProps = React.PropsWithChildren & React.ComponentProps<'div'>;
|
||||
|
||||
const ModalContent = ({ children, ...restProps }: ModalContentProps) => (
|
||||
// eslint-disable-next-line twenty/no-spread-props
|
||||
<StyledContent {...restProps}>{children}</StyledContent>
|
||||
const ModalContent = ({ children }: ModalContentProps) => (
|
||||
<StyledContent>{children}</StyledContent>
|
||||
);
|
||||
|
||||
type ModalFooterProps = React.PropsWithChildren & React.ComponentProps<'div'>;
|
||||
|
||||
const ModalFooter = ({ children, ...restProps }: ModalFooterProps) => (
|
||||
// eslint-disable-next-line twenty/no-spread-props
|
||||
<StyledFooter {...restProps}>{children}</StyledFooter>
|
||||
const ModalFooter = ({ children }: ModalFooterProps) => (
|
||||
<StyledFooter>{children}</StyledFooter>
|
||||
);
|
||||
|
||||
/**
|
||||
@ -147,7 +144,6 @@ export const Modal = ({
|
||||
onEnter,
|
||||
size = 'medium',
|
||||
padding = 'medium',
|
||||
...restProps
|
||||
}: ModalProps) => {
|
||||
const modalRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
@ -206,8 +202,6 @@ export const Modal = ({
|
||||
exit="exit"
|
||||
layout
|
||||
variants={modalVariants}
|
||||
// eslint-disable-next-line twenty/no-spread-props
|
||||
{...restProps}
|
||||
>
|
||||
{children}
|
||||
</StyledModalDiv>
|
||||
|
@ -111,7 +111,8 @@ export const SnackBar = ({
|
||||
variant = 'info',
|
||||
children,
|
||||
onClose,
|
||||
...rootProps
|
||||
id,
|
||||
title,
|
||||
}: SnackBarProps) => {
|
||||
const theme = useTheme();
|
||||
|
||||
@ -156,12 +157,7 @@ export const SnackBar = ({
|
||||
return (
|
||||
<StyledMotionContainer
|
||||
aria-live={role === 'alert' ? 'assertive' : 'polite'}
|
||||
role={role}
|
||||
onMouseEnter={onMouseEnter}
|
||||
onMouseLeave={onMouseLeave}
|
||||
variant={variant}
|
||||
// eslint-disable-next-line twenty/no-spread-props
|
||||
{...rootProps}
|
||||
{...{ id, onMouseEnter, onMouseLeave, role, title, variant }}
|
||||
>
|
||||
<StyledProgressBarContainer>
|
||||
<ProgressBar
|
||||
|
@ -69,23 +69,24 @@ export const SnackBarProvider = ({ children }: React.PropsWithChildren) => {
|
||||
<>
|
||||
{children}
|
||||
<StyledSnackBarContainer>
|
||||
{snackBarInternal.queue.map((snackBar) => (
|
||||
<StyledSnackBarMotionContainer
|
||||
key={snackBar.id}
|
||||
variants={reducedMotion ? reducedVariants : variants}
|
||||
initial="initial"
|
||||
animate="animate"
|
||||
exit="exit"
|
||||
transition={{ duration: 0.5 }}
|
||||
layout
|
||||
>
|
||||
<SnackBar
|
||||
// eslint-disable-next-line twenty/no-spread-props
|
||||
{...snackBar}
|
||||
onClose={() => handleSnackBarClose(snackBar.id)}
|
||||
/>
|
||||
</StyledSnackBarMotionContainer>
|
||||
))}
|
||||
{snackBarInternal.queue.map(
|
||||
({ duration, icon, id, message, title, variant }) => (
|
||||
<StyledSnackBarMotionContainer
|
||||
key={id}
|
||||
variants={reducedMotion ? reducedVariants : variants}
|
||||
initial="initial"
|
||||
animate="animate"
|
||||
exit="exit"
|
||||
transition={{ duration: 0.5 }}
|
||||
layout
|
||||
>
|
||||
<SnackBar
|
||||
{...{ duration, icon, message, title, variant }}
|
||||
onClose={() => handleSnackBarClose(id)}
|
||||
/>
|
||||
</StyledSnackBarMotionContainer>
|
||||
),
|
||||
)}
|
||||
</StyledSnackBarContainer>
|
||||
</>
|
||||
);
|
||||
|
@ -21,16 +21,11 @@ export type StepBarProps = React.PropsWithChildren &
|
||||
activeStep: number;
|
||||
};
|
||||
|
||||
export const StepBar = ({
|
||||
children,
|
||||
activeStep,
|
||||
...restProps
|
||||
}: StepBarProps) => {
|
||||
export const StepBar = ({ activeStep, children }: StepBarProps) => {
|
||||
const isMobile = useIsMobile();
|
||||
|
||||
return (
|
||||
// eslint-disable-next-line twenty/no-spread-props
|
||||
<StyledContainer {...restProps}>
|
||||
<StyledContainer>
|
||||
{React.Children.map(children, (child, index) => {
|
||||
if (!React.isValidElement(child)) {
|
||||
return null;
|
||||
|
@ -43,7 +43,28 @@ export type AppTooltipProps = {
|
||||
positionStrategy?: PositionStrategy;
|
||||
};
|
||||
|
||||
export const AppTooltip = (props: AppTooltipProps) => (
|
||||
// eslint-disable-next-line twenty/no-spread-props
|
||||
<StyledAppTooltip {...props} />
|
||||
export const AppTooltip = ({
|
||||
anchorSelect,
|
||||
className,
|
||||
content,
|
||||
delayHide,
|
||||
isOpen,
|
||||
noArrow,
|
||||
offset,
|
||||
place,
|
||||
positionStrategy,
|
||||
}: AppTooltipProps) => (
|
||||
<StyledAppTooltip
|
||||
{...{
|
||||
anchorSelect,
|
||||
className,
|
||||
content,
|
||||
delayHide,
|
||||
isOpen,
|
||||
noArrow,
|
||||
offset,
|
||||
place,
|
||||
positionStrategy,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
@ -22,13 +22,34 @@ export const Default: Story = {
|
||||
anchorSelect: '#hover-text',
|
||||
},
|
||||
decorators: [ComponentDecorator],
|
||||
render: (args) => (
|
||||
render: ({
|
||||
anchorSelect,
|
||||
className,
|
||||
content,
|
||||
delayHide,
|
||||
isOpen,
|
||||
noArrow,
|
||||
offset,
|
||||
place,
|
||||
positionStrategy,
|
||||
}) => (
|
||||
<>
|
||||
<p id="hover-text" data-testid="tooltip">
|
||||
Hover me!
|
||||
</p>
|
||||
{/* eslint-disable-next-line twenty/no-spread-props */}
|
||||
<Tooltip {...args} />
|
||||
<Tooltip
|
||||
{...{
|
||||
anchorSelect,
|
||||
className,
|
||||
content,
|
||||
delayHide,
|
||||
isOpen,
|
||||
noArrow,
|
||||
offset,
|
||||
place,
|
||||
positionStrategy,
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
),
|
||||
};
|
||||
|
@ -10,20 +10,13 @@ type AnimatedEaseInProps = Omit<
|
||||
export const AnimatedEaseIn = ({
|
||||
children,
|
||||
duration = 0.3,
|
||||
...restProps
|
||||
}: AnimatedEaseInProps) => {
|
||||
const initial = { opacity: 0 };
|
||||
const animate = { opacity: 1 };
|
||||
const transition = { ease: 'linear', duration };
|
||||
|
||||
return (
|
||||
<motion.div
|
||||
initial={initial}
|
||||
animate={animate}
|
||||
transition={transition}
|
||||
// eslint-disable-next-line twenty/no-spread-props
|
||||
{...restProps}
|
||||
>
|
||||
<motion.div initial={initial} animate={animate} transition={transition}>
|
||||
{children}
|
||||
</motion.div>
|
||||
);
|
||||
|
@ -47,10 +47,7 @@ const childAnimation = {
|
||||
},
|
||||
};
|
||||
|
||||
export const AnimatedTextWord = ({
|
||||
text = '',
|
||||
...restProps
|
||||
}: AnimatedTextWordProps) => {
|
||||
export const AnimatedTextWord = ({ text = '' }: AnimatedTextWordProps) => {
|
||||
const words = useMemo(() => {
|
||||
const words = text.split(' ');
|
||||
|
||||
@ -64,8 +61,6 @@ export const AnimatedTextWord = ({
|
||||
variants={containerAnimation}
|
||||
initial="hidden"
|
||||
animate="visible"
|
||||
// eslint-disable-next-line twenty/no-spread-props
|
||||
{...restProps}
|
||||
>
|
||||
{words.map((word, index) => (
|
||||
<StyledWord variants={childAnimation} key={index}>
|
||||
|
Loading…
Reference in New Issue
Block a user