Ant Design:企业级 UI 设计语言与 React 组件库

Ant Design

项目描述

Ant Design 是一套企业级的 UI 设计语言和 React 组件库,致力于提供高质量的设计规范和丰富的组件资源。该项目基于 TypeScript 开发,提供完整的类型定义,支持 React 16 到 19 版本,具有出色的国际化能力和可定制化主题功能。

功能特性

  • 丰富的组件库:提供超过 60 个高质量 React 组件,涵盖布局、导航、数据录入、数据展示、反馈等各类场景
  • TypeScript 支持:完整的 TypeScript 类型定义,提供优秀的开发体验
  • 国际化解决方案:内置多语言支持,轻松实现国际化需求
  • 可定制主题:支持 CSS 变量和设计令牌,方便进行主题定制
  • 企业级设计规范:遵循 Ant Design 设计语言,保证设计的一致性和专业性
  • 跨平台兼容:支持服务端渲染,兼容现代浏览器
  • 开发工具完善:提供完整的开发、构建、测试工具链

安装指南

环境要求

  • Node.js 版本 >= 16
  • React 16 ~ 19
  • 现代浏览器支持(Chrome 80+)

安装依赖

# 使用 npm 安装
npm install antd

# 使用 yarn 安装
yarn add antd

# 使用 pnpm 安装
pnpm add antd

# 使用 Bun 安装
bun add antd

开发环境设置

# 克隆项目
git clone https://github.com/ant-design/ant-design.git

# 安装依赖
npm install

# 启动开发服务器
npm start

# 运行测试
npm test

# 构建项目
npm run build

使用说明

基础使用

import React from 'react';
import { Button, DatePicker } from 'antd';

const App = () => (
  <>
    <Button type="primary">主要按钮</Button>
    <DatePicker />
  </>
);

export default App;

国际化配置

import React from 'react';
import { ConfigProvider } from 'antd';
import zhCN from 'antd/locale/zh_CN';

const App = () => (
  <ConfigProvider locale={zhCN}>
    <YourApp />
  </ConfigProvider>
);

主题定制

import React from 'react';
import { ConfigProvider } from 'antd';

const theme = {
  token: {
    colorPrimary: '#00b96b',
  },
};

const App = () => (
  <ConfigProvider theme={theme}>
    <YourApp />
  </ConfigProvider>
);

核心代码

组件样式管理

// components/style/index.ts
function pascalCase(name) {
  return name.charAt(0).toUpperCase() + name.slice(1).replace(/-(\w)/g, (m, n) => n.toUpperCase());
}

// 自动导入组件样式
const req = require.context('./components', true, /^\.\/[^_][\w-]+\/style\/index\.tsx?$/);

req.keys().forEach((mod) => {
  let v = req(mod);
  if (v?.default) {
    v = v.default;
  }
  const match = mod.match(/^\.\/([^_][\w-]+)\/index\.tsx?$/);
  if (match?.[1]) {
    if (match[1] === 'message' || match[1] === 'notification') {
      exports[match[1]] = v;
    } else {
      exports[pascalCase(match[1])] = v;
    }
  }
});

构建配置

// scripts/dist.config.js
function addLocales(config) {
  const newConfig = { ...config };
  let packageName = 'antd-with-locales';
  if (newConfig.entry['antd.min']) {
    packageName += '.min';
  }
  newConfig.entry[packageName] = './index-with-locales.js';
  newConfig.output.filename = '[name].js';
  return newConfig;
}

function externalDayjs(config) {
  const newConfig = { ...config };
  newConfig.externals.dayjs = {
    root: 'dayjs',
    commonjs2: 'dayjs',
    commonjs: 'dayjs',
    amd: 'dayjs',
  };
  return newConfig;
}

图标系统

// site/theme/common/IconSearch/index.tsx
import React, { useCallback, useMemo, useState } from 'react';
import Icon, * as AntdIcons from '@ant-design/icons';

export enum ThemeType {
  Filled = 'Filled',
  Outlined = 'Outlined',
  TwoTone = 'TwoTone',
}

const IconSearch: React.FC = () => {
  const [displayState, setDisplayState] = useState({
    searchKey: '',
    theme: ThemeType.Outlined,
  });

  const handleSearchIcon = debounce((e: React.ChangeEvent<HTMLInputElement>) => {
    setDisplayState(prevState => ({ ...prevState, searchKey: e.target.value }));
  }, 300);

  const handleChangeTheme = useCallback((value: ThemeType) => {
    setDisplayState(prevState => ({ ...prevState, theme: value }));
  }, []);

  return (
    <div>
      {/* 图标搜索和展示逻辑 */}
    </div>
  );
};

演示组件包装器

// site/theme/common/DemoWrapper.tsx
import React, { Suspense } from 'react';
import { DumiDemo, DumiDemoGrid } from 'dumi';

const DemoWrapper: typeof DumiDemoGrid = ({ items }) => {
  const { showDebug, setShowDebug } = React.useContext(DemoContext);
  const [expandAll, setExpandAll] = useLayoutState(false);
  const [enableCssVar, setEnableCssVar] = useLayoutState(true);

  const demos = React.useMemo(() =>
    items.reduce((acc, item) => {
      const { debug } = item.previewerProps;
      if (debug && !showDebug) return acc;
      return acc.concat({
        ...item,
        previewerProps: {
          ...item.previewerProps,
          expand: expandAll,
          debug: false,
          originDebug: debug,
        },
      });
    }, []),
    [expandAll, showDebug]
  );

  return (
    <div className="demo-wrapper">
      <ConfigProvider theme={{ cssVar: enableCssVar, hashed: !enableCssVar }}>
        <DumiDemoGrid
          items={demos}
          demoRender={(item) => (
            <Suspense key={item.demo.id} fallback={<DemoFallback />}>
              <DumiDemo {...item} />
            </Suspense>
          )}
        />
      </ConfigProvider>
    </div>
  );
};

主题切换动画

// site/theme/common/hooks/useThemeAnimation.ts
const useThemeAnimation = () => {
  const {
    token: { colorBgElevated },
  } = theme.useToken();

  const toggleAnimationTheme = (event: React.MouseEvent<HTMLElement>, isDark: boolean) => {
    if (!(event && typeof document.startViewTransition === 'function')) return;
    
    const x = event.clientX;
    const y = event.clientY;
    const endRadius = Math.hypot(Math.max(x, innerWidth - x), Math.max(y, innerHeight - y));
    
    document.startViewTransition(async () => {
      // 等待主题变更完成
      while (colorBgElevated === animateRef.current.colorBgElevated) {
        await new Promise<void>(resolve => setTimeout(resolve, 1000 / 60));
      }
      const root = document.documentElement;
      root.classList.remove(isDark ? 'dark' : 'light');
      root.classList.add(isDark ? 'light' : 'dark');
    });
  };

  return toggleAnimationTheme;
};

更多精彩内容 请关注我的个人公众号 公众号(办公AI智能小助手)
对网络安全、黑客技术感兴趣的朋友可以关注我的安全公众号(网络安全技术点滴分享)

公众号二维码

公众号二维码

posted @ 2025-10-18 14:12  qife  阅读(4)  评论(0)    收藏  举报