chore: add more linting rules and fix warnings (#325)
This commit is contained in:
parent
76741d6fb8
commit
87403c9407
11 changed files with 28 additions and 19 deletions
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"$schema": "./node_modules/oxlint/configuration_schema.json",
|
||||
"plugins": ["unicorn", "typescript", "oxc"],
|
||||
"plugins": ["eslint", "unicorn", "typescript", "oxc", "import", "react", "react-perf", "node", "jsx-a11y"],
|
||||
"categories": {},
|
||||
"rules": {
|
||||
"constructor-super": "warn",
|
||||
|
|
@ -112,7 +112,8 @@
|
|||
"unicorn/no-useless-length-check": "warn",
|
||||
"unicorn/no-useless-spread": "warn",
|
||||
"unicorn/prefer-set-size": "warn",
|
||||
"unicorn/prefer-string-starts-ends-with": "warn"
|
||||
"unicorn/prefer-string-starts-ends-with": "warn",
|
||||
"import/no-cycle": "error"
|
||||
},
|
||||
"settings": {
|
||||
"jsx-a11y": {
|
||||
|
|
|
|||
|
|
@ -489,18 +489,27 @@ interface ButtonProps {
|
|||
const NodeButton = memo(({ depth, icon, onClick, onMouseEnter, className, children }: ButtonProps) => {
|
||||
const paddingLeft = useMemo(() => `${8 + depth * NODE_PADDING_LEFT}px`, [depth]);
|
||||
|
||||
const handleKeyDown = useCallback(
|
||||
(e: React.KeyboardEvent) => {
|
||||
if (e.key === "Enter" || e.key === " ") {
|
||||
e.preventDefault();
|
||||
onClick?.();
|
||||
}
|
||||
},
|
||||
[onClick],
|
||||
);
|
||||
|
||||
return (
|
||||
// biome-ignore lint/a11y/noStaticElementInteractions: we handle click and hover manually
|
||||
// biome-ignore lint/a11y/useKeyWithClickEvents: we handle click and hover manually
|
||||
<div
|
||||
<button
|
||||
className={cn("flex items-center gap-2 w-full pr-2 text-sm py-1.5 text-left", className)}
|
||||
style={{ paddingLeft }}
|
||||
onClick={onClick}
|
||||
onMouseEnter={onMouseEnter}
|
||||
onKeyDown={handleKeyDown}
|
||||
>
|
||||
{icon}
|
||||
<div className="truncate w-full flex items-center gap-2">{children}</div>
|
||||
</div>
|
||||
</button>
|
||||
);
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ export const SnapshotsTable = ({ snapshots, repositoryId, backups }: Props) => {
|
|||
}
|
||||
setSelectedIds(newSelected);
|
||||
}}
|
||||
aria-label={`Select snapshot ${snapshot.short_id}`}
|
||||
aria-label={`Select snapshot ${snapshot.short_id}` as string}
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCell className="font-mono text-sm">
|
||||
|
|
|
|||
|
|
@ -27,9 +27,9 @@ const Alert = React.forwardRef<
|
|||
));
|
||||
Alert.displayName = "Alert";
|
||||
|
||||
const AlertTitle = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLHeadingElement>>(
|
||||
const AlertTitle = React.forwardRef<HTMLHeadingElement, React.HTMLAttributes<HTMLHeadingElement>>(
|
||||
({ className, ...props }, ref) => (
|
||||
<h5 ref={ref} className={cn("mb-1 font-medium leading-none tracking-tight", className)} {...props} />
|
||||
<h5 ref={ref} className={cn("mb-1 font-medium leading-none tracking-tight", className)} {...props}>{props.children}</h5>
|
||||
),
|
||||
);
|
||||
AlertTitle.displayName = "AlertTitle";
|
||||
|
|
|
|||
|
|
@ -43,16 +43,17 @@ function BreadcrumbLink({
|
|||
);
|
||||
}
|
||||
|
||||
function BreadcrumbPage({ className, ...props }: React.ComponentProps<"span">) {
|
||||
function BreadcrumbPage({ className, children, ...props }: React.ComponentProps<"a">) {
|
||||
return (
|
||||
<span
|
||||
<a
|
||||
data-slot="breadcrumb-page"
|
||||
role="link"
|
||||
aria-disabled="true"
|
||||
aria-current="page"
|
||||
className={cn("text-foreground font-normal truncate", className)}
|
||||
{...props}
|
||||
/>
|
||||
>
|
||||
{children}
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -88,7 +88,6 @@ export default function DownloadRecoveryKeyPage() {
|
|||
onChange={(e) => setPassword(e.target.value)}
|
||||
placeholder="Enter your password"
|
||||
required
|
||||
autoFocus
|
||||
disabled={downloadResticPassword.isPending}
|
||||
/>
|
||||
<p className="text-xs text-muted-foreground">Enter your account password to download the recovery key</p>
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ export default function LoginPage() {
|
|||
<FormItem>
|
||||
<FormLabel>Username</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field} type="text" placeholder="admin" disabled={isLoggingIn} autoFocus />
|
||||
<Input {...field} type="text" placeholder="admin" disabled={isLoggingIn} />
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ export default function OnboardingPage() {
|
|||
<FormItem>
|
||||
<FormLabel>Username</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field} type="text" placeholder="admin" disabled={submitting} autoFocus />
|
||||
<Input {...field} type="text" placeholder="admin" disabled={submitting} />
|
||||
</FormControl>
|
||||
<FormDescription>Choose a username for the admin account</FormDescription>
|
||||
<FormMessage />
|
||||
|
|
|
|||
|
|
@ -393,7 +393,7 @@ export const CreateScheduleForm = ({ initialValues, formId, onSubmit, volume }:
|
|||
type="button"
|
||||
onClick={() => handleRemovePath(path)}
|
||||
className="ml-1 hover:bg-destructive/20 rounded p-0.5 transition-colors"
|
||||
aria-label={`Remove ${path}`}
|
||||
aria-label={`Remove ${path}` as string}
|
||||
>
|
||||
<X className="h-3 w-3" />
|
||||
</button>
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ export const ScheduleSummary = (props: Props) => {
|
|||
repositoryLabel: schedule.repositoryId || "No repository selected",
|
||||
retentionLabel: retentionParts.length > 0 ? retentionParts.join(" • ") : "No retention policy",
|
||||
};
|
||||
}, [schedule, schedule.volume.name]);
|
||||
}, [schedule]);
|
||||
|
||||
const handleConfirmDelete = () => {
|
||||
setShowDeleteConfirm(false);
|
||||
|
|
|
|||
|
|
@ -244,7 +244,6 @@ export default function Settings({ loaderData }: Route.ComponentProps) {
|
|||
onChange={(e) => setDownloadPassword(e.target.value)}
|
||||
placeholder="Enter your password"
|
||||
required
|
||||
autoFocus
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Reference in a new issue