This is an automated email from the ASF dual-hosted git repository.
rusackas pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/superset.git
The following commit(s) were added to refs/heads/master by this push:
new acdd390b354 fix(frontend): finish migrating off direct antd imports,
enforce it in custom rules (#44927)
acdd390b354 is described below
commit acdd390b35469d65c568da1e933743b4ad77c2ba
Author: Evan Rusackas <[email protected]>
AuthorDate: Sat Oct 3 13:55:58 2026 -0700
fix(frontend): finish migrating off direct antd imports, enforce it in
custom rules (#44927)
Co-authored-by: Claude Sonnet 5 <[email protected]>
---
.../superset-ui-core/src/components/Tag/index.tsx | 1 +
superset-frontend/scripts/check-custom-rules.js | 42 ++++++++++++++++++++++
.../components/Chart/DrillBy/DrillBySubmenu.tsx | 2 +-
.../components/Chart/MenuItemWithTruncation.tsx | 5 ++-
.../Datasource/ChangeDatasourceModal/index.tsx | 2 +-
superset-frontend/src/components/Tag/index.tsx | 8 +++--
6 files changed, 52 insertions(+), 8 deletions(-)
diff --git
a/superset-frontend/packages/superset-ui-core/src/components/Tag/index.tsx
b/superset-frontend/packages/superset-ui-core/src/components/Tag/index.tsx
index f9b7884464a..7275d529104 100644
--- a/superset-frontend/packages/superset-ui-core/src/components/Tag/index.tsx
+++ b/superset-frontend/packages/superset-ui-core/src/components/Tag/index.tsx
@@ -17,3 +17,4 @@
* under the License.
*/
export { Tag } from 'antd';
+export type { TagProps, CheckableTagProps } from 'antd/es/tag';
diff --git a/superset-frontend/scripts/check-custom-rules.js
b/superset-frontend/scripts/check-custom-rules.js
index 11697b0515f..d3502ace105 100755
--- a/superset-frontend/scripts/check-custom-rules.js
+++ b/superset-frontend/scripts/check-custom-rules.js
@@ -174,6 +174,46 @@ function checkNoFaIcons(ast, filepath) {
});
}
+/**
+ * App code (and plugins) must go through the @superset-ui/core/components
+ * wrappers rather than importing from antd directly, so theming and behavior
+ * stay centralized in one place. The wrapper packages themselves
+ * (superset-ui-core, superset-core) are the legitimate exception -- they're
+ * what the wrappers are built from -- and `theme/utils` files that introspect
+ * antd's own design tokens are exempted the same way checkNoLiteralColors
+ * already exempts that directory (there is no wrapper for "list antd's own
+ * token names").
+ */
+const ANTD_DIRECT_IMPORT_EXEMPT = [
+ /\/theme\/utils\//,
+ /packages\/superset-ui-core\//,
+ /packages\/superset-core\//,
+];
+
+function checkNoDirectAntdImports(ast, filepath) {
+ if (ANTD_DIRECT_IMPORT_EXEMPT.some(pattern => pattern.test(filepath))) {
+ return;
+ }
+
+ traverse(ast, {
+ 'ImportDeclaration|ExportNamedDeclaration|ExportAllDeclaration': function (
+ path,
+ ) {
+ const source = path.node.source?.value ?? '';
+ if (source === 'antd' || source.startsWith('antd/')) {
+ if (hasEslintDisable(path, 'no-restricted-imports')) return;
+
+ // eslint-disable-next-line no-console
+ console.error(
+ `${RED}✖${RESET} ${filepath}: Direct import from "${source}". ` +
+ `Use the @superset-ui/core/components wrapper instead.`,
+ );
+ errorCount += 1;
+ }
+ },
+ });
+}
+
/**
* Check for improper i18n template usage
*/
@@ -625,6 +665,7 @@ function processFile(filepath) {
// Run all checks
checkNoLiteralColors(ast, filepath);
checkNoFaIcons(ast, filepath);
+ checkNoDirectAntdImports(ast, filepath);
checkI18nTemplates(ast, filepath);
checkEagerTranslationsInConfig(ast, filepath);
checkUntranslatedStrings(ast, filepath);
@@ -787,6 +828,7 @@ if (__filename === process.argv[1]) {
export default {
checkNoLiteralColors,
checkNoFaIcons,
+ checkNoDirectAntdImports,
checkI18nTemplates,
checkUntranslatedStrings,
checkTypeScriptOnlySource,
diff --git a/superset-frontend/src/components/Chart/DrillBy/DrillBySubmenu.tsx
b/superset-frontend/src/components/Chart/DrillBy/DrillBySubmenu.tsx
index 3e8a5fea83a..5d0fedf5ce9 100644
--- a/superset-frontend/src/components/Chart/DrillBy/DrillBySubmenu.tsx
+++ b/superset-frontend/src/components/Chart/DrillBy/DrillBySubmenu.tsx
@@ -42,11 +42,11 @@ import {
Loading,
Popover,
Icons,
+ type InputRef,
} from '@superset-ui/core/components';
import { Radio } from '@superset-ui/core/components/Radio';
import { debounce } from 'lodash-es';
import { List, type RowComponentProps } from 'react-window';
-import { InputRef } from 'antd';
import { MenuItemTooltip } from '../DisabledMenuItemTooltip';
import { VirtualizedMenuItem } from '../MenuItemWithTruncation';
import { Dataset } from '../types';
diff --git a/superset-frontend/src/components/Chart/MenuItemWithTruncation.tsx
b/superset-frontend/src/components/Chart/MenuItemWithTruncation.tsx
index 89cdec80c32..d2c67c2d4e5 100644
--- a/superset-frontend/src/components/Chart/MenuItemWithTruncation.tsx
+++ b/superset-frontend/src/components/Chart/MenuItemWithTruncation.tsx
@@ -17,17 +17,16 @@
* under the License.
*/
-import { ReactNode, CSSProperties, useCallback } from 'react';
+import { ComponentProps, ReactNode, CSSProperties, useCallback } from 'react';
import { truncationCSS, useCSSTextTruncation } from '@superset-ui/core';
import { css, useTheme } from '@apache-superset/core/theme';
import { Menu, type ItemType } from '@superset-ui/core/components/Menu';
import { Flex, Tooltip } from '@superset-ui/core/components';
-import { MenuItemProps } from 'antd';
export type MenuItemWithTruncationProps = {
tooltipText: ReactNode;
children: ReactNode;
- onClick?: MenuItemProps['onClick'];
+ onClick?: ComponentProps<typeof Menu.Item>['onClick'];
style?: CSSProperties;
menuKey?: string;
};
diff --git
a/superset-frontend/src/components/Datasource/ChangeDatasourceModal/index.tsx
b/superset-frontend/src/components/Datasource/ChangeDatasourceModal/index.tsx
index 093fe8c25f7..9697b8a6fec 100644
---
a/superset-frontend/src/components/Datasource/ChangeDatasourceModal/index.tsx
+++
b/superset-frontend/src/components/Datasource/ChangeDatasourceModal/index.tsx
@@ -37,6 +37,7 @@ import {
Loading,
Modal,
TableView,
+ type InputRef,
} from '@superset-ui/core/components';
import {
ServerPagination,
@@ -51,7 +52,6 @@ import {
SORT_BY as DATASET_SORT_BY,
} from 'src/features/datasets/constants';
import withToasts from 'src/components/MessageToasts/withToasts';
-import { InputRef } from 'antd';
import type { Datasource, ChangeDatasourceModalProps } from '../types';
import { datasetLabelLower } from 'src/features/semanticLayers/label';
diff --git a/superset-frontend/src/components/Tag/index.tsx
b/superset-frontend/src/components/Tag/index.tsx
index 0605977bc08..6229632f27c 100644
--- a/superset-frontend/src/components/Tag/index.tsx
+++ b/superset-frontend/src/components/Tag/index.tsx
@@ -20,10 +20,12 @@
import { styled } from '@apache-superset/core/theme';
import { Link } from 'react-router-dom';
import type { TagType } from 'src/types/TagType';
-import { Tag as AntdTag } from '@superset-ui/core/components/Tag';
+import {
+ Tag as AntdTag,
+ type TagProps,
+ type CheckableTagProps,
+} from '@superset-ui/core/components/Tag';
import { Tooltip } from '@superset-ui/core/components/Tooltip';
-import type { TagProps } from 'antd/es';
-import type { CheckableTagProps } from 'antd/es/tag';
import { useMemo } from 'react';
const StyledTag = styled(AntdTag)`