- {([
- "check",
- "x",
- "chevronDown",
- "copy",
- "externalLink",
- "github",
- "sun",
- "moon",
- ] as const).map((icon) => (
+ {(
+ [
+ "check",
+ "x",
+ "chevronDown",
+ "copy",
+ "externalLink",
+ "github",
+ "sun",
+ "moon",
+ ] as const
+ ).map((icon) => (
- size="sm"
+ size="sm"
- size="md"
+ size="md"
- size="lg"
+ size="lg"
- size="xl"
+ size="xl"
diff --git a/packages/config/biome.json b/packages/config/biome.json
index 33bac3c..d18ec6a 100644
--- a/packages/config/biome.json
+++ b/packages/config/biome.json
@@ -37,5 +37,17 @@
"trailingCommas": "es5",
"semicolons": "always"
}
- }
+ },
+ "overrides": [
+ {
+ "include": ["**/*.test.ts", "**/*.test.tsx", "**/*.spec.ts", "**/*.spec.tsx"],
+ "linter": {
+ "rules": {
+ "style": {
+ "noNonNullAssertion": "off"
+ }
+ }
+ }
+ }
+ ]
}
diff --git a/packages/config/eslint/base.js b/packages/config/eslint/base.js
index 55e8730..986566f 100644
--- a/packages/config/eslint/base.js
+++ b/packages/config/eslint/base.js
@@ -1,32 +1,44 @@
-import js from '@eslint/js';
-import tseslint from 'typescript-eslint';
-import importPlugin from 'eslint-plugin-import';
+import js from "@eslint/js";
+import importPlugin from "eslint-plugin-import";
+import tseslint from "typescript-eslint";
export default tseslint.config(
- js.configs.recommended,
- ...tseslint.configs.recommended,
- {
- plugins: {
- import: importPlugin,
- },
- rules: {
- // Module boundaries
- 'import/no-internal-modules': ['error', {
- allow: [
- '@tpmjs/ui/*/[!index]*',
- '@tpmjs/utils/*',
- '@tpmjs/types/*',
- ]
- }],
- 'import/no-restricted-paths': ['error', {
- zones: [
- { target: './packages', from: './apps' },
- { target: './packages/ui', from: './packages/utils' },
- ]
- }],
- 'import/no-anonymous-default-export': 'error',
- '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
- '@typescript-eslint/no-explicit-any': 'warn',
- },
- }
+ js.configs.recommended,
+ ...tseslint.configs.recommended,
+ {
+ plugins: {
+ import: importPlugin,
+ },
+ rules: {
+ // Module boundaries
+ "import/no-internal-modules": [
+ "error",
+ {
+ allow: [
+ "@tpmjs/ui/*/[!index]*",
+ "@tpmjs/utils/*",
+ "@tpmjs/types/*",
+ "@tpmjs/eslint-config/*",
+ "next/**",
+ "./.next/*",
+ ],
+ },
+ ],
+ "import/no-restricted-paths": [
+ "error",
+ {
+ zones: [
+ { target: "./packages", from: "./apps" },
+ { target: "./packages/ui", from: "./packages/utils" },
+ ],
+ },
+ ],
+ "import/no-anonymous-default-export": "error",
+ "@typescript-eslint/no-unused-vars": [
+ "error",
+ { argsIgnorePattern: "^_" },
+ ],
+ "@typescript-eslint/no-explicit-any": "warn",
+ },
+ },
);
diff --git a/packages/config/eslint/package.json b/packages/config/eslint/package.json
index e2e3731..e8a3b6e 100644
--- a/packages/config/eslint/package.json
+++ b/packages/config/eslint/package.json
@@ -1,19 +1,17 @@
{
- "name": "@tpmjs/eslint-config",
- "version": "0.0.0",
- "private": true,
- "main": "./base.js",
- "files": [
- "base.js",
- "react.js"
- ],
- "dependencies": {
- "@eslint/js": "^9.18.0",
- "eslint": "^9.18.0",
- "eslint-plugin-import": "^2.31.0",
- "eslint-plugin-jsx-a11y": "^6.10.2",
- "eslint-plugin-react": "^7.37.3",
- "eslint-plugin-react-hooks": "^5.1.0",
- "typescript-eslint": "^8.19.1"
- }
+ "name": "@tpmjs/eslint-config",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "main": "./base.js",
+ "files": ["base.js", "react.js"],
+ "dependencies": {
+ "@eslint/js": "^9.18.0",
+ "eslint": "^9.18.0",
+ "eslint-plugin-import": "^2.31.0",
+ "eslint-plugin-jsx-a11y": "^6.10.2",
+ "eslint-plugin-react": "^7.37.3",
+ "eslint-plugin-react-hooks": "^5.1.0",
+ "typescript-eslint": "^8.19.1"
+ }
}
diff --git a/packages/ui/eslint.config.js b/packages/ui/eslint.config.js
deleted file mode 100644
index 6219a57..0000000
--- a/packages/ui/eslint.config.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import reactConfig from '@tpmjs/eslint-config/react.js';
-
-export default reactConfig;
diff --git a/packages/ui/eslint.config.mjs b/packages/ui/eslint.config.mjs
new file mode 100644
index 0000000..d6a0cd0
--- /dev/null
+++ b/packages/ui/eslint.config.mjs
@@ -0,0 +1,28 @@
+import reactConfig from '@tpmjs/eslint-config/react.js';
+
+export default [
+ {
+ ignores: ['dist/**', 'node_modules/**', 'eslint.config.mjs']
+ },
+ ...reactConfig,
+ {
+ rules: {
+ 'import/no-internal-modules': ['error', {
+ allow: [
+ '@tpmjs/ui/*/[!index]*',
+ '@tpmjs/utils/*',
+ '@tpmjs/types/*',
+ '@tpmjs/eslint-config/*',
+ '@testing-library/**',
+ 'react/*',
+ ]
+ }],
+ }
+ },
+ {
+ files: ['**/*.test.ts', '**/*.test.tsx', '**/*.spec.ts', '**/*.spec.tsx'],
+ rules: {
+ 'jsx-a11y/no-autofocus': 'off',
+ }
+ }
+];
diff --git a/packages/ui/src/Badge/Badge.test.tsx b/packages/ui/src/Badge/Badge.test.tsx
index 8c5d9c6..33abfdf 100644
--- a/packages/ui/src/Badge/Badge.test.tsx
+++ b/packages/ui/src/Badge/Badge.test.tsx
@@ -242,7 +242,7 @@ describe("Badge", () => {
let ref: HTMLDivElement | null = null;
render(
{
+ ref={(el) => {
ref = el;
}}
>
@@ -250,7 +250,7 @@ describe("Badge", () => {
,
);
expect(ref).toBeInstanceOf(HTMLDivElement);
- expect(ref?.tagName).toBe("DIV");
+ expect(ref!.tagName).toBe("DIV");
});
});
diff --git a/packages/ui/src/Button/Button.test.tsx b/packages/ui/src/Button/Button.test.tsx
index e7d7b1e..147832d 100644
--- a/packages/ui/src/Button/Button.test.tsx
+++ b/packages/ui/src/Button/Button.test.tsx
@@ -233,7 +233,7 @@ describe("Button", () => {
let ref: HTMLButtonElement | null = null;
render(
,
);
expect(ref).toBeInstanceOf(HTMLButtonElement);
- expect(ref?.tagName).toBe("BUTTON");
+ expect(ref!.tagName).toBe("BUTTON");
});
});
diff --git a/packages/ui/src/Card/Card.test.tsx b/packages/ui/src/Card/Card.test.tsx
index 599d791..3696eae 100644
--- a/packages/ui/src/Card/Card.test.tsx
+++ b/packages/ui/src/Card/Card.test.tsx
@@ -74,7 +74,7 @@ describe("Card", () => {
);
const card = screen.getByTestId("card");
expect(card.className).toContain("border-dotted");
- expect(card.className).toContain("border-2");
+ expect(card.className).toContain("border-2");
expect(card.className).toContain("bg-transparent");
});
@@ -409,7 +409,7 @@ describe("Card", () => {
let ref: HTMLDivElement | null = null;
render(
{
+ ref={(el) => {
ref = el;
}}
>
@@ -417,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", () => {
@@ -425,7 +425,7 @@ describe("Card", () => {
render(
{
+ ref={(el) => {
ref = el;
}}
>
@@ -442,7 +442,7 @@ describe("Card", () => {
{
+ ref={(el) => {
ref = el;
}}
>
@@ -452,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", () => {
@@ -461,7 +461,7 @@ describe("Card", () => {
{
+ ref={(el) => {
ref = el;
}}
>
@@ -478,7 +478,7 @@ describe("Card", () => {
render(
{
+ ref={(el) => {
ref = el;
}}
>
@@ -494,7 +494,7 @@ describe("Card", () => {
render(
{
+ ref={(el) => {
ref = el;
}}
>
diff --git a/packages/ui/src/Card/types.ts b/packages/ui/src/Card/types.ts
index d5d41aa..833f422 100644
--- a/packages/ui/src/Card/types.ts
+++ b/packages/ui/src/Card/types.ts
@@ -42,8 +42,7 @@ export interface CardTitleProps extends HTMLAttributes {
/**
* CardDescription component props
*/
-export interface CardDescriptionProps
- extends HTMLAttributes {}
+export type CardDescriptionProps = HTMLAttributes;
/**
* CardContent component props
diff --git a/packages/ui/src/CodeBlock/CodeBlock.test.tsx b/packages/ui/src/CodeBlock/CodeBlock.test.tsx
index e2697ee..d6297cd 100644
--- a/packages/ui/src/CodeBlock/CodeBlock.test.tsx
+++ b/packages/ui/src/CodeBlock/CodeBlock.test.tsx
@@ -287,13 +287,13 @@ describe("CodeBlock", () => {
render(
{
+ ref={(el) => {
ref = el;
}}
/>,
);
expect(ref).toBeInstanceOf(HTMLDivElement);
- expect(ref?.querySelector("code")).toBeInTheDocument();
+ expect(ref!.querySelector("code")).toBeInTheDocument();
});
});
diff --git a/packages/ui/src/Container/Container.test.tsx b/packages/ui/src/Container/Container.test.tsx
index 5606d99..997bc64 100644
--- a/packages/ui/src/Container/Container.test.tsx
+++ b/packages/ui/src/Container/Container.test.tsx
@@ -215,7 +215,7 @@ describe("Container", () => {
let ref: HTMLDivElement | null = null;
render(
{
+ ref={(el) => {
ref = el;
}}
>
@@ -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 df79d4e..b863d15 100644
--- a/packages/ui/src/GridContainer/GridContainer.test.tsx
+++ b/packages/ui/src/GridContainer/GridContainer.test.tsx
@@ -258,7 +258,7 @@ describe("GridContainer", () => {
let ref: HTMLDivElement | null = null;
render(
{
+ ref={(el) => {
ref = el;
}}
>
diff --git a/packages/ui/src/Header/Header.test.tsx b/packages/ui/src/Header/Header.test.tsx
index 0ffbe73..b73fca7 100644
--- a/packages/ui/src/Header/Header.test.tsx
+++ b/packages/ui/src/Header/Header.test.tsx
@@ -249,13 +249,13 @@ describe("Header", () => {
let ref: HTMLElement | null = null;
render(
{
+ ref={(el) => {
ref = el;
}}
/>,
);
expect(ref).toBeInstanceOf(HTMLElement);
- expect(ref?.tagName).toBe("HEADER");
+ expect(ref!.tagName).toBe("HEADER");
});
});
diff --git a/packages/ui/src/Icon/Icon.test.tsx b/packages/ui/src/Icon/Icon.test.tsx
index bf43a6c..aab4a9b 100644
--- a/packages/ui/src/Icon/Icon.test.tsx
+++ b/packages/ui/src/Icon/Icon.test.tsx
@@ -179,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/Input/Input.test.tsx b/packages/ui/src/Input/Input.test.tsx
index e00c0cd..9d5ea4d 100644
--- a/packages/ui/src/Input/Input.test.tsx
+++ b/packages/ui/src/Input/Input.test.tsx
@@ -311,26 +311,26 @@ describe("Input", () => {
let ref: HTMLInputElement | null = null;
render(
{
+ ref={(el) => {
ref = el;
}}
/>,
);
expect(ref).toBeInstanceOf(HTMLInputElement);
- expect(ref?.tagName).toBe("INPUT");
+ expect(ref!.tagName).toBe("INPUT");
});
it("can focus input through ref", () => {
let ref: HTMLInputElement | null = null;
render(
{
+ ref={(el) => {
ref = el;
}}
data-testid="input"
/>,
);
- ref?.focus();
+ ref!.focus();
expect(screen.getByTestId("input")).toHaveFocus();
});
});
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/ProgressBar/ProgressBar.test.tsx b/packages/ui/src/ProgressBar/ProgressBar.test.tsx
index b52fc1a..7d13405 100644
--- a/packages/ui/src/ProgressBar/ProgressBar.test.tsx
+++ b/packages/ui/src/ProgressBar/ProgressBar.test.tsx
@@ -221,7 +221,7 @@ describe("ProgressBar", () => {
render(
{
+ ref={(el) => {
ref = el;
}}
/>,
diff --git a/packages/ui/src/Section/Section.test.tsx b/packages/ui/src/Section/Section.test.tsx
index bbddb5f..3990e4e 100644
--- a/packages/ui/src/Section/Section.test.tsx
+++ b/packages/ui/src/Section/Section.test.tsx
@@ -284,7 +284,7 @@ describe("Section", () => {
let ref: HTMLElement | null = null;
render(
{
+ ref={(el) => {
ref = el;
}}
>
@@ -292,7 +292,7 @@ describe("Section", () => {
,
);
expect(ref).toBeInstanceOf(HTMLElement);
- expect(ref?.tagName).toBe("SECTION");
+ expect(ref!.tagName).toBe("SECTION");
});
});
diff --git a/packages/ui/src/Tabs/Tabs.test.tsx b/packages/ui/src/Tabs/Tabs.test.tsx
index f0b11ba..49cb311 100644
--- a/packages/ui/src/Tabs/Tabs.test.tsx
+++ b/packages/ui/src/Tabs/Tabs.test.tsx
@@ -370,7 +370,7 @@ describe("Tabs", () => {
tabs={mockTabs}
activeTab="all"
onTabChange={handleChange}
- ref={(el: HTMLDivElement | null) => {
+ ref={(el) => {
ref = el;
}}
/>,