index.ts 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. import type { Config } from 'tailwindcss';
  2. import fs from 'node:fs';
  3. import path from 'node:path';
  4. import { getPackagesSync } from '@vben/node-utils';
  5. import { addDynamicIconSelectors } from '@iconify/tailwind';
  6. import typographyPlugin from '@tailwindcss/typography';
  7. import animate from 'tailwindcss-animate';
  8. import { enterAnimationPlugin } from './plugins/entry';
  9. // import defaultTheme from 'tailwindcss/defaultTheme';
  10. const { packages } = getPackagesSync();
  11. const tailwindPackages: string[] = [];
  12. packages.forEach((pkg) => {
  13. // apps目录下和 @vben-core/tailwind-ui 包需要使用到 tailwindcss ui
  14. if (fs.existsSync(path.join(pkg.dir, 'tailwind.config.mjs'))) {
  15. tailwindPackages.push(pkg.dir);
  16. }
  17. });
  18. const shadcnUiColors = {
  19. accent: {
  20. DEFAULT: 'hsl(var(--accent))',
  21. foreground: 'hsl(var(--accent-foreground))',
  22. hover: 'hsl(var(--accent-hover))',
  23. },
  24. background: {
  25. deep: 'hsl(var(--background-deep))',
  26. DEFAULT: 'hsl(var(--background))',
  27. },
  28. border: {
  29. DEFAULT: 'hsl(var(--border))',
  30. },
  31. card: {
  32. DEFAULT: 'hsl(var(--card))',
  33. foreground: 'hsl(var(--card-foreground))',
  34. },
  35. destructive: {
  36. ...createColorsPalette('destructive'),
  37. DEFAULT: 'hsl(var(--destructive))',
  38. },
  39. foreground: {
  40. DEFAULT: 'hsl(var(--foreground))',
  41. },
  42. input: {
  43. background: 'hsl(var(--input-background))',
  44. DEFAULT: 'hsl(var(--input))',
  45. },
  46. muted: {
  47. DEFAULT: 'hsl(var(--muted))',
  48. foreground: 'hsl(var(--muted-foreground))',
  49. },
  50. popover: {
  51. DEFAULT: 'hsl(var(--popover))',
  52. foreground: 'hsl(var(--popover-foreground))',
  53. },
  54. primary: {
  55. ...createColorsPalette('primary'),
  56. DEFAULT: 'hsl(var(--primary))',
  57. },
  58. ring: 'hsl(var(--ring))',
  59. secondary: {
  60. DEFAULT: 'hsl(var(--secondary))',
  61. desc: 'hsl(var(--secondary-desc))',
  62. foreground: 'hsl(var(--secondary-foreground))',
  63. },
  64. };
  65. const customColors = {
  66. green: {
  67. ...createColorsPalette('green'),
  68. foreground: 'hsl(var(--success-foreground))',
  69. },
  70. header: {
  71. DEFAULT: 'hsl(var(--header))',
  72. },
  73. heavy: {
  74. DEFAULT: 'hsl(var(--heavy))',
  75. foreground: 'hsl(var(--heavy-foreground))',
  76. },
  77. main: {
  78. DEFAULT: 'hsl(var(--main))',
  79. },
  80. overlay: 'hsl(var(--overlay))',
  81. red: {
  82. ...createColorsPalette('red'),
  83. foreground: 'hsl(var(--destructive-foreground))',
  84. },
  85. sidebar: {
  86. deep: 'hsl(var(--sidebar-deep))',
  87. DEFAULT: 'hsl(var(--sidebar))',
  88. },
  89. success: {
  90. ...createColorsPalette('success'),
  91. DEFAULT: 'hsl(var(--success))',
  92. },
  93. warning: {
  94. ...createColorsPalette('warning'),
  95. DEFAULT: 'hsl(var(--warning))',
  96. },
  97. yellow: {
  98. ...createColorsPalette('yellow'),
  99. foreground: 'hsl(var(--warning-foreground))',
  100. },
  101. };
  102. export default {
  103. content: [
  104. './index.html',
  105. ...tailwindPackages.map((item) =>
  106. path.join(item, 'src/**/*.{vue,js,ts,jsx,tsx,svelte,astro,html}'),
  107. ),
  108. ],
  109. darkMode: 'selector',
  110. plugins: [
  111. animate,
  112. typographyPlugin,
  113. addDynamicIconSelectors(),
  114. enterAnimationPlugin,
  115. ],
  116. prefix: '',
  117. safelist: ['dark'],
  118. theme: {
  119. container: {
  120. center: true,
  121. padding: '2rem',
  122. screens: {
  123. '2xl': '1400px',
  124. },
  125. },
  126. extend: {
  127. animation: {
  128. 'accordion-down': 'accordion-down 0.2s ease-out',
  129. 'accordion-up': 'accordion-up 0.2s ease-out',
  130. 'collapsible-down': 'collapsible-down 0.2s ease-in-out',
  131. 'collapsible-up': 'collapsible-up 0.2s ease-in-out',
  132. float: 'float 5s linear 0ms infinite',
  133. },
  134. animationDuration: {
  135. '2000': '2000ms',
  136. '3000': '3000ms',
  137. },
  138. borderRadius: {
  139. lg: 'var(--radius)',
  140. md: 'calc(var(--radius) - 2px)',
  141. sm: 'calc(var(--radius) - 4px)',
  142. xl: 'calc(var(--radius) + 4px)',
  143. },
  144. boxShadow: {
  145. float: `0 6px 16px 0 rgb(0 0 0 / 8%),
  146. 0 3px 6px -4px rgb(0 0 0 / 12%),
  147. 0 9px 28px 8px rgb(0 0 0 / 5%)`,
  148. },
  149. colors: {
  150. ...customColors,
  151. ...shadcnUiColors,
  152. },
  153. fontFamily: {
  154. sans: [
  155. 'var(--font-family)',
  156. // ...defaultTheme.fontFamily.sans
  157. ],
  158. },
  159. keyframes: {
  160. 'accordion-down': {
  161. from: { height: '0' },
  162. to: { height: 'var(--radix-accordion-content-height)' },
  163. },
  164. 'accordion-up': {
  165. from: { height: 'var(--radix-accordion-content-height)' },
  166. to: { height: '0' },
  167. },
  168. 'collapsible-down': {
  169. from: { height: '0' },
  170. to: { height: 'var(--radix-collapsible-content-height)' },
  171. },
  172. 'collapsible-up': {
  173. from: { height: 'var(--radix-collapsible-content-height)' },
  174. to: { height: '0' },
  175. },
  176. float: {
  177. '0%': { transform: 'translateY(0)' },
  178. '50%': { transform: 'translateY(-20px)' },
  179. '100%': { transform: 'translateY(0)' },
  180. },
  181. },
  182. zIndex: {
  183. '100': '100',
  184. '1000': '1000',
  185. },
  186. },
  187. },
  188. } as Config;
  189. function createColorsPalette(name: string) {
  190. // backgroundLightest: '#EFF6FF', // Tailwind CSS 默认的 `blue-50`
  191. // backgroundLighter: '#DBEAFE', // Tailwind CSS 默认的 `blue-100`
  192. // backgroundLight: '#BFDBFE', // Tailwind CSS 默认的 `blue-200`
  193. // borderLight: '#93C5FD', // Tailwind CSS 默认的 `blue-300`
  194. // border: '#60A5FA', // Tailwind CSS 默认的 `blue-400`
  195. // main: '#3B82F6', // Tailwind CSS 默认的 `blue-500`
  196. // hover: '#2563EB', // Tailwind CSS 默认的 `blue-600`
  197. // active: '#1D4ED8', // Tailwind CSS 默认的 `blue-700`
  198. // backgroundDark: '#1E40AF', // Tailwind CSS 默认的 `blue-800`
  199. // backgroundDarker: '#1E3A8A', // Tailwind CSS 默认的 `blue-900`
  200. // backgroundDarkest: '#172554', // Tailwind CSS 默认的 `blue-950`
  201. // • backgroundLightest (#EFF6FF): 适用于最浅的背景色,可能用于非常轻微的阴影或卡片的背景。
  202. // • backgroundLighter (#DBEAFE): 适用于略浅的背景色,通常用于次要背景或略浅的区域。
  203. // • backgroundLight (#BFDBFE): 适用于浅色背景,可能用于输入框或表单区域的背景。
  204. // • borderLight (#93C5FD): 适用于浅色边框,可能用于输入框或卡片的边框。
  205. // • border (#60A5FA): 适用于普通边框,可能用于按钮或卡片的边框。
  206. // • main (#3B82F6): 适用于主要的主题色,通常用于按钮、链接或主要的强调色。
  207. // • hover (#2563EB): 适用于鼠标悬停状态下的颜色,例如按钮悬停时的背景色或边框色。
  208. // • active (#1D4ED8): 适用于激活状态下的颜色,例如按钮按下时的背景色或边框色。
  209. // • backgroundDark (#1E40AF): 适用于深色背景,可能用于主要按钮或深色卡片背景。
  210. // • backgroundDarker (#1E3A8A): 适用于更深的背景,通常用于头部导航栏或页脚。
  211. // • backgroundDarkest (#172554): 适用于最深的背景,可能用于非常深色的区域或极端对比色。
  212. return {
  213. 50: `hsl(var(--${name}-50))`,
  214. 100: `hsl(var(--${name}-100))`,
  215. 200: `hsl(var(--${name}-200))`,
  216. 300: `hsl(var(--${name}-300))`,
  217. 400: `hsl(var(--${name}-400))`,
  218. 500: `hsl(var(--${name}-500))`,
  219. 600: `hsl(var(--${name}-600))`,
  220. 700: `hsl(var(--${name}-700))`,
  221. // 800: `hsl(var(--${name}-800))`,
  222. // 900: `hsl(var(--${name}-900))`,
  223. // 950: `hsl(var(--${name}-950))`,
  224. // 激活状态下的颜色,适用于按钮按下时的背景色或边框色。
  225. active: `hsl(var(--${name}-700))`,
  226. // 浅色背景,适用于输入框或表单区域的背景。
  227. 'background-light': `hsl(var(--${name}-200))`,
  228. // 适用于略浅的背景色,通常用于次要背景或略浅的区域。
  229. 'background-lighter': `hsl(var(--${name}-100))`,
  230. // 最浅的背景色,适用于非常轻微的阴影或卡片的背景。
  231. 'background-lightest': `hsl(var(--${name}-50))`,
  232. // 适用于普通边框,可能用于按钮或卡片的边框。
  233. border: `hsl(var(--${name}-400))`,
  234. // 浅色边框,适用于输入框或卡片的边框。
  235. 'border-light': `hsl(var(--${name}-300))`,
  236. foreground: `hsl(var(--${name}-foreground))`,
  237. // 鼠标悬停状态下的颜色,适用于按钮悬停时的背景色或边框色。
  238. hover: `hsl(var(--${name}-600))`,
  239. // 主色文本
  240. text: `hsl(var(--${name}-500))`,
  241. // 主色文本激活态
  242. 'text-active': `hsl(var(--${name}-700))`,
  243. // 主色文本悬浮态
  244. 'text-hover': `hsl(var(--${name}-600))`,
  245. };
  246. }