Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
3ade323
refactor: πŸ’‘ make eslint config root-level
punkbit Mar 27, 2026
8511f1e
refactor: πŸ’‘ make tsconfig base
punkbit Mar 27, 2026
a788d8e
refactor: πŸ’‘ root-level tsconfig for eslint
punkbit Mar 27, 2026
b922b20
fix: πŸ› Removed the non-functional references array
punkbit Mar 27, 2026
74d62f2
fix: πŸ› remove duplicate prettier version
punkbit Mar 27, 2026
31f9637
chore: πŸ€– exclude non eslint packages
punkbit Mar 27, 2026
76d3e40
refactor: πŸ’‘ shared eslint config
punkbit Mar 27, 2026
faa3f91
fix: πŸ› missing type def
punkbit Mar 27, 2026
ce767c5
refactor: πŸ’‘ convert the eslint root-level config a typescript file
punkbit Mar 27, 2026
3fc9993
refactor: πŸ’‘ move click-ui specific eslint rules
punkbit Mar 27, 2026
3b007a8
fix: πŸ› type errors, e.g. Using Record<string, unknown> as the type an…
punkbit Mar 27, 2026
1270a82
fix: πŸ› Using Linter.RulesRecord from eslint provides the correct type…
punkbit Mar 27, 2026
8443376
refactor: πŸ’‘ React/Storybook plugins should be added at
punkbit Mar 27, 2026
e8ab91b
chore: πŸ€– add comment
punkbit Mar 27, 2026
8f24d86
chore: πŸ€– remove comment
punkbit Mar 27, 2026
fb80f48
refactor: πŸ’‘ root-level tsconfig.eslint doesnt need a includes
punkbit Mar 27, 2026
b43d4e5
refactor: πŸ’‘ move click ui specific eslint packages
punkbit Mar 27, 2026
548f696
chore: πŸ€– tsconfig.eslint default include set to eslint.config.ts
punkbit Mar 27, 2026
af27131
refactor: πŸ’‘ add local configs and extend to follow convention
punkbit Mar 27, 2026
6b7a58d
chore: πŸ€– update lockfile
punkbit Apr 2, 2026
f6c22c1
fix: πŸ› remove redundant @typescript-eslint/eslint-plugin (bundled in …
punkbit Apr 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 91 additions & 0 deletions eslint.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/**
* Shared ESLint configuration for TypeScript packages.
*
* Important:
* - Packages should create their own eslint.config.ts that imports and extends this.
* - React/Storybook-specific plugins and rules should be added at the package level.
*
* Excluded packages (using alternative linters):
* - design-tokens: uses Terrazzo's linter (tz lint)
*/
import js from '@eslint/js';
import tseslint from 'typescript-eslint';
import preferArrowFunctions from 'eslint-plugin-prefer-arrow-functions';
import importPlugin from 'eslint-plugin-import';
import globals from 'globals';
import type { Linter } from 'eslint';

export const ignores = {
ignores: [
'**/dist/**',
'**/node_modules/**',
'**/build/**',
'**/coverage/**',
'**/*.d.ts',
],
};

export const baseConfigs = [js.configs.recommended, ...tseslint.configs.recommended];

export const plugins = {
'prefer-arrow-functions': preferArrowFunctions,
import: importPlugin,
};

export const sharedLanguageOptions = {
ecmaVersion: 'latest' as const,
sourceType: 'module' as const,
parser: tseslint.parser,
parserOptions: {
ecmaFeatures: {
jsx: true,
},
},
globals: {
...globals.browser,
...globals.es2020,
},
};

export const sharedRules: Linter.RulesRecord = {
curly: ['error', 'all'],
'no-multiple-empty-lines': 'error',
quotes: ['error', 'single', { avoidEscape: true }],
'arrow-parens': ['error', 'as-needed'],
'prefer-arrow-functions/prefer-arrow-functions': [
'warn',
{
classPropertiesAllowed: false,
disallowPrototype: false,
returnStyle: 'unchanged',
singleReturnOnly: false,
},
],
'@typescript-eslint/no-empty-object-type': 'off',
'import/extensions': [
'error',
'ignorePackages',
{
js: 'never',
jsx: 'never',
ts: 'never',
tsx: 'never',
},
],
'import/no-cycle': [
'error',
{
maxDepth: 10,
ignoreExternal: true,
allowUnsafeDynamicCyclicDependency: false,
},
],
'import/no-self-import': 'error',
'@typescript-eslint/no-deprecated': 'warn',
};

export const testFileRules: Linter.RulesRecord = {
'@typescript-eslint/no-unused-expressions': 'off',
};

export { tseslint };
11 changes: 10 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"name": "click-ui-monorepo",
"private": true,
"type": "module",
"workspaces": [
"packages/*"
],
Expand All @@ -19,7 +20,15 @@
"prepare": "husky"
},
"devDependencies": {
"husky": "^9.1.7"
"eslint": "^9",
"eslint-import-resolver-typescript": "^4.4.4",
"eslint-plugin-import": "^2.32.0",
"eslint-plugin-prefer-arrow-functions": "^3.3.2",
"globals": "^16.5.0",
"husky": "^9.1.7",
"jiti": "^2.4.0",
"prettier": "^3.7.4",
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Root prettier was changed to a caret range (^3.7.4), which is already resolving to 3.8.1 in yarn.lock. Since formatting consistency is the goal of this PR (and @clickhouse/click-ui previously pinned Prettier), consider pinning Prettier to an exact version (or adding a Yarn resolution) to avoid formatting diffs when new minor versions are released.

Suggested change
"prettier": "^3.7.4",
"prettier": "3.8.1",

Copilot uses AI. Check for mistakes.
"typescript-eslint": "^8"
},
"resolutions": {
"@types/react": "18.3.1",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,82 +1,53 @@
import js from '@eslint/js';
import tseslint from 'typescript-eslint';
import {
ignores,
baseConfigs,
plugins,
sharedLanguageOptions,
sharedRules,
testFileRules,
tseslint,
} from '../../eslint.config.ts';
import reactHooks from 'eslint-plugin-react-hooks';
import reactRefresh from 'eslint-plugin-react-refresh';
import preferArrowFunctions from 'eslint-plugin-prefer-arrow-functions';
import storybook from 'eslint-plugin-storybook';
import importPlugin from 'eslint-plugin-import';
import globals from 'globals';

export default tseslint.config(
ignores,
...baseConfigs,
{
ignores: ['dist/**', 'node_modules/**', 'build/**', 'coverage/**', '**/*.d.ts'],
},
js.configs.recommended,
...tseslint.configs.recommended,
{
files: ['**/*.{ts,tsx}'],
files: ['src/**/*.{ts,tsx}'],
languageOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
parser: tseslint.parser,
...sharedLanguageOptions,
parserOptions: {
project: './tsconfig.json',
...sharedLanguageOptions.parserOptions,
project: './tsconfig.eslint.json',
tsconfigRootDir: import.meta.dirname,
ecmaFeatures: {
jsx: true,
},
},
globals: {
...globals.browser,
...globals.es2020,
},
},
plugins: {
...plugins,
'react-hooks': reactHooks,
'react-refresh': reactRefresh,
'prefer-arrow-functions': preferArrowFunctions,
storybook: storybook,
import: importPlugin,
},
settings: {
'import/resolver': {
typescript: true,
typescript: {
project: './tsconfig.eslint.json',
},
node: true,
},
},
rules: {
...sharedRules,
...reactHooks.configs.recommended.rules,
curly: ['error', 'all'],
'react-refresh/only-export-components': 'warn',
'no-multiple-empty-lines': 'error',
quotes: ['error', 'single', { avoidEscape: true }],
'arrow-parens': ['error', 'as-needed'],
'prefer-arrow-functions/prefer-arrow-functions': [
'warn',
{
classPropertiesAllowed: false,
disallowPrototype: false,
returnStyle: 'unchanged',
singleReturnOnly: false,
},
],
'react-hooks/exhaustive-deps': [
'warn',
{
additionalHooks: '(useUpdateEffect)',
},
],
'@typescript-eslint/no-empty-object-type': 'off',
'import/extensions': [
'error',
'ignorePackages',
{
js: 'never',
jsx: 'never',
ts: 'never',
tsx: 'never',
},
],
'no-restricted-imports': [
'error',
{
Expand Down Expand Up @@ -106,24 +77,11 @@ export default tseslint.config(
],
},
],
'import/no-cycle': [
'error',
{
maxDepth: 10,
ignoreExternal: true,
allowUnsafeDynamicCyclicDependency: false,
},
],
'import/no-self-import': 'error',
'@typescript-eslint/no-deprecated': 'warn',
},
},
// Special config for test files
{
files: ['**/*.test.{ts,tsx}', '**/*.spec.{ts,tsx}'],
rules: {
'@typescript-eslint/no-unused-expressions': 'off',
},
files: ['src/**/*.test.{ts,tsx}', 'src/**/*.spec.{ts,tsx}'],
rules: testFileRules,
},
...storybook.configs['flat/recommended']
);
23 changes: 10 additions & 13 deletions packages/click-ui/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@clickhouse/click-ui",
"version": "0.2.0-test.0",
"version": "0.0.252-test.7",
"description": "Official ClickHouse design system react library",
"type": "module",
"license": "Apache-2.0",
Expand Down Expand Up @@ -371,12 +371,12 @@
"convert:payment": ".scripts/js/convert-svg-to-react-component --type=payments",
"convert:regenerate": ".scripts/js/convert-svg-to-react-component --regenerate",
"dev": "yarn storybook",
"format": ".scripts/bash/format",
"format:fix": ".scripts/bash/format --write",
"format": "yarn run -T prettier --check \"src/**/*.{js,jsx,ts,tsx}\"",
"format:fix": "yarn run -T prettier --write \"src/**/*.{js,jsx,ts,tsx}\"",
"generate:exports": ".scripts/js/generate-exports",
"generate:tokens": "node ./.scripts/js/generate-tokens.js && yarn format:fix src/theme/tokens/**/*.ts",
"lint": "eslint src --report-unused-disable-directives",
"lint:fix": "eslint src --report-unused-disable-directives --fix",
"generate:tokens": "node ./.scripts/js/generate-tokens.js && yarn run -T prettier --write \"src/theme/tokens/**/*.ts\"",
"lint": "yarn run -T eslint src --report-unused-disable-directives",
"lint:fix": "yarn run -T eslint src --report-unused-disable-directives --fix",
"prettify": "yarn format:fix",
"preview": "vite preview",
"storybook": "storybook dev -p 6006",
Expand Down Expand Up @@ -443,16 +443,10 @@
"babel-plugin-styled-components": "^2.1.4",
"chromatic": "^13.3.4",
"date-fns": "4.1.0",
"eslint": "^9",
"eslint-import-resolver-typescript": "^4.4.4",
"eslint-plugin-import": "^2.32.0",
"eslint-plugin-prefer-arrow-functions": "^3.3.2",
"eslint-plugin-react-hooks": "^5",
"eslint-plugin-react-refresh": "0.4.7",
"eslint-plugin-storybook": "^10.1.10",
"globals": "^16.5.0",
"jsdom": "^24.0.0",
"prettier": "3.7.4",
"prop-types": "^15.8.1",
"react": "18.3.1",
"react-dom": "18.3.1",
Expand All @@ -464,7 +458,6 @@
"stylis": "^4.3.0",
"ts-node": "^10.9.1",
"typescript": "^5.5.3",
"typescript-eslint": "^8",
"vite": "^7.3.0",
"vite-plugin-dts": "^4.3.0",
"vite-plugin-externalize-deps": "^0.10.0",
Expand All @@ -482,5 +475,9 @@
"@types/react": "18.3.1",
"@types/react-dom": "18.3.1",
"styled-components": "6.1.11"
},
"packageManager": "yarn@4.5.3",
"engines": {
"node": ">=22.12.0"
}
}
10 changes: 10 additions & 0 deletions packages/click-ui/tsconfig.eslint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"extends": "../../tsconfig.eslint.json",
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["src/*"]
}
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tsconfig.eslint.json is now the parserOptions.project for ESLint, but it doesn’t include the test/global typings used in src/**/*.test.tsx (e.g. describe, it, expect, vi from vitest/globals). This can degrade type-aware linting and can surface TypeScript semantic diagnostics during lint runs. Consider adding the same compilerOptions.types as tsconfig.json (e.g. vitest/globals, @testing-library/jest-dom) or extending from tsconfig.json and overriding only include/exclude.

