Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
8 changes: 8 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ updates:
time: '21:00'
timezone: Asia/Shanghai
open-pull-requests-limit: 10
groups:
npm-dependencies:
patterns:
- '*'

- package-ecosystem: github-actions
directory: '/'
Expand All @@ -17,3 +21,7 @@ updates:
time: '21:00'
timezone: Asia/Shanghai
open-pull-requests-limit: 10
groups:
github-actions:
patterns:
- '*'
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<div align="center">
<h1>@rc-component/progress</h1>
<p><sub><img alt="Ant Design" height="14" src="https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg" style="vertical-align: -0.125em;" /> Part of the Ant Design ecosystem.</sub></p>
<p><sub><a href="https://ant.design"><img alt="Ant Design" height="14" src="https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg" style="vertical-align: -0.125em;" /></a> Part of the Ant Design ecosystem.</sub></p>
<p>📊 Lightweight React line and circle progress indicators with SVG rendering.</p>

<p>
Expand Down
2 changes: 1 addition & 1 deletion README.zh-CN.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<div align="center">
<h1>@rc-component/progress</h1>
<p><sub><img alt="Ant Design" height="14" src="https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg" style="vertical-align: -0.125em;" /> Ant Design 生态的一部分。</sub></p>
<p><sub><a href="https://ant.design"><img alt="Ant Design" height="14" src="https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg" style="vertical-align: -0.125em;" /></a> Ant Design 生态的一部分。</sub></p>
<p>📊 React 进度条组件,支持线型、圆形和自定义进度展示。</p>

<p>
Expand Down
88 changes: 88 additions & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { FlatCompat } from '@eslint/eslintrc';
import js from '@eslint/js';
import tsEslintPlugin from '@typescript-eslint/eslint-plugin';
import { createRequire } from 'node:module';
import path from 'node:path';
import { fileURLToPath } from 'node:url';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const require = createRequire(import.meta.url);

const compat = new FlatCompat({
baseDirectory: __dirname,
recommendedConfig: js.configs.recommended,
allConfig: js.configs.all,
});

const recommendedTsRules = new Set(
Object.keys(tsEslintPlugin.configs.recommended.rules || {}),
);
const noopRule = {
meta: { type: 'problem', docs: {}, schema: [] },
create: () => ({}),
};

