| /*! |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| import js from "@eslint/js"; |
| import globals from "globals"; |
| import perfectionist from "eslint-plugin-perfectionist"; |
| import reactHooks from "eslint-plugin-react-hooks"; |
| import reactRefresh from "eslint-plugin-react-refresh"; |
| import tseslint from "typescript-eslint"; |
| import prettierConfig from "eslint-config-prettier"; |
| |
| export default tseslint.config( |
| { ignores: ["dist"] }, |
| { |
| extends: [js.configs.recommended, ...tseslint.configs.recommended], |
| files: ["**/*.{ts,tsx}"], |
| languageOptions: { |
| ecmaVersion: "latest", |
| globals: globals.browser, |
| }, |
| plugins: { |
| perfectionist, |
| "react-hooks": reactHooks, |
| "react-refresh": reactRefresh, |
| }, |
| rules: { |
| ...reactHooks.configs.recommended.rules, |
| // `@types/react` declares `export as namespace React`, so `React.ReactNode` |
| // type-checks even without an import — only a syntax rule catches those. |
| "@typescript-eslint/no-restricted-imports": [ |
| "error", |
| { |
| paths: [ |
| { |
| importNames: ["default"], |
| message: |
| 'The automatic JSX runtime makes the React namespace import unnecessary. Import what you need by name, e.g. `import { forwardRef, type ReactNode } from "react"`.', |
| name: "react", |
| }, |
| ], |
| }, |
| ], |
| "no-restricted-syntax": [ |
| "error", |
| { |
| message: |
| "Do not type components with `React.FC`. Annotate the props parameter instead: `const Foo = ({ bar }: FooProps) => ...`.", |
| selector: "TSQualifiedName[left.name='React'][right.name=/^(FC|FunctionComponent|VFC)$/]", |
| }, |
| { |
| message: |
| "Do not type components with `FC`. Annotate the props parameter instead: `const Foo = ({ bar }: FooProps) => ...`.", |
| selector: |
| "VariableDeclarator[init.type='ArrowFunctionExpression'] > Identifier > TSTypeAnnotation > TSTypeReference > Identifier[name=/^(FC|FunctionComponent|VFC)$/]", |
| }, |
| { |
| message: |
| 'Import React types by name instead of qualifying them with the `React` namespace: `import { type ReactElement } from "react"`, then use `ReactElement`.', |
| selector: "TSQualifiedName[left.name='React']:not([right.name=/^(FC|FunctionComponent|VFC)$/])", |
| }, |
| ], |
| "perfectionist/sort-objects": [ |
| "error", |
| { |
| type: "natural", |
| order: "asc", |
| }, |
| ], |
| "react-refresh/only-export-components": [ |
| "warn", |
| { allowConstantExport: true }, |
| ], |
| }, |
| }, |
| prettierConfig |
| ); |