Suggested change
}
},
"types": ["vitest/globals", "@testing-library/jest-dom"]

Copilot uses AI. Check for mistakes.
},
"include": ["src/**/*.ts", "src/**/*.tsx"]
}
23 changes: 2 additions & 21 deletions packages/click-ui/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,33 +1,14 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"target": "ESNext",
"esModuleInterop": true,
"lib": ["DOM", "DOM.Iterable", "ESNext"],
"module": "ESNext",
"skipLibCheck": true,

/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",

/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"paths": {
"@/*": ["./src/*"],
"@/*": ["./src/*"]
},
"types": ["@testing-library/jest-dom", "vitest/globals"]
},
"include": ["src"],
"exclude": [
"node_modules",
"dist",
],
"references": [{ "path": "./tsconfig.node.json" }]
}
18 changes: 2 additions & 16 deletions packages/design-tokens/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,18 +1,4 @@
{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "bundler",
"esModuleInterop": true,
"skipLibCheck": true,
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true
},
"include": ["*.ts"],
"exclude": ["node_modules", "dist"]
"extends": "../../tsconfig.base.json",
"include": ["*.ts"]
}
17 changes: 17 additions & 0 deletions tsconfig.base.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "bundler",
"esModuleInterop": true,
"skipLibCheck": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
},
"exclude": ["node_modules", "dist"]
}
Loading
Loading