Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
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
9 changes: 9 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
root = true

[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
6 changes: 0 additions & 6 deletions .eslintrc.ts-next.json

This file was deleted.

6 changes: 0 additions & 6 deletions .eslintrc.ts-react.json

This file was deleted.

6 changes: 0 additions & 6 deletions .eslintrc.ts.json

This file was deleted.

25 changes: 25 additions & 0 deletions configs/formatjs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { defineConfig } from 'eslint/config'
import formatjsPlugin from 'eslint-plugin-formatjs'
import jsonc from 'eslint-plugin-jsonc'

export default defineConfig([
{
files: ['**/*.{js,cjs,mjs,jsx,ts,tsx}'],
plugins: {
formatjs: formatjsPlugin,
},
rules: {
'formatjs/enforce-placeholders': 'error',
'formatjs/no-multiple-whitespaces': 'error',
'formatjs/enforce-id': 'error',
},
},
{
files: ['**/translations/*.json'],
language: 'json/json',
plugins: { jsonc },
rules: {
'jsonc/sort-keys': 'error',
},
},
])
9 changes: 9 additions & 0 deletions configs/jest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { defineConfig } from 'eslint/config'
import jestPlugin from 'eslint-plugin-jest'

export default defineConfig([
{
files: ['**/*.{js,cjs,mjs,jsx,ts,tsx}'],
...jestPlugin.configs['flat/recommended'],
},
])
39 changes: 39 additions & 0 deletions configs/next.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { dirname } from 'path'
import { fileURLToPath } from 'url'
import { FlatCompat } from '@eslint/eslintrc'
import { defineConfig } from 'eslint/config'

const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)

const compat = new FlatCompat({
baseDirectory: __dirname,
})

export default defineConfig([
// coreWebVitals includes Next recommended rules
...compat.extends('plugin:@next/next/core-web-vitals'),
{
files: ['**/*.{js,cjs,mjs,jsx,ts,tsx}'],
rules: {
'@next/next/no-img-element': 'off',
},
},
])

// Alternative/modern approach:
// Working, but has some issues with the Next lint command (running with `next build`).
// This approach can probably be used with Next 16, as they removed Next lint completely.
//
// import next from '@next/eslint-plugin-next'
// import { defineConfig } from 'eslint/config'
// export default defineConfig([
// {
// files: ['**/*.{js,cjs,mjs,jsx,ts,tsx}'],
// // coreWebVitals includes Next recommended rules
// ...next.flatConfig.coreWebVitals,
// rules: {
// '@next/next/no-img-element': 'off',
// },
// },
// ])
44 changes: 44 additions & 0 deletions configs/react.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { defineConfig } from 'eslint/config'
import jsxA11y from 'eslint-plugin-jsx-a11y'
import reactPlugin from 'eslint-plugin-react'
import reactHooks from 'eslint-plugin-react-hooks'

export default defineConfig([
{
languageOptions: {
parserOptions: {
ecmaFeatures: {
jsx: true,
},
},
},
files: ['**/*.{js,cjs,mjs,jsx,ts,tsx}'],
extends: [
reactPlugin.configs.flat.recommended,
reactPlugin.configs.flat['jsx-runtime'],
reactHooks.configs['recommended-latest'],
jsxA11y.flatConfigs.strict,
],
settings: {
react: {
version: 'detect',
},
},
rules: {
'react/jsx-curly-brace-presence': [
'error',
{ props: 'never', children: 'never', propElementValues: 'always' },
],
'react/self-closing-comp': [
'error',
{
component: true,
html: true,
},
],
'react-hooks/rules-of-hooks': 'error',
'react-hooks/exhaustive-deps': 'error',
'jsx-a11y/no-autofocus': 'off',
},
},
])
27 changes: 27 additions & 0 deletions configs/storybook.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { defineConfig } from 'eslint/config'
import * as mdx from 'eslint-plugin-mdx'
import storybook from 'eslint-plugin-storybook'
import { configs as tseslintConfigs } from 'typescript-eslint'

export default defineConfig([
{
files: ['**/*.{js,cjs,mjs,jsx,ts,tsx}'],
extends: [storybook.configs['flat/recommended']],
},
{
ignores: ['!.storybook'],
},
{
...mdx.flat,
processor: mdx.createRemarkProcessor({
lintCodeBlocks: false, // Disable linting of code blocks as it shows irrelevant errors.
}),
},
{
...mdx.flatCodeBlocks,
extends: [tseslintConfigs.disableTypeChecked],
rules: {
'import/no-unresolved': 'off',
},
},
])
66 changes: 66 additions & 0 deletions configs/tailwind.js
Comment thread
lukasvice marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { defineConfig } from 'eslint/config'
import eslintPluginBetterTailwindcss from 'eslint-plugin-better-tailwindcss'
import {
getDefaultCallees,
getDefaultVariables,
} from 'eslint-plugin-better-tailwindcss/api/defaults'

