From 990ba6f05072193d30815ecb42c8b4202bde86e6 Mon Sep 17 00:00:00 2001 From: Ajax Davis Date: Wed, 26 Nov 2025 19:04:34 +1000 Subject: [PATCH] fix: correct Biome formatting and restore non-null assertions in tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove root biome.json (conflicted with packages/config/biome.json) - Format all files with correct config (spaces, not tabs) - Restore non-null assertions (ref!) in test files where refs are guaranteed - Biome's optional chaining conversion broke TypeScript inference in tests Fixes type-check and format-check CI failures. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- biome.json | 29 --- packages/ui/src/Badge/Badge.test.tsx | 22 ++- packages/ui/src/Badge/types.ts | 9 +- packages/ui/src/Badge/variants.ts | 28 ++- packages/ui/src/Button/Button.test.tsx | 13 +- packages/ui/src/Button/variants.ts | 8 +- packages/ui/src/Card/Card.test.tsx | 37 +++- packages/ui/src/Card/Card.tsx | 25 ++- packages/ui/src/Card/variants.ts | 10 +- packages/ui/src/CodeBlock/CodeBlock.test.tsx | 38 +++- packages/ui/src/CodeBlock/CodeBlock.tsx | 18 +- packages/ui/src/CodeBlock/types.ts | 3 +- packages/ui/src/Container/Container.test.tsx | 2 +- .../src/GridContainer/GridContainer.test.tsx | 15 +- packages/ui/src/Header/Header.test.tsx | 18 +- packages/ui/src/Header/Header.tsx | 24 ++- packages/ui/src/Header/types.ts | 3 +- packages/ui/src/Icon/Icon.test.tsx | 16 +- packages/ui/src/Icon/types.ts | 3 +- packages/ui/src/Input/Input.test.tsx | 8 +- packages/ui/src/Input/types.ts | 3 +- packages/ui/src/Label/Label.test.tsx | 2 +- packages/ui/src/Label/Label.tsx | 12 +- .../ui/src/ProgressBar/ProgressBar.test.tsx | 41 +++- packages/ui/src/ProgressBar/ProgressBar.tsx | 12 +- packages/ui/src/ProgressBar/types.ts | 3 +- packages/ui/src/Section/Section.test.tsx | 10 +- packages/ui/src/Tabs/Tabs.test.tsx | 183 ++++++++++++++---- packages/ui/src/Tabs/Tabs.tsx | 16 +- packages/ui/src/Tabs/types.ts | 3 +- packages/ui/src/system/variants.ts | 22 ++- 31 files changed, 484 insertions(+), 152 deletions(-) delete mode 100644 biome.json diff --git a/biome.json b/biome.json deleted file mode 100644 index 8225e3a..0000000 --- a/biome.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json", - "vcs": { - "enabled": true, - "clientKind": "git", - "useIgnoreFile": true - }, - "files": { - "ignoreUnknown": false, - "ignore": [".next", "dist", ".turbo", "node_modules", "storybook-static"] - }, - "formatter": { - "enabled": true, - "formatWithErrors": false, - "indentStyle": "tab", - "indentWidth": 2, - "lineWidth": 100, - "lineEnding": "lf" - }, - "linter": { - "enabled": true, - "rules": { - "recommended": true, - "suspicious": { - "noExplicitAny": "warn" - } - } - } -} diff --git a/packages/ui/src/Badge/Badge.test.tsx b/packages/ui/src/Badge/Badge.test.tsx index 236ca3a..33abfdf 100644 --- a/packages/ui/src/Badge/Badge.test.tsx +++ b/packages/ui/src/Badge/Badge.test.tsx @@ -250,7 +250,7 @@ describe("Badge", () => { , ); expect(ref).toBeInstanceOf(HTMLDivElement); - expect(ref?.tagName).toBe("DIV"); + expect(ref!.tagName).toBe("DIV"); }); }); @@ -297,7 +297,11 @@ describe("Badge", () => { it("works correctly with outline variant and custom className", () => { render( - + Outlined , ); @@ -351,7 +355,12 @@ describe("Badge", () => { describe("Semantic Usage", () => { it("can be used as status indicator with role", () => { render( - + Online , ); @@ -363,7 +372,12 @@ describe("Badge", () => { it("can be used as notification count", () => { render( - + 3 , ); diff --git a/packages/ui/src/Badge/types.ts b/packages/ui/src/Badge/types.ts index 5726667..0264f6f 100644 --- a/packages/ui/src/Badge/types.ts +++ b/packages/ui/src/Badge/types.ts @@ -8,7 +8,14 @@ export interface BadgeProps extends HTMLAttributes { * Visual variant of the badge * @default 'default' */ - variant?: "default" | "secondary" | "outline" | "success" | "error" | "warning" | "info"; + variant?: + | "default" + | "secondary" + | "outline" + | "success" + | "error" + | "warning" + | "info"; /** * Size of the badge diff --git a/packages/ui/src/Badge/variants.ts b/packages/ui/src/Badge/variants.ts index 61f6a49..35dff41 100644 --- a/packages/ui/src/Badge/variants.ts +++ b/packages/ui/src/Badge/variants.ts @@ -19,17 +19,33 @@ export const badgeVariants = createVariants({ variants: { variant: { - default: ["bg-primary text-primary-foreground", "border border-primary"].join(" "), + default: [ + "bg-primary text-primary-foreground", + "border border-primary", + ].join(" "), - secondary: ["bg-secondary text-secondary-foreground", "border border-secondary"].join(" "), + secondary: [ + "bg-secondary text-secondary-foreground", + "border border-secondary", + ].join(" "), - outline: ["bg-transparent text-foreground", "border border-border"].join(" "), + outline: ["bg-transparent text-foreground", "border border-border"].join( + " ", + ), - success: ["bg-success text-success-foreground", "border border-success"].join(" "), + success: [ + "bg-success text-success-foreground", + "border border-success", + ].join(" "), - error: ["bg-error text-error-foreground", "border border-error"].join(" "), + error: ["bg-error text-error-foreground", "border border-error"].join( + " ", + ), - warning: ["bg-warning text-warning-foreground", "border border-warning"].join(" "), + warning: [ + "bg-warning text-warning-foreground", + "border border-warning", + ].join(" "), info: ["bg-info text-info-foreground", "border border-info"].join(" "), }, diff --git a/packages/ui/src/Button/Button.test.tsx b/packages/ui/src/Button/Button.test.tsx index 897b560..147832d 100644 --- a/packages/ui/src/Button/Button.test.tsx +++ b/packages/ui/src/Button/Button.test.tsx @@ -119,7 +119,9 @@ describe("Button", () => { }); it("applies icon size classes", () => { - render(, ); expect(ref).toBeInstanceOf(HTMLButtonElement); - expect(ref?.tagName).toBe("BUTTON"); + expect(ref!.tagName).toBe("BUTTON"); }); }); describe("HTML Attributes", () => { it("passes through HTML button attributes", () => { render( - , ); diff --git a/packages/ui/src/Button/variants.ts b/packages/ui/src/Button/variants.ts index f3f024f..3fa6a7e 100644 --- a/packages/ui/src/Button/variants.ts +++ b/packages/ui/src/Button/variants.ts @@ -65,9 +65,11 @@ export const buttonVariants = createVariants({ "active:bg-accent/80", ].join(" "), - link: ["text-primary underline-offset-4", "hover:underline", "active:text-primary/80"].join( - " ", - ), + link: [ + "text-primary underline-offset-4", + "hover:underline", + "active:text-primary/80", + ].join(" "), }, size: { diff --git a/packages/ui/src/Card/Card.test.tsx b/packages/ui/src/Card/Card.test.tsx index 3c62ce0..3696eae 100644 --- a/packages/ui/src/Card/Card.test.tsx +++ b/packages/ui/src/Card/Card.test.tsx @@ -1,6 +1,13 @@ import { render, screen } from "@testing-library/react"; import { describe, expect, it } from "vitest"; -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "./Card"; +import { + Card, + CardContent, + CardDescription, + CardFooter, + CardHeader, + CardTitle, +} from "./Card"; describe("Card", () => { describe("Rendering", () => { @@ -16,7 +23,9 @@ describe("Card", () => { Title - Description + + Description + Content Footer @@ -227,7 +236,9 @@ describe("Card", () => { render( - Description text + + Description text + , ); @@ -239,7 +250,9 @@ describe("Card", () => { render( - Description + + Description + , ); @@ -404,7 +417,7 @@ describe("Card", () => { , ); expect(ref).toBeInstanceOf(HTMLDivElement); - expect(ref?.tagName).toBe("DIV"); + expect(ref!.tagName).toBe("DIV"); }); it("forwards ref to CardHeader element", () => { @@ -439,7 +452,7 @@ describe("Card", () => { , ); expect(ref).toBeInstanceOf(HTMLHeadingElement); - expect(ref?.tagName).toBe("H3"); + expect(ref!.tagName).toBe("H3"); }); it("forwards ref to CardDescription element", () => { @@ -561,7 +574,9 @@ describe("Card", () => { render( - Description + + Description + , ); @@ -591,7 +606,9 @@ describe("Card", () => { Card Title This is a card description - Card content goes here + + Card content goes here + Footer actions , ); @@ -599,7 +616,9 @@ describe("Card", () => { const card = screen.getByTestId("card"); expect(card).toBeInTheDocument(); expect(screen.getByText("Card Title")).toBeInTheDocument(); - expect(screen.getByText("This is a card description")).toBeInTheDocument(); + expect( + screen.getByText("This is a card description"), + ).toBeInTheDocument(); expect(screen.getByText("Card content goes here")).toBeInTheDocument(); expect(screen.getByText("Footer actions")).toBeInTheDocument(); }); diff --git a/packages/ui/src/Card/Card.tsx b/packages/ui/src/Card/Card.tsx index 8b2f644..d458f9f 100644 --- a/packages/ui/src/Card/Card.tsx +++ b/packages/ui/src/Card/Card.tsx @@ -93,7 +93,13 @@ CardHeader.displayName = "CardHeader"; export const CardTitle = forwardRef( ({ className, as = "h3", ...props }, ref) => { const Component = as; - return ; + return ( + + ); }, ); @@ -104,11 +110,18 @@ CardTitle.displayName = "CardTitle"; * * Description text for a card, typically placed below the title. */ -export const CardDescription = forwardRef( - ({ className, ...props }, ref) => { - return