function normalizeConfig(config) {
const next = { ...config };

if (next.plugins?.['@typescript-eslint']) {
next.plugins = { ...next.plugins };
delete next.plugins['@typescript-eslint'];
}

if (next.rules) {
next.rules = Object.fromEntries(
Object.entries(next.rules).filter(([ruleName]) => {
if (!ruleName.startsWith('@typescript-eslint/')) {
return true;
}
return (
recommendedTsRules.has(ruleName) ||
ruleName === '@typescript-eslint/ban-types'
);
}),
);
Comment on lines +34 to +45

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '## file list\n'
git ls-files | rg '^(eslint\.config\.mjs|\.eslintrc\.js)$|typescript-eslint|eslint'

printf '\n## locate no-explicit-any and related ts rule filtering\n'
rg -n "`@typescript-eslint/no-explicit-any`|recommendedTsRules|ban-types|normalizeConfig|FlatCompat" eslint.config.mjs .eslintrc.js

Repository: react-component/progress

Length of output: 944


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '## eslint.config.mjs lines\n'
cat -n eslint.config.mjs | sed -n '1,140p'

printf '\n## .eslintrc.js lines\n'
cat -n .eslintrc.js | sed -n '1,120p'

Repository: react-component/progress

Length of output: 3317


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
import re, json

cfg = Path('eslint.config.mjs').read_text()
legacy = Path('.eslintrc.js').read_text()

for name, text in [('eslint.config.mjs', cfg), ('.eslintrc.js', legacy)]:
    print(f'## {name}')
    for pat in ['no-explicit-any', 'recommendedTsRules', 'ban-types', 'normalizeConfig', 'FlatCompat']:
        if pat in text:
            print(f'contains {pat}')
    print()

# simple extraction of the filter block if present
m = re.search(r'if \(next\.rules\) \{.*?Object\.fromEntries\(\s*Object\.entries\(next\.rules\)\.filter\(\(\[ruleName\]\) => \{(.*?)\}\),\s*\);\n', cfg, re.S)
print('filter_block_found=', bool(m))
if m:
    print(m.group(1))
PY

Repository: react-component/progress

Length of output: 539


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
import re

cfg = Path('eslint.config.mjs').read_text()
legacy = Path('.eslintrc.js').read_text()

for name, text in [('eslint.config.mjs', cfg), ('.eslintrc.js', legacy)]:
    print(f'## {name}')
    for pat in ['no-explicit-any', 'recommendedTsRules', 'ban-types', 'normalizeConfig', 'FlatCompat']:
        if pat in text:
            print(f'contains {pat}')
    print()

m = re.search(r'if \(next\.rules\) \{.*?Object\.fromEntries\(\s*Object\.entries\(next\.rules\)\.filter\(\(\[ruleName\]\) => \{(.*?)\}\),\s*\);\n', cfg, re.S)
print('filter_block_found=', bool(m))
if m:
    print(m.group(1))
PY

Repository: react-component/progress

Length of output: 539


保留 @typescript-eslint/no-explicit-any 的迁移规则

.eslintrc.js:11 里有显式关闭,但 eslint.config.mjs:42-46 只保留 recommended 里的 TS 规则和 @typescript-eslint/ban-types,这个 override 会在迁移时被丢掉;后面的全局 rules 里也没有再关回去。可把它补进 allowlist,或在 flat config 末尾显式关闭。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@eslint.config.mjs` around lines 40 - 48, `next.rules` 的过滤逻辑把迁移中需要保留的
`@typescript-eslint/no-explicit-any` 丢掉了,导致原来在 `.eslintrc.js` 里显式关闭的规则在 flat
config 中失效。请在 `eslint.config.mjs` 的这段 allowlist 过滤中把
`@typescript-eslint/no-explicit-any` 加回去,或者在最终的 flat config `rules`
合并结果里再次显式关闭它,确保迁移后的行为与现有配置一致。

}

return next;
}

export default [
{
ignores: [
'node_modules/',
'coverage/',
'es/',
'lib/',
'dist/',
'docs-dist/',
'.dumi/',
'.doc/',
'.vercel/',
'.eslintrc.js',
'src/index.d.ts',
],
},
{
plugins: {
'@typescript-eslint': {
...tsEslintPlugin,
rules: {
...tsEslintPlugin.rules,
'ban-types': noopRule,
'consistent-type-exports': noopRule,
},
},
},
},
...compat.config(require('./.eslintrc.js')).map(normalizeConfig),
{
rules: {
'@typescript-eslint/ban-types': 'off',
'@typescript-eslint/no-empty-object-type': 'off',
'@typescript-eslint/no-unsafe-function-type': 'off',
'@typescript-eslint/no-unused-vars': 'off',
},
},
];
48 changes: 48 additions & 0 deletions global.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/// <reference types="jest" />
/// <reference types="node" />
/// <reference types="react" />
/// <reference types="react-dom" />
/// <reference types="@testing-library/jest-dom" />

declare module '*.css';
declare module '*.less';
declare module 'jsonp';

declare namespace JSX {
type Element = React.JSX.Element;
interface ElementClass extends React.JSX.ElementClass {}
interface ElementAttributesProperty extends React.JSX.ElementAttributesProperty {}
interface ElementChildrenAttribute extends React.JSX.ElementChildrenAttribute {}
type LibraryManagedAttributes<C, P> = React.JSX.LibraryManagedAttributes<C, P>;
interface IntrinsicAttributes extends React.JSX.IntrinsicAttributes {}
interface IntrinsicClassAttributes<T> extends React.JSX.IntrinsicClassAttributes<T> {}
interface IntrinsicElements extends React.JSX.IntrinsicElements {}
}

declare namespace jest {
interface Matchers<R> {
lastCalledWith(...expected: unknown[]): R;
nthCalledWith(nthCall: number, ...expected: unknown[]): R;
toBeCalled(): R;
toBeCalledTimes(expected: number): R;
toBeCalledWith(...expected: unknown[]): R;
}
}

declare const vi: {
fn: <T extends (...args: any[]) => any = (...args: any[]) => any>(implementation?: T) => jest.MockedFunction<T>;
mock: (moduleName: string, factory?: (importOriginal: <T>() => Promise<T>) => unknown) => void;
spyOn: typeof jest.spyOn;
useFakeTimers: () => void;
useRealTimers: () => void;
advanceTimersByTime: (msToRun: number) => void;
clearAllTimers: () => void;
runAllTimers: () => void;
importActual: <T>(moduleName: string) => Promise<T>;
clearAllMocks: () => void;
resetAllMocks: () => void;
restoreAllMocks: () => void;
};


declare module 'moment/locale/zh-cn';
37 changes: 24 additions & 13 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,30 +44,41 @@
"clsx": "^2.1.1"
},
"devDependencies": {
"@babel/eslint-parser": "^7.29.7",
"@babel/eslint-plugin": "^7.29.7",
"@eslint/eslintrc": "^3.3.5",
"@eslint/js": "^9.39.4",
"@rc-component/father-plugin": "^2.2.0",
"@rc-component/np": "^1.0.4",
"@testing-library/react": "^15.0.7",
"@types/jest": "^29.5.14",
"@types/keyv": "3.1.4",
"@testing-library/dom": "^10.4.1",
"@testing-library/jest-dom": "^6.9.1",
"@testing-library/react": "^16.3.2",
"@types/jest": "^30.0.0",
"@types/keyv": "^4.2.0",
"@types/node": "^26.0.1",
"@types/react": "^18.3.31",
"@types/react-dom": "^18.3.7",
"@types/react": "^19.2.17",
"@types/react-dom": "^19.2.3",
"@typescript-eslint/eslint-plugin": "^8.62.0",
"@typescript-eslint/parser": "^8.62.0",
"@umijs/fabric": "^4.0.1",
"cross-env": "^10.1.0",
"dumi": "^2.4.35",
"eslint": "^8.57.1",
"eslint-plugin-jest": "^27.9.0",
"eslint-plugin-unicorn": "^56.0.1",
"eslint": "^9.39.4",
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-jest": "^29.15.3",
"eslint-plugin-react": "^7.37.5",
"eslint-plugin-react-hooks": "^7.1.1",
"eslint-plugin-unicorn": "^65.0.1",
"father": "^4.6.23",
"gh-pages": "^6.3.0",
"glob": "^13.0.6",
"husky": "^9.1.7",
"lint-staged": "^17.0.8",
"prettier": "^3.9.0",
"rc-test": "^7.1.3",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"typescript": "^5.9.3",
"husky": "^9.1.7",
"lint-staged": "^16.4.0"
"react": "^19.2.7",
"react-dom": "^19.2.7",
"typescript": "^6.0.3"
},
"peerDependencies": {
"react": ">=16.9.0",
Expand Down
16 changes: 16 additions & 0 deletions react-compat.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import * as React from 'react';

declare module 'react' {
type ReactText = string | number;
function useRef<T = undefined>(): React.MutableRefObject<T | undefined>;
function isValidElement<P = any>(object: {} | null | undefined): object is React.ReactElement<P>;
function cloneElement<P = any>(
element: React.ReactElement<P>,
props?: (Partial<P> & React.Attributes) | null,
...children: React.ReactNode[]
): React.ReactElement<P>;
}

declare module 'react-dom' {
function hydrate(element: React.ReactNode, container: Element | DocumentFragment): void;
}
Comment on lines +3 to +16

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

Globally overriding and augmenting core React types (like useRef, isValidElement, cloneElement, and hydrate) is highly discouraged. This can cause severe type conflicts and unexpected behavior for consumers of this library, as these global overrides will affect their own compilation environments if the declaration files are exported. Instead of globally overriding these types to bypass React 19 breaking changes, you should update the component implementations to use React 19-compatible patterns, or use local type assertions/helper functions where necessary.

20 changes: 14 additions & 6 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,26 +1,34 @@
{
"compilerOptions": {
"target": "esnext",
"moduleResolution": "node",
"baseUrl": "./",
"moduleResolution": "bundler",
"jsx": "react",
"declaration": true,
"skipLibCheck": true,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

Does TypeScript's skipLibCheckskip checking project-local.d.tsfiles included viatsconfig, especially for module augmentation and declaration merging?

💡 Result:

Yes, TypeScript's skipLibCheck option applies to all declaration files (.d.ts) included in your compilation, including project-local ones [1]. When skipLibCheck is enabled, it instructs the compiler to skip the "check each top-level statement or declaration" step for all.d.ts files [2][3]. This behavior has several specific implications for module augmentation and declaration merging: 1. Scope of Effect: The option does not distinguish between files in node_modules and your own project-local.d.ts files [1][4]. If a declaration file is part of your compilation (e.g., included via tsconfig), it will be skipped regardless of its location [1]. 2. Impact on Type Checking: skipLibCheck does not mean that.d.ts files are completely ignored [5]. TypeScript will still process and use the types contained within them when you reference them in your source code [6][5]. However, it prevents the compiler from performing a full, proactive validation of every declaration within those files [6][2]. 3. Module Augmentation and Merging: Because skipLibCheck skips the explicit validation of.d.ts files, it may hide errors that would otherwise be caught during declaration merging or module augmentation [1]. For example, if your module augmentation in a.ts file conflicts with a definition in a.d.ts file, the compiler might suppress or fail to report errors related to that.d.ts file's internal consistency [1][7]. 4. No Partial Control: There is currently no built-in mechanism in TypeScript to enable skipLibCheck for node_modules while keeping it disabled for project-local declaration files [8][1]. In practice, if you need to ensure that your local declaration files are rigorously checked—especially when performing complex module augmentation or merging—you should keep skipLibCheck set to false [9]. The performance cost of checking project-local.d.ts files is generally significantly lower than the cost of checking the entire node_modules directory [8].

Citations:


不要用 skipLibCheck 跳过这次新增声明文件的检查。

global.d.tsreact-compat.d.ts 是这次新增的兼容声明层;这里设成 true 会让它们的冲突、合并和 augmentation 问题更容易漏过,而这个包还会产出 d.ts,更应该让这部分参与校验。建议改回 false,或至少补一条不启用 skipLibCheck 的类型检查。

建议修改
-    "skipLibCheck": true,
+    "skipLibCheck": false,
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"skipLibCheck": true,
"skipLibCheck": false,
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tsconfig.json` at line 7, The tsconfig setting currently skips declaration
checking, which can hide issues in the new compatibility layer. Update the
tsconfig entry for skipLibCheck to stop bypassing checks so the newly added
global.d.ts and react-compat.d.ts are type-checked, and make sure the package’s
d.ts output is validated; if needed, add a type-check path that runs without
skipLibCheck.

"esModuleInterop": true,
"paths": {
"@/*": [
"src/*"
"./src/*"
],
"@@/*": [
".dumi/tmp/*"
"./.dumi/tmp/*"
],
"@rc-component/progress": [
"src/index.ts"
"./src/index.ts"
]
},
"ignoreDeprecations": "5.0"
"noImplicitAny": false,
"strictNullChecks": false,
"strictPropertyInitialization": false,
"strictFunctionTypes": false,
"strict": false,
"noImplicitThis": false,
"strictBindCallApply": false,
"module": "ESNext"
},
"include": [
"react-compat.d.ts",
"global.d.ts",
".fatherrc.ts",
".dumirc.ts",
"src",
Expand Down
Loading