Browse Source

fix: fix Tailwind CSS not being applied due to Less import issue (#11662)

* fix: fix Tailwind CSS not being applied due to Less import issue

Tailwind CSS v4 was not generating styles because it was imported via
Less's @import in global.less. Less could not process the modern CSS syntax
(@import "tailwindcss"), causing the PostCSS plugin to never process it.

Fixed by importing tailwind.css directly in app.tsx, which allows Vite to
process it through PostCSS correctly.

Closes #11661

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: remove font smoothing CSS properties

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: 重新设计 Welcome 页面,使用 Tailwind CSS 实现现代简洁风格

- 采用左侧介绍 + 右侧卡片布局
- 使用 Tailwind 类名替代内联样式
- 卡片增加 hover 效果和圆角
- 支持亮色/暗色主题

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: configure Tailwind CSS v3

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: 修复 Welcome 页面主题兼容性问题

- 移除 Tailwind dark: 类,改用 Ant Design token 驱动颜色
- 修复 flex 布局使用 flex-none 替代 flex-1

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: 重新设计 Welcome 页面 - 渐变标题 + 毛玻璃卡片

- 标题使用渐变色
- 卡片使用毛玻璃效果 (backdrop-blur)
- 添加悬停光效动画
- 三列网格布局

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
pull/11672/head
afc163 6 months ago
committed by GitHub
parent
commit
673e9989d1
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 6
      config/config.ts
  2. 3
      package.json
  3. 2
      src/global.less
  4. 176
      src/pages/Welcome.tsx
  5. 3
      tailwind.config.js
  6. 16
      tailwind.css

6
config/config.ts

@ -1,7 +1,6 @@
// https://umijs.org/config/ // https://umijs.org/config/
import { join } from 'node:path'; import { join } from 'node:path';
import tailwindcss from '@tailwindcss/postcss';
import { defineConfig } from '@umijs/max'; import { defineConfig } from '@umijs/max';
import defaultSettings from './defaultSettings'; import defaultSettings from './defaultSettings';
import proxy from './proxy'; import proxy from './proxy';
@ -202,5 +201,8 @@ export default defineConfig({
'process.env.COMMIT_HASH': process.env.COMMIT_HASH || '', 'process.env.COMMIT_HASH': process.env.COMMIT_HASH || '',
'process.env.CF_PAGES_COMMIT_SHA': process.env.CF_PAGES_COMMIT_SHA || '', 'process.env.CF_PAGES_COMMIT_SHA': process.env.CF_PAGES_COMMIT_SHA || '',
}, },
extraPostCSSPlugins: [tailwindcss], tailwindcss: {
// 这里可以配置 tailwindcss 的选项,具体配置项可以参考 tailwindcss 官方文档
// https://tailwindcss.com/docs/configuration
},
}); });

3
package.json

@ -57,7 +57,6 @@
"@biomejs/biome": "^2.1.1", "@biomejs/biome": "^2.1.1",
"@commitlint/cli": "^20.1.0", "@commitlint/cli": "^20.1.0",
"@commitlint/config-conventional": "^20.0.0", "@commitlint/config-conventional": "^20.0.0",
"@tailwindcss/postcss": "^4",
"@testing-library/dom": "^10.4.0", "@testing-library/dom": "^10.4.0",
"@testing-library/react": "^16.3.0", "@testing-library/react": "^16.3.0",
"@types/express": "^5.0.6", "@types/express": "^5.0.6",
@ -79,7 +78,7 @@
"jest-environment-jsdom": "^30.0.5", "jest-environment-jsdom": "^30.0.5",
"lint-staged": "^16.1.2", "lint-staged": "^16.1.2",
"mockjs": "^1.1.0", "mockjs": "^1.1.0",
"tailwindcss": "^4", "tailwindcss": "^3.3.2",
"ts-node": "^10.9.2", "ts-node": "^10.9.2",
"typescript": "^6.0.2", "typescript": "^6.0.2",
"umi-serve": "^1.9.11" "umi-serve": "^1.9.11"

2
src/global.less

