chore: improve eslint rules (#26056)

## Description
Make eslint rules stricter for packages

#### Type of change
- Chore (housekeeping or task changes that don't impact user perception)

## Testing
>
#### How Has This Been Tested?
> Please describe the tests that you ran to verify your changes. Also
list any relevant details for your test configuration.
> Delete anything that is not relevant
- [x] Manual
- [x] Jest
- [ ] Cypress

## Checklist:
#### Dev activity
- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my own code
- [ ] I have commented my code, particularly in hard-to-understand areas
- [ ] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [ ] I have added tests that prove my fix is effective or that my
feature works
- [x] New and existing unit tests pass locally with my changes
- [ ] PR is being merged under a feature flag

Co-authored-by: Valera Melnikov <melnikov.vv@greendatasoft.ru>
This commit is contained in:
Valera Melnikov 2023-08-07 15:38:48 +03:00 committed by GitHub
parent 56602436b7
commit abff60b6a2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
42 changed files with 438 additions and 390 deletions

View File

@ -28,16 +28,7 @@
}
},
"rules": {
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-use-before-define": "off",
"@typescript-eslint/no-var-requires": "off",
"import/no-webpack-loader-syntax": "off",
"no-undef": "off",
"react/prop-types": "off",
"react/display-name": "off",
"@typescript-eslint/explicit-module-boundary-types": "off",
"cypress/no-unnecessary-waiting": "off",
"cypress/no-assigning-return-values": "off",
"@typescript-eslint/no-explicit-any": "error",
"@typescript-eslint/no-unused-vars": "error",
"jest/no-focused-tests": "error",
"jest/no-disabled-tests": "error",

View File

@ -13,6 +13,9 @@ const baseNoRestrictedImports =
const eslintConfig = {
extends: ["./.eslintrc.base.json"],
rules: {
"@typescript-eslint/no-explicit-any": "off",
"react/display-name": "off",
"react/prop-types": "off",
// `no-restricted-imports` is disabled, as recommended in https://typescript-eslint.io/rules/no-restricted-imports/.
// Please use @typescript-eslint/no-restricted-imports below instead.
"no-restricted-imports": "off",

View File

@ -13,6 +13,8 @@
"@typescript-eslint/no-non-null-assertion": "error",
"cypress/unsafe-to-chain-command": "off",
"@typescript-eslint/adjacent-overload-signatures": "off",
"jest/no-disabled-tests": "off"
"jest/no-disabled-tests": "off",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-var-requires": "off"
}
}

View File

@ -1,4 +1,7 @@
{
"extends": ["../../.eslintrc.base.json"],
"ignorePatterns": ["build"]
"ignorePatterns": ["build"],
"rules": {
"@typescript-eslint/no-explicit-any": "off"
}
}

View File

@ -2,8 +2,7 @@ import peerDepsExternal from "rollup-plugin-peer-deps-external";
import commonjs from "@rollup/plugin-commonjs";
import typescript from "rollup-plugin-typescript2";
import generatePackageJson from "rollup-plugin-generate-package-json";
const packageJson = require("./package.json");
import packageJson from "./package.json";
export default {
// TODO: Figure out regex where each directory can be a separate module without having to manually add them

View File

@ -19,7 +19,7 @@ export interface ButtonProps extends SpectrumAriaBaseButtonProps {
export type ButtonRef = React.Ref<HTMLButtonElement>;
type ButtonRefObject = React.RefObject<HTMLButtonElement>;
export const Button = forwardRef((props: ButtonProps, ref: ButtonRef) => {
const _Button = (props: ButtonProps, ref: ButtonRef) => {
const { autoFocus, children, className, draggable, isDisabled } = props;
const { hoverProps, isHovered } = useHover({ isDisabled });
const { focusProps, isFocusVisible } = useFocusRing({ autoFocus });
@ -41,4 +41,6 @@ export const Button = forwardRef((props: ButtonProps, ref: ButtonRef) => {
{children}
</button>
);
});
};
export const Button = forwardRef(_Button);

View File

@ -29,7 +29,7 @@ export type CheckboxRef = FocusableRef<HTMLLabelElement>;
const ICON_SIZE = 14;
export const Checkbox = forwardRef((props: CheckboxProps, ref: CheckboxRef) => {
const _Checkbox = (props: CheckboxProps, ref: CheckboxRef) => {
const {
autoFocus,
children,
@ -100,4 +100,6 @@ export const Checkbox = forwardRef((props: CheckboxProps, ref: CheckboxRef) => {
{children}
</label>
);
});
};
export const Checkbox = forwardRef(_Checkbox);

View File

@ -18,40 +18,40 @@ export interface CheckboxGroupProps
labelWidth?: LabelProps["labelWidth"];
}
export const CheckboxGroup = forwardRef(
(props: CheckboxGroupProps, ref: CheckboxGroupRef) => {
const { children, className, isDisabled, orientation = "vertical" } = props;
const domRef = useDOMRef(ref);
const state = useCheckboxGroupState(props);
const { descriptionProps, errorMessageProps, groupProps, labelProps } =
useCheckboxGroup(props, state);
const _CheckboxGroup = (props: CheckboxGroupProps, ref: CheckboxGroupRef) => {
const { children, className, isDisabled, orientation = "vertical" } = props;
const domRef = useDOMRef(ref);
const state = useCheckboxGroupState(props);
const { descriptionProps, errorMessageProps, groupProps, labelProps } =
useCheckboxGroup(props, state);
return (
<Field
{...props}
descriptionProps={descriptionProps}
errorMessageProps={errorMessageProps}
includeNecessityIndicatorInAccessibilityName
labelProps={labelProps}
ref={domRef}
wrapperClassName={className}
return (
<Field
{...props}
descriptionProps={descriptionProps}
errorMessageProps={errorMessageProps}
includeNecessityIndicatorInAccessibilityName
labelProps={labelProps}
ref={domRef}
wrapperClassName={className}
>
<div
{...groupProps}
data-disabled={props.isDisabled ? "" : undefined}
data-field-group=""
data-orientation={orientation}
>
<div
{...groupProps}
data-disabled={props.isDisabled ? "" : undefined}
data-field-group=""
data-orientation={orientation}
<CheckboxGroupContext.Provider
value={{
state,
isDisabled,
}}
>
<CheckboxGroupContext.Provider
value={{
state,
isDisabled,
}}
>
{children}
</CheckboxGroupContext.Provider>
</div>
</Field>
);
},
);
{children}
</CheckboxGroupContext.Provider>
</div>
</Field>
);
};
export const CheckboxGroup = forwardRef(_CheckboxGroup);

View File

@ -9,18 +9,18 @@ interface HelpTextProps extends SpectrumHelpTextProps {
errorMessageProps?: HTMLAttributes<HTMLElement>;
}
export const ErrorText = forwardRef(
(props: HelpTextProps, ref: DOMRef<HTMLDivElement>) => {
const { errorMessage, errorMessageProps, showErrorIcon } = props;
const domRef = useDOMRef(ref);
const _ErrorText = (props: HelpTextProps, ref: DOMRef<HTMLDivElement>) => {
const { errorMessage, errorMessageProps, showErrorIcon } = props;
const domRef = useDOMRef(ref);
return (
<div data-field-error-text="">
{showErrorIcon && <AlertIcon />}
<span {...errorMessageProps} ref={domRef}>
{errorMessage}
</span>
</div>
);
},
);
return (
<div data-field-error-text="">
{showErrorIcon && <AlertIcon />}
<span {...errorMessageProps} ref={domRef}>
{errorMessage}
</span>
</div>
);
};
export const ErrorText = forwardRef(_ErrorText);

View File

@ -1,14 +1,15 @@
import React, { forwardRef } from "react";
import type { SpectrumFieldProps } from "@react-types/label";
import type { Ref } from "react";
import { Label } from "./Label";
import { ErrorText } from "./ErrorText";
export type FieldProps = SpectrumFieldProps;
export type FieldRef = any;
export type FieldRef = Ref<HTMLDivElement>;
export const Field = forwardRef((props: FieldProps, ref: FieldRef) => {
const _Field = (props: FieldProps, ref: FieldRef) => {
const {
children,
elementType,
@ -74,4 +75,6 @@ export const Field = forwardRef((props: FieldProps, ref: FieldRef) => {
</div>
</div>
);
});
};
export const Field = forwardRef(_Field);

View File

@ -10,63 +10,61 @@ export interface LabelProps extends SpectrumLabelProps {
labelWidth?: string;
}
export const Label = forwardRef(
(props: LabelProps, ref: DOMRef<HTMLLabelElement>) => {
const {
children,
labelPosition = "top",
labelAlign = labelPosition === "side" ? "start" : null,
isRequired,
necessityIndicator = isRequired != null ? "icon" : null,
includeNecessityIndicatorInAccessibilityName = false,
htmlFor,
for: labelFor,
elementType: ElementType = "label",
onClick,
...otherProps
} = props;
const _Label = (props: LabelProps, ref: DOMRef<HTMLLabelElement>) => {
const {
children,
labelPosition = "top",
labelAlign = labelPosition === "side" ? "start" : null,
isRequired,
necessityIndicator = isRequired != null ? "icon" : null,
includeNecessityIndicatorInAccessibilityName = false,
htmlFor,
for: labelFor,
elementType: ElementType = "label",
onClick,
...otherProps
} = props;
const domRef = useDOMRef(ref);
const domRef = useDOMRef(ref);
const necessityLabel = isRequired ? "(required)" : "(optional)";
const icon = (
<AsteriskIcon
aria-label={
includeNecessityIndicatorInAccessibilityName
? "(required)"
: undefined
}
data-field-necessity-indicator-icon=""
/>
);
const necessityLabel = isRequired ? "(required)" : "(optional)";
const icon = (
<AsteriskIcon
aria-label={
includeNecessityIndicatorInAccessibilityName ? "(required)" : undefined
}
data-field-necessity-indicator-icon=""
/>
);
return (
<ElementType
data-align={labelAlign}
data-field-label=""
data-position={labelPosition}
{...filterDOMProps(otherProps)}
htmlFor={ElementType === "label" ? labelFor || htmlFor : undefined}
onClick={onClick}
ref={domRef}
>
{children}
{/* necessityLabel is hidden to screen readers if the field is required because
* aria-required is set on the field in that case. That will already be announced,
* so no need to duplicate it here. If optional, we do want it to be announced here. */}
{necessityIndicator === "label" && (
<span
aria-hidden={
!includeNecessityIndicatorInAccessibilityName
? isRequired
: undefined
}
>
{necessityLabel}
</span>
)}
{necessityIndicator === "icon" && isRequired && icon}
</ElementType>
);
},
);
return (
<ElementType
data-align={labelAlign}
data-field-label=""
data-position={labelPosition}
{...filterDOMProps(otherProps)}
htmlFor={ElementType === "label" ? labelFor || htmlFor : undefined}
onClick={onClick}
ref={domRef}
>
{children}
{/* necessityLabel is hidden to screen readers if the field is required because
* aria-required is set on the field in that case. That will already be announced,
* so no need to duplicate it here. If optional, we do want it to be announced here. */}
{necessityIndicator === "label" && (
<span
aria-hidden={
!includeNecessityIndicatorInAccessibilityName
? isRequired
: undefined
}
>
{necessityLabel}
</span>
)}
{necessityIndicator === "icon" && isRequired && icon}
</ElementType>
);
};
export const Label = forwardRef(_Label);

View File

@ -10,7 +10,7 @@ import type { FocusableRef, StyleProps } from "@react-types/shared";
import { RadioContext } from "./context";
import type { RadioGroupContext } from "./context";
import type { InlineLabelProps } from "../Checkbox/Checkbox";
import type { InlineLabelProps } from "../Checkbox";
export interface RadioProps
extends Omit<SpectrumRadioProps, keyof StyleProps>,
@ -20,7 +20,7 @@ export interface RadioProps
export type RadioRef = FocusableRef<HTMLLabelElement>;
export const Radio = forwardRef((props: RadioProps, ref: RadioRef) => {
const _Radio = (props: RadioProps, ref: RadioRef) => {
const {
autoFocus,
children,
@ -65,4 +65,6 @@ export const Radio = forwardRef((props: RadioProps, ref: RadioRef) => {
{children}
</label>
);
});
};
export const Radio = forwardRef(_Radio);

View File

@ -17,46 +17,46 @@ export interface RadioGroupProps
labelWidth?: LabelProps["labelWidth"];
}
export const RadioGroup = forwardRef(
(props: RadioGroupProps, ref: RadioGroupRef) => {
const {
children,
className,
isDisabled = false,
orientation = "vertical",
validationState,
} = props;
const domRef = useDOMRef(ref);
const state = useRadioGroupState(props);
const { descriptionProps, errorMessageProps, labelProps, radioGroupProps } =
useRadioGroup(props, state);
const _RadioGroup = (props: RadioGroupProps, ref: RadioGroupRef) => {
const {
children,
className,
isDisabled = false,
orientation = "vertical",
validationState,
} = props;
const domRef = useDOMRef(ref);
const state = useRadioGroupState(props);
const { descriptionProps, errorMessageProps, labelProps, radioGroupProps } =
useRadioGroup(props, state);
return (
<Field
{...props}
descriptionProps={descriptionProps}
errorMessageProps={errorMessageProps}
includeNecessityIndicatorInAccessibilityName
labelProps={labelProps}
ref={domRef}
wrapperClassName={className}
return (
<Field
{...props}
descriptionProps={descriptionProps}
errorMessageProps={errorMessageProps}
includeNecessityIndicatorInAccessibilityName
labelProps={labelProps}
ref={domRef}
wrapperClassName={className}
>
<div
{...radioGroupProps}
data-field-group=""
data-orientation={orientation}
>
<div
{...radioGroupProps}
data-field-group=""
data-orientation={orientation}
<RadioContext.Provider
value={{
validationState,
state,
isDisabled,
}}
>
<RadioContext.Provider
value={{
validationState,
state,
isDisabled,
}}
>
{children}
</RadioContext.Provider>
</div>
</Field>
);
},
);
{children}
</RadioContext.Provider>
</div>
</Field>
);
};
export const RadioGroup = forwardRef(_RadioGroup);

View File

@ -24,7 +24,7 @@ export interface SwitchProps
export type SwitchRef = FocusableRef<HTMLLabelElement>;
export const Switch = forwardRef((props: SwitchProps, ref: SwitchRef) => {
const _Switch = (props: SwitchProps, ref: SwitchRef) => {
const {
autoFocus,
children,
@ -87,4 +87,6 @@ export const Switch = forwardRef((props: SwitchProps, ref: SwitchRef) => {
{children}
</label>
);
});
};
export const Switch = forwardRef(_Switch);

View File

@ -1,4 +1,4 @@
import React from "react";
import React, { forwardRef } from "react";
import {
useMergeRefs,
FloatingPortal,
@ -9,42 +9,46 @@ import { useTooltipContext } from "./TooltipContext";
export type TooltipContentProps = React.HTMLAttributes<HTMLDivElement> & {
root?: HTMLElement;
className?: string;
};
export type TooltipContentRef = React.Ref<HTMLDivElement>;
export const TooltipContent = React.forwardRef(
(props: TooltipContentProps, propRef: TooltipContentRef) => {
const context = useTooltipContext();
const { className, root: rootProp, ...rest } = props;
const ref = useMergeRefs([context.refs.setFloating, propRef]);
const { children, ...floatingProps } = context.getFloatingProps(rest);
const arrowWidth = context.arrowRef.current?.clientWidth ?? 0;
const _TooltipContent = (
props: TooltipContentProps,
propRef: TooltipContentRef,
) => {
const context = useTooltipContext();
const { className, root: rootProp, ...rest } = props;
const ref = useMergeRefs([context.refs.setFloating, propRef]);
const { children, ...floatingProps } = context.getFloatingProps(rest);
const arrowWidth = context.arrowRef.current?.clientWidth ?? 0;
if (!context.open) return null;
if (!context.open) return null;
const root = context.refs.domReference.current?.closest(
"[data-theme-provider]",
) as HTMLElement;
const root = context.refs.domReference.current?.closest(
"[data-theme-provider]",
) as HTMLElement;
return (
<FloatingPortal root={rootProp ?? root}>
<div
className={className}
data-tooltip-content=""
data-tooltip-placement={context.placement}
ref={ref}
style={context.floatingStyles}
{...floatingProps}
>
{children}
<FloatingArrow
context={context.context}
data-tooltip-trigger-arrow=""
ref={context.arrowRef}
staticOffset={`calc(50% - ${arrowWidth / 2}px)`}
/>
</div>
</FloatingPortal>
);
},
);
return (
<FloatingPortal root={rootProp ?? root}>
<div
className={className}
data-tooltip-content=""
data-tooltip-placement={context.placement}
ref={ref}
style={context.floatingStyles}
{...floatingProps}
>
{children}
<FloatingArrow
context={context.context}
data-tooltip-trigger-arrow=""
ref={context.arrowRef}
staticOffset={`calc(50% - ${arrowWidth / 2}px)`}
/>
</div>
</FloatingPortal>
);
};
export const TooltipContent = forwardRef(_TooltipContent);

View File

@ -1,4 +1,4 @@
import * as React from "react";
import React, { forwardRef } from "react";
import { useMergeRefs } from "@floating-ui/react";
import { useTooltipContext } from "./TooltipContext";
@ -6,13 +6,14 @@ import { useTooltipContext } from "./TooltipContext";
export type TooltipTriggerRef = React.Ref<HTMLElement>;
export type TooltipTriggerProps = React.HTMLProps<HTMLElement>;
export const TooltipTrigger = React.forwardRef(function TooltipTrigger(
const _TooltipTrigger = (
props: TooltipTriggerProps,
propRef: TooltipTriggerRef,
) {
) => {
const { children, ...rest } = props;
const context = useTooltipContext();
const childrenRef = (children as any).ref;
// @ts-expect-error we don't which type children will be
const childrenRef = (children as unknown).ref;
const ref = useMergeRefs([context.refs.setReference, propRef, childrenRef]);
if (React.isValidElement(children)) {
@ -31,4 +32,6 @@ export const TooltipTrigger = React.forwardRef(function TooltipTrigger(
}
return null;
});
};
export const TooltipTrigger = forwardRef(_TooltipTrigger);

View File

@ -0,0 +1,7 @@
{
"extends": ["../../../.eslintrc.base.json"],
"rules": {
"@typescript-eslint/no-explicit-any": "off",
"react/display-name": "off"
}
}

View File

@ -6,7 +6,7 @@ import { render, screen } from "@testing-library/react";
import { Button } from "./";
// Adapted from remixicon-react/EmotionHappyLineIcon (https://github.com/Remix-Design/RemixIcon/blob/f88a51b6402562c6c2465f61a3e845115992e4c6/icons/User%20%26%20Faces/emotion-happy-line.svg)
const EmotionHappyLineIcon = ({ ...props }: Record<string, any>) => {
const EmotionHappyLineIcon = ({ ...props }: Record<string, string>) => {
return (
<svg
fill="currentColor"

View File

@ -40,67 +40,67 @@ export interface ButtonProps extends Omit<HeadlessButtonProps, "className"> {
loadingText?: string;
}
export const Button = forwardRef(
(props: ButtonProps, ref: HeadlessButtonRef) => {
props = useVisuallyDisabled(props);
const {
children,
color = "accent",
icon,
iconPosition = "start",
isLoading,
loadingText = "Loading...",
// eslint-disable-next-line -- TODO add onKeyUp when the bug is fixed https://github.com/adobe/react-spectrum/issues/4350
onKeyUp,
variant = "filled",
visuallyDisabled,
...rest
} = props;
const { visuallyHiddenProps } = useVisuallyHidden();
const renderChildren = () => {
return (
<>
<span aria-hidden={isLoading ? true : undefined} data-content="">
{icon}
<Text lineClamp={1} textAlign="center">
{children}
</Text>
</span>
<span aria-hidden={!isLoading ? true : undefined} data-loader="">
<HeadlessIcon>
<Spinner />
</HeadlessIcon>
<span {...visuallyHiddenProps}>{loadingText}</span>
</span>
</>
);
};
const _Button = (props: ButtonProps, ref: HeadlessButtonRef) => {
props = useVisuallyDisabled(props);
const {
children,
color = "accent",
icon,
iconPosition = "start",
isLoading,
loadingText = "Loading...",
// eslint-disable-next-line -- TODO add onKeyUp when the bug is fixed https://github.com/adobe/react-spectrum/issues/4350
onKeyUp,
variant = "filled",
visuallyDisabled,
...rest
} = props;
const { visuallyHiddenProps } = useVisuallyHidden();
const renderChildren = () => {
return (
<StyledButton
$color={color}
$variant={variant}
aria-busy={isLoading ? true : undefined}
aria-disabled={
visuallyDisabled || isLoading || props.isDisabled ? true : undefined
}
data-button=""
data-color={color}
data-icon-position={iconPosition === "start" ? "start" : "end"}
data-loading={isLoading ? "" : undefined}
data-variant={variant}
draggable
ref={ref}
{...rest}
>
{renderChildren()}
<DragContainer aria-hidden="true" />
</StyledButton>
<>
<span aria-hidden={isLoading ? true : undefined} data-content="">
{icon}
<Text lineClamp={1} textAlign="center">
{children}
</Text>
</span>
<span aria-hidden={!isLoading ? true : undefined} data-loader="">
<HeadlessIcon>
<Spinner />
</HeadlessIcon>
<span {...visuallyHiddenProps}>{loadingText}</span>
</span>
</>
);
},
);
};
return (
<StyledButton
$color={color}
$variant={variant}
aria-busy={isLoading ? true : undefined}
aria-disabled={
visuallyDisabled || isLoading || props.isDisabled ? true : undefined
}
data-button=""
data-color={color}
data-icon-position={iconPosition === "start" ? "start" : "end"}
data-loading={isLoading ? "" : undefined}
data-variant={variant}
draggable
ref={ref}
{...rest}
>
{renderChildren()}
<DragContainer aria-hidden="true" />
</StyledButton>
);
};
export const Button = forwardRef(_Button);
/**
* This hook is used to disable all click/press events on a button

View File

@ -28,7 +28,7 @@ describe("@design-system/widgets/Button Group", () => {
it("should support custom props", () => {
const { container } = renderComponent({
"data-testid": "button-group",
} as any);
} as ButtonGroupProps);
const buttonGroup = container.querySelector("div") as HTMLElement;
expect(buttonGroup).toHaveAttribute("data-testid", "button-group");

View File

@ -7,7 +7,7 @@ import userEvent from "@testing-library/user-event";
import { Checkbox } from "./Checkbox";
// Adapted from remixicon-react/EmotionHappyLineIcon (https://github.com/Remix-Design/RemixIcon/blob/f88a51b6402562c6c2465f61a3e845115992e4c6/icons/User%20%26%20Faces/emotion-happy-line.svg)
const EmotionHappyLineIcon = ({ ...props }: Record<string, any>) => {
const EmotionHappyLineIcon = ({ ...props }: Record<string, string>) => {
return (
<svg
fill="currentColor"

View File

@ -10,14 +10,14 @@ import { StyledCheckbox } from "./index.styled";
export type CheckboxProps = HeadlessCheckboxProps;
export const Checkbox = forwardRef(
(props: CheckboxProps, ref: HeadlessCheckboxRef) => {
const { children, labelPosition = "right", ...rest } = props;
const _Checkbox = (props: CheckboxProps, ref: HeadlessCheckboxRef) => {
const { children, labelPosition = "right", ...rest } = props;
return (
<StyledCheckbox labelPosition={labelPosition} ref={ref} {...rest}>
{children && <Text>{children}</Text>}
</StyledCheckbox>
);
},
);
return (
<StyledCheckbox labelPosition={labelPosition} ref={ref} {...rest}>
{children && <Text>{children}</Text>}
</StyledCheckbox>
);
};
export const Checkbox = forwardRef(_Checkbox);

View File

@ -12,19 +12,22 @@ export interface CheckboxGroupProps extends HeadlessCheckboxGroupProps {
className?: string;
}
export const CheckboxGroup = forwardRef(
(props: CheckboxGroupProps, ref: HeadlessCheckboxGroupRef) => {
const { errorMessage, label, ...rest } = props;
const wrappedErrorMessage = errorMessage && <Text>{errorMessage}</Text>;
const wrappedLabel = label && <Text>{label}</Text>;
const _CheckboxGroup = (
props: CheckboxGroupProps,
ref: HeadlessCheckboxGroupRef,
) => {
const { errorMessage, label, ...rest } = props;
const wrappedErrorMessage = errorMessage && <Text>{errorMessage}</Text>;
const wrappedLabel = label && <Text>{label}</Text>;
return (
<StyledCheckboxGroup
errorMessage={wrappedErrorMessage}
label={wrappedLabel}
ref={ref}
{...rest}
/>
);
},
);
return (
<StyledCheckboxGroup
errorMessage={wrappedErrorMessage}
label={wrappedLabel}
ref={ref}
{...rest}
/>
);
};
export const CheckboxGroup = forwardRef(_CheckboxGroup);

View File

@ -1,6 +1,6 @@
import styled from "styled-components";
import type { StyledFlexProps } from "./types";
import type { Responsive, StyledFlexProps } from "./types";
export const StyledFlex = styled.div<StyledFlexProps>`
${({ $wrap }) => {
@ -140,9 +140,12 @@ export const StyledFlex = styled.div<StyledFlexProps>`
}}
`;
// the value and returned callback value can be of any type in accordance with component props
const containerDimensionStyles = (
cssProp: string,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
value: any,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
callback?: (value: any) => void,
) => {
if (value == null) return;
@ -169,7 +172,21 @@ const containerDimensionStyles = (
return `${cssProp}: ${callback ? callback(value) : value};`;
};
const flexAlignValue = (value: any) => {
const flexAlignValue = (
value: Responsive<
| "start"
| "end"
| "center"
| "stretch"
| "self-start"
| "self-end"
| "baseline"
| "first baseline"
| "last baseline"
| "safe center"
| "unsafe center"
>,
) => {
if (value === "start") {
return "flex-start";
}
@ -181,7 +198,9 @@ const flexAlignValue = (value: any) => {
return value;
};
const flexWrapValue = (value: any) => {
const flexWrapValue = (
value: Responsive<boolean | "wrap" | "nowrap" | "wrap-reverse">,
) => {
if (typeof value === "boolean") {
return value ? "wrap" : "nowrap";
}
@ -189,7 +208,7 @@ const flexWrapValue = (value: any) => {
return value;
};
const cssVarValue = (value: any) => {
const cssVarValue = (value: string) => {
if (value == null) return;
if (value.includes("spacing") || value.includes("sizing")) {
@ -199,7 +218,7 @@ const cssVarValue = (value: any) => {
return value;
};
const hiddenValue = (value?: any) => {
const hiddenValue = (value: boolean) => {
return value ? "none" : "flex";
};

View File

@ -2,7 +2,7 @@ import type { ReactNode, CSSProperties } from "react";
import type { OmitRename } from "../../utils";
import type { SizingDimension, SpacingDimension } from "./dimensions";
type Responsive<T> =
export type Responsive<T> =
| T
| {
base?: T;

View File

@ -10,7 +10,7 @@ import { StyledRadio } from "./index.styled";
export type RadioProps = HeadlessRadioProps;
export const Radio = forwardRef((props: RadioProps, ref: HeadlessRadioRef) => {
const _Radio = (props: RadioProps, ref: HeadlessRadioRef) => {
const { children, labelPosition = "right", ...rest } = props;
return (
@ -18,4 +18,6 @@ export const Radio = forwardRef((props: RadioProps, ref: HeadlessRadioRef) => {
{children && <Text>{children}</Text>}
</StyledRadio>
);
});
};
export const Radio = forwardRef(_Radio);

View File

@ -12,19 +12,19 @@ export interface RadioGroupProps extends HeadlessRadioGroupProps {
className?: string;
}
export const RadioGroup = forwardRef(
(props: RadioGroupProps, ref: HeadlessRadioGroupRef) => {
const { errorMessage, label, ...rest } = props;
const wrappedErrorMessage = errorMessage && <Text>{errorMessage}</Text>;
const wrappedLabel = label && <Text>{label}</Text>;
const _RadioGroup = (props: RadioGroupProps, ref: HeadlessRadioGroupRef) => {
const { errorMessage, label, ...rest } = props;
const wrappedErrorMessage = errorMessage && <Text>{errorMessage}</Text>;
const wrappedLabel = label && <Text>{label}</Text>;
return (
<StyledRadioGroup
errorMessage={wrappedErrorMessage}
label={wrappedLabel}
ref={ref}
{...rest}
/>
);
},
);
return (
<StyledRadioGroup
errorMessage={wrappedErrorMessage}
label={wrappedLabel}
ref={ref}
{...rest}
/>
);
};
export const RadioGroup = forwardRef(_RadioGroup);

View File

@ -7,7 +7,7 @@ function LoaderIcon({
...props
}: {
className?: string;
[key: string]: any;
[key: string]: unknown;
}) {
return (
<svg

View File

@ -10,19 +10,14 @@ import { StyledSwitch } from "./index.styled";
export type SwitchProps = Omit<HeadlessSwitchProps, "icon" | "isIndeterminate">;
export const Switch = forwardRef(
(props: SwitchProps, ref: HeadlessSwitchRef) => {
const { children, labelPosition = "right", ...rest } = props;
const _Switch = (props: SwitchProps, ref: HeadlessSwitchRef) => {
const { children, labelPosition = "right", ...rest } = props;
return (
<StyledSwitch
labelPosition={labelPosition}
ref={ref}
{...rest}
icon={null}
>
{children && <Text>{children}</Text>}
</StyledSwitch>
);
},
);
return (
<StyledSwitch labelPosition={labelPosition} ref={ref} {...rest} icon={null}>
{children && <Text>{children}</Text>}
</StyledSwitch>
);
};
export const Switch = forwardRef(_Switch);

View File

@ -35,34 +35,34 @@ export interface TextProps {
children: React.ReactNode;
}
export const Text = forwardRef(
(props: TextProps, ref: Ref<HTMLParagraphElement>) => {
const {
children,
className,
color = "default",
isBold = false,
isItalic = false,
lineClamp,
textAlign = "left",
variant = "body",
...rest
} = props;
const _Text = (props: TextProps, ref: Ref<HTMLParagraphElement>) => {
const {
children,
className,
color = "default",
isBold = false,
isItalic = false,
lineClamp,
textAlign = "left",
variant = "body",
...rest
} = props;
return (
<StyledText
$isBold={isBold}
$isItalic={isItalic}
$lineClamp={lineClamp}
$textAlign={textAlign}
$variant={variant}
className={classNames(className, getTypographyClassName(variant))}
color={color}
ref={ref}
{...rest}
>
<span>{children}</span>
</StyledText>
);
},
);
return (
<StyledText
$isBold={isBold}
$isItalic={isItalic}
$lineClamp={lineClamp}
$textAlign={textAlign}
$variant={variant}
className={classNames(className, getTypographyClassName(variant))}
color={color}
ref={ref}
{...rest}
>
<span>{children}</span>
</StyledText>
);
};
export const Text = forwardRef(_Text);

View File

@ -10,21 +10,24 @@ import type {
} from "@design-system/headless";
import { StyledTooltipContent } from "./index.styled";
export const TooltipContent = forwardRef(
(props: HeadlessTooltipContentProps, ref: HeadlessTooltipContentRef) => {
const { children, ...rest } = props;
const _TooltipContent = (
props: HeadlessTooltipContentProps,
ref: HeadlessTooltipContentRef,
) => {
const { children, ...rest } = props;
// We have to shift the arrow so that there is no empty space if the tooltip has rounding
const theme = useThemeContext();
const borderRadius = Number(
(theme?.borderRadius?.[1].value as string).replace("px", ""),
);
const isRounded = borderRadius > BORDER_RADIUS_THRESHOLD;
// We have to shift the arrow so that there is no empty space if the tooltip has rounding
const theme = useThemeContext();
const borderRadius = Number(
(theme?.borderRadius?.[1].value as string).replace("px", ""),
);
const isRounded = borderRadius > BORDER_RADIUS_THRESHOLD;
return (
<StyledTooltipContent $isRounded={isRounded} ref={ref} {...rest}>
{typeof children === "string" ? <Text>{children}</Text> : children}
</StyledTooltipContent>
);
},
);
return (
<StyledTooltipContent $isRounded={isRounded} ref={ref} {...rest}>
{typeof children === "string" ? <Text>{children}</Text> : children}
</StyledTooltipContent>
);
};
export const TooltipContent = forwardRef(_TooltipContent);

View File

@ -2,8 +2,7 @@ import peerDepsExternal from "rollup-plugin-peer-deps-external";
import commonjs from "@rollup/plugin-commonjs";
import typescript from "rollup-plugin-typescript2";
import generatePackageJson from "rollup-plugin-generate-package-json";
const packageJson = require("./package.json");
import packageJson from "./package.json";
export default {
// TODO: Figure out regex where each directory can be a separate module without having to manually add them

View File

@ -85,7 +85,7 @@ describe("Test #2 - normalize operations on SIMPLE DSL structures", () => {
};
it("Test `flattenDSL` for simple_dsl", () => {
const flatDSL = flattenDSL<Record<string, any>>(simple_dsl);
const flatDSL = flattenDSL<Record<string, unknown>>(simple_dsl);
expect(flatDSL).toStrictEqual(simple_flat_dsl);
});

View File

@ -1,4 +1,7 @@
{
"extends": ["../../.eslintrc.base.json"],
"ignorePatterns": ["dist"]
"ignorePatterns": ["dist"],
"rules": {
"@typescript-eslint/no-explicit-any": "off"
}
}

View File

@ -26,13 +26,12 @@ import { TAILWIND_COLORS } from "constants/ThemeConstants";
import useDSEvent from "utils/hooks/useDSEvent";
import { DSEventTypes } from "utils/AppsmithUtils";
import { getBrandColors } from "@appsmith/selectors/tenantSelectors";
import FocusTrap from "focus-trap-react";
import {
createMessage,
FULL_COLOR_PICKER_LABEL,
} from "@appsmith/constants/messages";
const FocusTrap = require("focus-trap-react");
const MAX_COLS = 10;
/**

View File

@ -1,6 +1,7 @@
// Leaving this require here. The path-to-regexp module has a commonJS version and an ESM one.
// We are loading the correct one with the typings with our compilerOptions property "moduleResolution" set to "node". Ref: https://stackoverflow.com/questions/59013618/unable-to-find-module-path-to-regexp
// All solutions from closed issues on their repo have been tried. Ref: https://github.com/pillarjs/path-to-regexp/issues/193
// eslint-disable-next-line @typescript-eslint/no-var-requires
const { match } = require("path-to-regexp");
export const BUILDER_VIEWER_PATH_PREFIX = "/app/";

View File

@ -1,3 +1,4 @@
// eslint-disable-next-line @typescript-eslint/no-var-requires
const { match } = require("path-to-regexp");
export const BASE_URL = "/";

View File

@ -1,4 +1,5 @@
// Leaving this require here. Importing causes type mismatches which have not been resolved by including the typings or any other means. Ref: https://github.com/remix-run/history/issues/802
// eslint-disable-next-line @typescript-eslint/no-var-requires
const createHistory = require("history").createBrowserHistory;
import type { History } from "history";

View File

@ -3,6 +3,7 @@
import React from "react";
if (process.env.NODE_ENV === "development") {
// eslint-disable-next-line @typescript-eslint/no-var-requires
const whyDidYouRender = require("@welldone-software/why-did-you-render");
whyDidYouRender(React, {
trackAllPureComponents: false,

View File

@ -20,6 +20,7 @@ import { EChartsConfigurationBuilder } from "./EChartsConfigurationBuilder";
import { EChartsDatasetBuilder } from "./EChartsDatasetBuilder";
// Leaving this require here. Ref: https://stackoverflow.com/questions/41292559/could-not-find-a-declaration-file-for-module-module-name-path-to-module-nam/42505940#42505940
// FusionCharts comes with its own typings so there is no need to separately import them. But an import from fusioncharts/core still requires a declaration file.
// eslint-disable-next-line @typescript-eslint/no-var-requires
const FusionCharts = require("fusioncharts");
const plugins: Record<string, any> = {
Charts: require("fusioncharts/fusioncharts.charts"),

View File

@ -1,7 +1,7 @@
import FileDataTypes from "../constants";
import parseFileData from "./FileParser";
import fs from "fs";
const path = require("path");
import path from "path";
describe("File parser formats differenty file types correctly", () => {
it("parses csv file correclty", async () => {

View File

@ -34,8 +34,7 @@ import { rgbaMigrationConstantV56 } from "./constants";
import type { ContainerWidgetProps } from "./ContainerWidget/widget";
import type { SchemaItem } from "./JSONFormWidget/constants";
import { WIDGET_COMPONENT_BOUNDARY_CLASS } from "constants/componentClassNameConstants";
const punycode = require("punycode/");
import punycode from "punycode";
type SanitizeOptions = {
existingKeys?: string[];