; - }, -); +export const CardDescription = forwardRef< + HTMLParagraphElement, + CardDescriptionProps +>(({ className, ...props }, ref) => { + return ( +

+ ); +}); CardDescription.displayName = "CardDescription"; diff --git a/packages/ui/src/Card/variants.ts b/packages/ui/src/Card/variants.ts index 3499ef8..115e98b 100644 --- a/packages/ui/src/Card/variants.ts +++ b/packages/ui/src/Card/variants.ts @@ -28,7 +28,10 @@ export const cardVariants = createVariants({ "shadow-md", ].join(" "), - outline: ["border-2 border-dotted border-border", "bg-transparent text-foreground"].join(" "), + outline: [ + "border-2 border-dotted border-border", + "bg-transparent text-foreground", + ].join(" "), blueprint: [ "border border-dotted border-border", @@ -82,7 +85,10 @@ export const cardHeaderVariants = createVariants({ * CardTitle variant definitions */ export const cardTitleVariants = createVariants({ - base: ["text-2xl font-semibold leading-none tracking-tight", "text-foreground"].join(" "), + base: [ + "text-2xl font-semibold leading-none tracking-tight", + "text-foreground", + ].join(" "), variants: {}, diff --git a/packages/ui/src/CodeBlock/CodeBlock.test.tsx b/packages/ui/src/CodeBlock/CodeBlock.test.tsx index c8407af..d6297cd 100644 --- a/packages/ui/src/CodeBlock/CodeBlock.test.tsx +++ b/packages/ui/src/CodeBlock/CodeBlock.test.tsx @@ -50,7 +50,13 @@ describe("CodeBlock", () => { describe("Language", () => { it("sets data-language attribute", () => { - render(); + render( + , + ); const codeblock = screen.getByTestId("codeblock"); const code = codeblock.querySelector("code"); expect(code).toHaveAttribute("data-language", "javascript"); @@ -71,7 +77,9 @@ describe("CodeBlock", () => { let code = codeblock.querySelector("code"); expect(code).toHaveAttribute("data-language", "python"); - rerender(); + rerender( + , + ); codeblock = screen.getByTestId("codeblock"); code = codeblock.querySelector("code"); expect(code).toHaveAttribute("data-language", "bash"); @@ -215,8 +223,12 @@ describe("CodeBlock", () => { }); it("handles clipboard API errors gracefully", async () => { - const consoleErrorSpy = vi.spyOn(console, "error").mockImplementation(() => {}); - mockClipboard.writeText.mockRejectedValueOnce(new Error("Clipboard not available")); + const consoleErrorSpy = vi + .spyOn(console, "error") + .mockImplementation(() => {}); + mockClipboard.writeText.mockRejectedValueOnce( + new Error("Clipboard not available"), + ); try { render(); @@ -237,13 +249,17 @@ describe("CodeBlock", () => { describe("HTML Attributes", () => { it("passes through id attribute", () => { - render(); + render( + , + ); const codeblock = screen.getByTestId("codeblock"); expect(codeblock).toHaveAttribute("id", "codeblock-id"); }); it("passes through data attributes", () => { - render(); + render( + , + ); const codeblock = screen.getByTestId("codeblock"); expect(codeblock).toHaveAttribute("data-custom", "test"); }); @@ -251,7 +267,13 @@ describe("CodeBlock", () => { describe("Custom className", () => { it("merges custom className with variant classes", () => { - render(); + render( + , + ); const codeblock = screen.getByTestId("codeblock"); expect(codeblock.className).toContain("custom-class"); expect(codeblock.className).toContain("bg-background"); @@ -271,7 +293,7 @@ describe("CodeBlock", () => { />, ); expect(ref).toBeInstanceOf(HTMLDivElement); - expect(ref?.querySelector("code")).toBeInTheDocument(); + expect(ref!.querySelector("code")).toBeInTheDocument(); }); }); diff --git a/packages/ui/src/CodeBlock/CodeBlock.tsx b/packages/ui/src/CodeBlock/CodeBlock.tsx index 46585ff..50dc9e8 100644 --- a/packages/ui/src/CodeBlock/CodeBlock.tsx +++ b/packages/ui/src/CodeBlock/CodeBlock.tsx @@ -32,7 +32,17 @@ import { * ``` */ export const CodeBlock = forwardRef( - ({ className, code, language = "text", size = "md", showCopy = true, ...props }, ref) => { + ( + { + className, + code, + language = "text", + size = "md", + showCopy = true, + ...props + }, + ref, + ) => { const [copied, setCopied] = useState(false); const handleCopy = async () => { @@ -47,7 +57,11 @@ export const CodeBlock = forwardRef( }; return ( -

+
, "children"> { +export interface CodeBlockProps + extends Omit, "children"> { /** * Code content to display */ diff --git a/packages/ui/src/Container/Container.test.tsx b/packages/ui/src/Container/Container.test.tsx index db90bf2..997bc64 100644 --- a/packages/ui/src/Container/Container.test.tsx +++ b/packages/ui/src/Container/Container.test.tsx @@ -223,7 +223,7 @@ describe("Container", () => { , ); expect(ref).toBeInstanceOf(HTMLDivElement); - expect(ref?.tagName).toBe("DIV"); + expect(ref!.tagName).toBe("DIV"); }); }); diff --git a/packages/ui/src/GridContainer/GridContainer.test.tsx b/packages/ui/src/GridContainer/GridContainer.test.tsx index 92a5e2d..b863d15 100644 --- a/packages/ui/src/GridContainer/GridContainer.test.tsx +++ b/packages/ui/src/GridContainer/GridContainer.test.tsx @@ -281,7 +281,13 @@ describe("GridContainer", () => { describe("Compound Scenarios", () => { it("works with multiple variants combined", () => { render( - + Content , ); @@ -294,7 +300,12 @@ describe("GridContainer", () => { it("works with fixed columns and custom className", () => { render( - + Content , ); diff --git a/packages/ui/src/Header/Header.test.tsx b/packages/ui/src/Header/Header.test.tsx index 0dd6737..b73fca7 100644 --- a/packages/ui/src/Header/Header.test.tsx +++ b/packages/ui/src/Header/Header.test.tsx @@ -77,7 +77,11 @@ describe("Header", () => { }); it("renders ReactNode as actions", () => { - render(
Custom Actions
} />); + render( +
Custom Actions
} + />, + ); expect(screen.getByTestId("custom-actions")).toBeInTheDocument(); }); }); @@ -251,7 +255,7 @@ describe("Header", () => { />, ); expect(ref).toBeInstanceOf(HTMLElement); - expect(ref?.tagName).toBe("HEADER"); + expect(ref!.tagName).toBe("HEADER"); }); }); @@ -271,7 +275,15 @@ describe("Header", () => { describe("Compound Scenarios", () => { it("works correctly with large size and sticky", () => { - render(
); + render( +
, + ); const header = screen.getByTestId("header"); expect(header.className).toContain("h-20"); expect(header.className).toContain("px-8"); diff --git a/packages/ui/src/Header/Header.tsx b/packages/ui/src/Header/Header.tsx index 6e620f2..3acc0d7 100644 --- a/packages/ui/src/Header/Header.tsx +++ b/packages/ui/src/Header/Header.tsx @@ -1,7 +1,11 @@ import { cn } from "@tpmjs/utils/cn"; import { forwardRef } from "react"; import type { HeaderProps } from "./types"; -import { headerActionsVariants, headerTitleVariants, headerVariants } from "./variants"; +import { + headerActionsVariants, + headerTitleVariants, + headerVariants, +} from "./variants"; /** * Header component @@ -27,7 +31,18 @@ import { headerActionsVariants, headerTitleVariants, headerVariants } from "./va * ``` */ export const Header = forwardRef( - ({ className, title, actions, size = "md", sticky = false, children, ...props }, ref) => { + ( + { + className, + title, + actions, + size = "md", + sticky = false, + children, + ...props + }, + ref, + ) => { return (
( )} {children && ( -
+
{children}
)} diff --git a/packages/ui/src/Header/types.ts b/packages/ui/src/Header/types.ts index b22848c..7816818 100644 --- a/packages/ui/src/Header/types.ts +++ b/packages/ui/src/Header/types.ts @@ -3,7 +3,8 @@ import type { HTMLAttributes, ReactNode } from "react"; /** * Header component props */ -export interface HeaderProps extends Omit, "title"> { +export interface HeaderProps + extends Omit, "title"> { /** * Title/logo content for the left side */ diff --git a/packages/ui/src/Icon/Icon.test.tsx b/packages/ui/src/Icon/Icon.test.tsx index 87c6ee4..aab4a9b 100644 --- a/packages/ui/src/Icon/Icon.test.tsx +++ b/packages/ui/src/Icon/Icon.test.tsx @@ -119,7 +119,10 @@ describe("Icon", () => { render(); const icon = screen.getByTestId("icon"); const path = icon.querySelector("path"); - expect(path).toHaveAttribute("d", "M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6 1.41-1.41z"); + expect(path).toHaveAttribute( + "d", + "M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6 1.41-1.41z", + ); }); }); @@ -145,7 +148,14 @@ describe("Icon", () => { }); it("passes through aria-label", () => { - render(); + render( + , + ); const icon = screen.getByTestId("icon"); expect(icon).toHaveAttribute("aria-label", "Success"); }); @@ -169,7 +179,7 @@ describe("Icon", () => { />, ); expect(ref).toBeInstanceOf(SVGSVGElement); - expect(ref?.tagName).toBe("svg"); + expect(ref!.tagName).toBe("svg"); }); }); diff --git a/packages/ui/src/Icon/types.ts b/packages/ui/src/Icon/types.ts index 400a112..f8007f3 100644 --- a/packages/ui/src/Icon/types.ts +++ b/packages/ui/src/Icon/types.ts @@ -4,7 +4,8 @@ import type { IconName } from "./icons"; /** * Icon component props */ -export interface IconProps extends Omit, "children"> { +export interface IconProps + extends Omit, "children"> { /** * Icon to display */ diff --git a/packages/ui/src/Input/Input.test.tsx b/packages/ui/src/Input/Input.test.tsx index 44e3f6e..9d5ea4d 100644 --- a/packages/ui/src/Input/Input.test.tsx +++ b/packages/ui/src/Input/Input.test.tsx @@ -196,7 +196,9 @@ describe("Input", () => { describe("Value and onChange", () => { it("renders with initial value", () => { - render( {}} data-testid="input" />); + render( + {}} data-testid="input" />, + ); const input = screen.getByTestId("input") as HTMLInputElement; expect(input.value).toBe("test value"); }); @@ -315,7 +317,7 @@ describe("Input", () => { />, ); expect(ref).toBeInstanceOf(HTMLInputElement); - expect(ref?.tagName).toBe("INPUT"); + expect(ref!.tagName).toBe("INPUT"); }); it("can focus input through ref", () => { @@ -328,7 +330,7 @@ describe("Input", () => { data-testid="input" />, ); - ref?.focus(); + ref!.focus(); expect(screen.getByTestId("input")).toHaveFocus(); }); }); diff --git a/packages/ui/src/Input/types.ts b/packages/ui/src/Input/types.ts index f51957d..94b6ac1 100644 --- a/packages/ui/src/Input/types.ts +++ b/packages/ui/src/Input/types.ts @@ -3,7 +3,8 @@ import type { InputHTMLAttributes } from "react"; /** * Input component props */ -export interface InputProps extends Omit, "size"> { +export interface InputProps + extends Omit, "size"> { /** * Visual state of the input * @default 'default' diff --git a/packages/ui/src/Label/Label.test.tsx b/packages/ui/src/Label/Label.test.tsx index 93205bb..8afeefd 100644 --- a/packages/ui/src/Label/Label.test.tsx +++ b/packages/ui/src/Label/Label.test.tsx @@ -208,7 +208,7 @@ describe("Label", () => { , ); expect(ref).toBeInstanceOf(HTMLLabelElement); - expect(ref?.tagName).toBe("LABEL"); + expect(ref!.tagName).toBe("LABEL"); }); }); diff --git a/packages/ui/src/Label/Label.tsx b/packages/ui/src/Label/Label.tsx index b4c384a..b8e9420 100644 --- a/packages/ui/src/Label/Label.tsx +++ b/packages/ui/src/Label/Label.tsx @@ -18,7 +18,17 @@ import { labelVariants } from "./variants"; * ``` */ export const Label = forwardRef( - ({ className, size = "md", required = false, disabled = false, children, ...props }, ref) => { + ( + { + className, + size = "md", + required = false, + disabled = false, + children, + ...props + }, + ref, + ) => { return ( // biome-ignore lint/a11y/noLabelWithoutControl: This is a generic label component that can be used with htmlFor or wrap inputs