@ -1,5 +1,3 @@
@import '../tailwind.css';
@font-face { @font-face {
font-family: "AlibabaSans"; font-family: "AlibabaSans";
font-style: normal; font-style: normal;

176
src/pages/Welcome.tsx

@ -3,158 +3,138 @@ import { useModel } from '@umijs/max';
import { Card, theme } from 'antd'; import { Card, theme } from 'antd';
import React from 'react'; import React from 'react';
/**
* 每个单独的卡片,为了复用样式抽成了组件
* @param param0
* @returns
*/
const InfoCard: React.FC<{ const InfoCard: React.FC<{
title: string; title: string;
index: number; index: number;
desc: string; desc: string;
href: string; href: string;
}> = ({ title, href, index, desc }) => { isDark?: boolean;
const { useToken } = theme; }> = ({ title, href, index, desc, isDark }) => {
const { token } = theme.useToken();
const { token } = useToken();
return ( return (
<div <a
href={href}
target="_blank"
rel="noreferrer"
className="group relative overflow-hidden rounded-2xl p-6 transition-all duration-300 hover:scale-[1.02]"
style={{ style={{
backgroundColor: token.colorBgContainer, background: isDark
boxShadow: token.boxShadow, ? 'rgba(255, 255, 255, 0.05)'
borderRadius: '8px', : 'rgba(255, 255, 255, 0.7)',
fontSize: '14px', backdropFilter: 'blur(20px)',
color: token.colorTextSecondary, border: `1px solid ${isDark ? 'rgba(255,255,255,0.1)' : 'rgba(255,255,255,0.5)'}`,
lineHeight: '22px', boxShadow: isDark
padding: '16px 19px', ? '0 4px 24px rgba(0,0,0,0.3)'
minWidth: '220px', : '0 4px 24px rgba(0,0,0,0.06)',
flex: 1,
}} }}
> >
{/* 悬停时的光效 */}
<div <div
style={{ className="absolute -inset-full top-0 block h-full w-1/2 -skew-x-12 bg-gradient-to-r from-transparent to-white opacity-0 transition-all duration-500 group-hover:animate-shine group-hover:opacity-10"
display: 'flex', style={{ display: isDark ? 'none' : 'block' }}
gap: '4px', />
alignItems: 'center',
}} <div className="relative flex items-start gap-4">
>
<div <div
className="shrink-0 w-14 h-14 rounded-2xl flex items-center justify-center text-white text-xl font-bold"
style={{ style={{
width: 48, background: `linear-gradient(135deg, ${token.colorPrimary} 0%, ${token.colorPrimaryHover} 100%)`,
height: 48, boxShadow: `0 8px 20px ${token.colorPrimary}40`,
lineHeight: '22px',
backgroundSize: '100%',
textAlign: 'center',
padding: '8px 16px 16px 12px',
color: '#FFF',
fontWeight: 'bold',
backgroundImage:
"url('https://gw.alipayobjects.com/zos/bmw-prod/daaf8d50-8e6d-4251-905d-676a24ddfa12.svg')",
}} }}
> >
{index} {index}
</div> </div>
<div <div className="flex-1 min-w-0">
style={{ <h3
fontSize: '16px', className="text-lg font-semibold mb-2 group-hover:text-primary transition-colors"
color: token.colorText, style={{ color: token.colorText }}
paddingBottom: 8, >
}} {title}
> </h3>
{title} <p
className="text-sm leading-relaxed line-clamp-2"
style={{ color: token.colorTextSecondary }}
>
{desc}
</p>
</div> </div>
</div> </div>
<div <div
style={{ className="mt-4 text-sm font-medium flex items-center gap-1 transition-colors group-hover:gap-2"
fontSize: '14px', style={{ color: token.colorPrimary }}
color: token.colorTextSecondary,
textAlign: 'justify',
lineHeight: '22px',
marginBottom: 8,
}}
> >
{desc} 了解更多
<span className="transition-transform">→</span>
</div> </div>
<a href={href} target="_blank" rel="noreferrer"> </a>
了解更多 {'>'}
</a>
</div>
); );
}; };
const Welcome: React.FC = () => { const Welcome: React.FC = () => {
const { token } = theme.useToken(); const { token } = theme.useToken();
const { initialState } = useModel('@@initialState'); const { initialState } = useModel('@@initialState');
const isDark = initialState?.settings?.navTheme === 'realDark';
return ( return (
<PageContainer> <PageContainer>
<Card <Card
style={{ className="rounded-2xl overflow-hidden"
borderRadius: 8,
}}
styles={{ styles={{
body: { body: {
backgroundImage: background: isDark
initialState?.settings?.navTheme === 'realDark' ? 'linear-gradient(135deg, #0a0a0f 0%, #1a1a2e 50%, #16213e 100%)'
? 'background-image: linear-gradient(75deg, #1A1B1F 0%, #191C1F 100%)' : 'linear-gradient(135deg, #f8fafc 0%, #e2e8f0 50%, #cbd5e1 100%)',
: 'background-image: linear-gradient(75deg, #FBFDFF 0%, #F5F7FF 100%)', padding: '48px 0',
}, },
}} }}
> >
<div <div className="max-w-6xl mx-auto px-6">
style={{ {/* 标题区域 */}
backgroundPosition: '100% -30%', <div className="text-center mb-16">
backgroundRepeat: 'no-repeat', <h1
backgroundSize: '274px auto', className="text-5xl font-bold mb-6"
backgroundImage: style={{
"url('https://gw.alipayobjects.com/mdn/rms_a9745b/afts/img/A*BuFmQqsB2iAAAAAAAAAAAAAAARQnAQ')", background: `linear-gradient(135deg, ${token.colorPrimary} 0%, ${token.colorPrimaryHover} 100%)`,
}} WebkitBackgroundClip: 'text',
> WebkitTextFillColor: 'transparent',
<div backgroundClip: 'text',
style={{ }}
fontSize: '20px', >
color: token.colorTextHeading, 欢迎使用 Ant Design Pro
}} </h1>
> <p
欢迎使用 Ant Design Pro className="text-lg max-w-2xl mx-auto leading-relaxed"
style={{ color: token.colorTextSecondary }}
>
Ant Design Pro 是一个整合了 umi,Ant Design 和 ProComponents
的脚手架方案。致力于在设计规范和基础组件的基础上,继续向上构建,提炼出典型模板/业务组件/配套设计资源,进一步提升企业级中后台产品设计研发过程中的『用户』和『设计者』的体验。
</p>
</div> </div>
<p
style={{ {/* 卡片区域 */}
fontSize: '14px', <div className="grid grid-cols-1 md:grid-cols-3 gap-6">
color: token.colorTextSecondary,
lineHeight: '22px',
marginTop: 16,
marginBottom: 32,
width: '65%',
}}
>
Ant Design Pro 是一个整合了 umi,Ant Design 和 ProComponents
的脚手架方案。致力于在设计规范和基础组件的基础上,继续向上构建,提炼出典型模板/业务组件/配套设计资源,进一步提升企业级中后台产品设计研发过程中的『用户』和『设计者』的体验。
</p>
<div
style={{
display: 'flex',
flexWrap: 'wrap',
gap: 16,
}}
>
<InfoCard <InfoCard
index={1} index={1}
href="https://umijs.org/docs/introduce/introduce" href="https://umijs.org/docs/introduce/introduce"
title="了解 umi" title="了解 umi"
desc="umi 是一个可扩展的企业级前端应用框架,umi 以路由为基础的,同时支持配置式路由和约定式路由,保证路由的功能完备,并以此进行功能扩展。" desc="umi 是一个可扩展的企业级前端应用框架,umi 以路由为基础的,同时支持配置式路由和约定式路由,保证路由的功能完备,并以此进行功能扩展。"
isDark={isDark}
/> />
<InfoCard <InfoCard
index={2} index={2}
title="了解 ant design" title="了解 ant design"
href="https://ant.design" href="https://ant.design"
desc="antd 是基于 Ant Design 设计体系的 React UI 组件库,主要用于研发企业级中后台产品。" desc="antd 是基于 Ant Design 设计体系的 React UI 组件库,主要用于研发企业级中后台产品。"
isDark={isDark}
/> />
<InfoCard <InfoCard
index={3} index={3}
title="了解 Pro Components" title="了解 Pro Components"
href="https://procomponents.ant.design" href="https://procomponents.ant.design"
desc="ProComponents 是一个基于 Ant Design 做了更高抽象的模板组件,以 一个组件就是一个页面为开发理念,为中后台开发带来更好的体验。" desc="ProComponents 是一个基于 Ant Design 做了更高抽象的模板组件,以 一个组件就是一个页面为开发理念,为中后台开发带来更好的体验。"
isDark={isDark}
/> />
</div> </div>
</div> </div>

3
tailwind.config.js

@ -0,0 +1,3 @@
module.exports = {
content: ['./src/**/*.tsx'],
};

16
tailwind.css

@ -1,2 +1,14 @@
@import "tailwindcss"; @tailwind base;
@source "./src/**/*.tsx"; @tailwind components;
@tailwind utilities;
@layer utilities {
@keyframes shine {
100% {
left: 125%;
}
}
.animate-shine {
animation: shine 0.75s;
}
}

Loading…
Cancel
Save