export default defineConfig([
{
files: ['**/*.{js,cjs,mjs,jsx,ts,tsx}'],
plugins: {
'better-tailwindcss': eslintPluginBetterTailwindcss,
},
rules: {
// Recommended rules
...eslintPluginBetterTailwindcss.configs['recommended-error'].rules,

// Configure rules
'better-tailwindcss/enforce-consistent-line-wrapping': ['off'], // This rule is not compatible with prettier
'better-tailwindcss/enforce-consistent-class-order': [
'error',
{
// Use official Tailwind CSS class order to be in line with the Prettier plugin
order: 'official',
},
],

// Additional rules
'better-tailwindcss/enforce-consistent-variable-syntax': ['error'],
'better-tailwindcss/enforce-consistent-important-position': ['error'],
'better-tailwindcss/enforce-shorthand-classes': ['error'],
'better-tailwindcss/no-deprecated-classes': ['error'],
'better-tailwindcss/no-conflicting-classes': ['error'],
},
settings: {
'better-tailwindcss': {
callees: [
...getDefaultCallees(),
[
'classNames',
[
{ match: 'strings' },
{
match: 'objectKeys',
pathPattern: '.*',
},
{
match: 'objectValues',
pathPattern: '.*',
},
],
],
],
variables: [...getDefaultVariables(), '.*ClassNames?$'],
},
},
/*
settings: {
'better-tailwindcss': {
// Entrypoint for Tailwind CSS 4
entryPoint: 'styles/index.css',
},
},
*/
},
])
113 changes: 113 additions & 0 deletions configs/ts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import eslint from '@eslint/js'
import json from '@eslint/json'
import { defineConfig } from 'eslint/config'
import importPlugin from 'eslint-plugin-import'
import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended'
import globals from 'globals'
import { configs as tseslintConfigs } from 'typescript-eslint'

export default defineConfig([
{
files: ['**/*.{js,mjs,cjs,ts,jsx,tsx}'],
languageOptions: {
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname,
},
globals: {
...globals.browser,
...globals.node,
},
},
extends: [
eslint.configs.recommended,
tseslintConfigs.strictTypeChecked,
tseslintConfigs.stylisticTypeChecked,
importPlugin.flatConfigs.recommended,
importPlugin.flatConfigs.typescript,
eslintPluginPrettierRecommended,
],
settings: {
'import/resolver': {
typescript: true,
node: true,
},
},
rules: {
'@typescript-eslint/no-unused-vars': [
'error',
{
argsIgnorePattern: '^_',
varsIgnorePattern: '^_',
caughtErrorsIgnorePattern: '^_',
destructuredArrayIgnorePattern: '^_',
},
],
'@typescript-eslint/consistent-type-definitions': ['error', 'type'],
'@typescript-eslint/restrict-template-expressions': [
'error',
{
allowNumber: true,
allowAny: false,
allowNullish: false,
allowBoolean: false,
allowRegExp: false,
allowNever: false,
},
],
'@typescript-eslint/member-delimiter-style': 'off',
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/no-deprecated': 'warn',
'import/order': [
'error',
{
groups: [
'builtin',
'external',
'internal',
'unknown',
'parent',
'sibling',
'index',
'object',
'type',
],
alphabetize: {
order: 'asc',
orderImportKind: 'asc',
caseInsensitive: true,
},
'newlines-between': 'never',
warnOnUnassignedImports: true,
},
],
'sort-imports': [
'error',
{
ignoreDeclarationSort: true,
},
],
'no-console': [
'error',
{
allow: ['warn', 'error', 'assert'],
},
],
'no-implicit-coercion': 'error',
curly: ['error', 'all'],
'object-shorthand': ['error'],
eqeqeq: 'error',
},
},
{
files: ['**/*.{js,mjs,cjs,jsx}'],
extends: [tseslintConfigs.disableTypeChecked],
},
{
files: ['**/*.json'],
ignores: ['package-lock.json'],
plugins: { json },
language: 'json/json',
extends: [eslintPluginPrettierRecommended, json.configs.recommended],
},
])
9 changes: 9 additions & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { defineConfig } from 'eslint/config'
import ts from './configs/ts.js'

export default defineConfig([
ts,
{
ignores: ['node_modules'],
},
])
9 changes: 0 additions & 9 deletions formatjs.js

This file was deleted.

Loading