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 }}><DumiDemoGriditems={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智能小助手)
对网络安全、黑客技术感兴趣的朋友可以关注我的安全公众号(网络安全技术点滴分享)
公众号二维码
公众号二维码