responsive-font-unified.js 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. /**
  2. * 统一的UnoCSS响应式字体插件
  3. * 集成了静态规则和动态规则,提供完整的响应式字体解决方案
  4. */
  5. import { definePreset } from 'unocss'
  6. export const responsiveFontUnifiedPreset = definePreset(() => {
  7. // 静态规则 - 预定义常用字体大小,提高性能
  8. const staticFontSizeRules = [
  9. // 生成常用的px字体大小规则
  10. ['text-10px', { 'font-size': 'calc(10px * var(--font-scale, 1)) !important' }],
  11. ['text-11px', { 'font-size': 'calc(11px * var(--font-scale, 1)) !important' }],
  12. ['text-12px', { 'font-size': 'calc(12px * var(--font-scale, 1)) !important' }],
  13. ['text-13px', { 'font-size': 'calc(13px * var(--font-scale, 1)) !important' }],
  14. ['text-14px', { 'font-size': 'calc(14px * var(--font-scale, 1)) !important' }],
  15. ['text-15px', { 'font-size': 'calc(15px * var(--font-scale, 1)) !important' }],
  16. ['text-16px', { 'font-size': 'calc(16px * var(--font-scale, 1)) !important' }],
  17. ['text-17px', { 'font-size': 'calc(17px * var(--font-scale, 1)) !important' }],
  18. ['text-18px', { 'font-size': 'calc(18px * var(--font-scale, 1)) !important' }],
  19. ['text-19px', { 'font-size': 'calc(19px * var(--font-scale, 1)) !important' }],
  20. ['text-20px', { 'font-size': 'calc(20px * var(--font-scale, 1)) !important' }],
  21. ['text-21px', { 'font-size': 'calc(21px * var(--font-scale, 1)) !important' }],
  22. ['text-22px', { 'font-size': 'calc(22px * var(--font-scale, 1)) !important' }],
  23. ['text-23px', { 'font-size': 'calc(23px * var(--font-scale, 1)) !important' }],
  24. ['text-24px', { 'font-size': 'calc(24px * var(--font-scale, 1)) !important' }],
  25. ['text-25px', { 'font-size': 'calc(25px * var(--font-scale, 1)) !important' }],
  26. ['text-26px', { 'font-size': 'calc(26px * var(--font-scale, 1)) !important' }],
  27. ['text-27px', { 'font-size': 'calc(27px * var(--font-scale, 1)) !important' }],
  28. ['text-28px', { 'font-size': 'calc(28px * var(--font-scale, 1)) !important' }],
  29. ['text-29px', { 'font-size': 'calc(29px * var(--font-scale, 1)) !important' }],
  30. ['text-30px', { 'font-size': 'calc(30px * var(--font-scale, 1)) !important' }],
  31. ['text-31px', { 'font-size': 'calc(31px * var(--font-scale, 1)) !important' }],
  32. ['text-32px', { 'font-size': 'calc(32px * var(--font-scale, 1)) !important' }],
  33. ['text-33px', { 'font-size': 'calc(33px * var(--font-scale, 1)) !important' }],
  34. ['text-34px', { 'font-size': 'calc(34px * var(--font-scale, 1)) !important' }],
  35. ['text-35px', { 'font-size': 'calc(35px * var(--font-scale, 1)) !important' }],
  36. ['text-36px', { 'font-size': 'calc(36px * var(--font-scale, 1)) !important' }],
  37. ['text-10', { 'font-size': 'calc(10px * var(--font-scale, 1)) !important' }],
  38. ['text-11', { 'font-size': 'calc(11px * var(--font-scale, 1)) !important' }],
  39. ['text-12', { 'font-size': 'calc(12px * var(--font-scale, 1)) !important' }],
  40. ['text-13', { 'font-size': 'calc(13px * var(--font-scale, 1)) !important' }],
  41. ['text-14', { 'font-size': 'calc(14px * var(--font-scale, 1)) !important' }],
  42. ['text-15', { 'font-size': 'calc(15px * var(--font-scale, 1)) !important' }],
  43. ['text-16', { 'font-size': 'calc(16px * var(--font-scale, 1)) !important' }],
  44. ['text-17', { 'font-size': 'calc(17px * var(--font-scale, 1)) !important' }],
  45. ['text-18', { 'font-size': 'calc(18px * var(--font-scale, 1)) !important' }],
  46. ['text-19', { 'font-size': 'calc(19px * var(--font-scale, 1)) !important' }],
  47. ['text-20', { 'font-size': 'calc(20px * var(--font-scale, 1)) !important' }],
  48. ['text-21', { 'font-size': 'calc(21px * var(--font-scale, 1)) !important' }],
  49. ['text-22', { 'font-size': 'calc(22px * var(--font-scale, 1)) !important' }],
  50. ['text-23', { 'font-size': 'calc(23px * var(--font-scale, 1)) !important' }],
  51. ['text-24', { 'font-size': 'calc(24px * var(--font-scale, 1)) !important' }],
  52. ['text-25', { 'font-size': 'calc(25px * var(--font-scale, 1)) !important' }],
  53. ['text-26', { 'font-size': 'calc(26px * var(--font-scale, 1)) !important' }],
  54. ['text-27', { 'font-size': 'calc(27px * var(--font-scale, 1)) !important' }],
  55. ['text-28', { 'font-size': 'calc(28px * var(--font-scale, 1)) !important' }],
  56. ['text-29', { 'font-size': 'calc(29px * var(--font-scale, 1)) !important' }],
  57. ['text-30', { 'font-size': 'calc(30px * var(--font-scale, 1)) !important' }],
  58. ['text-31', { 'font-size': 'calc(31px * var(--font-scale, 1)) !important' }],
  59. ['text-32', { 'font-size': 'calc(32px * var(--font-scale, 1)) !important' }],
  60. ['text-33', { 'font-size': 'calc(33px * var(--font-scale, 1)) !important' }],
  61. ['text-34', { 'font-size': 'calc(34px * var(--font-scale, 1)) !important' }],
  62. ['text-35', { 'font-size': 'calc(35px * var(--font-scale, 1)) !important' }],
  63. ['text-36', { 'font-size': 'calc(36px * var(--font-scale, 1)) !important' }],
  64. // 预定义尺寸
  65. ['text-xs', { 'font-size': 'calc(12px * var(--font-scale, 1)) !important' }],
  66. ['text-sm', { 'font-size': 'calc(14px * var(--font-scale, 1)) !important' }],
  67. ['text-base', { 'font-size': 'calc(16px * var(--font-scale, 1)) !important' }],
  68. ['text-lg', { 'font-size': 'calc(18px * var(--font-scale, 1)) !important' }],
  69. ['text-xl', { 'font-size': 'calc(20px * var(--font-scale, 1)) !important' }],
  70. ]
  71. // 静态行高规则
  72. const staticLineHeightRules = [
  73. ['leading-12', { 'line-height': 'calc(12px * var(--font-scale, 1)) !important' }],
  74. ['leading-14', { 'line-height': 'calc(14px * var(--font-scale, 1)) !important' }],
  75. ['leading-16', { 'line-height': 'calc(16px * var(--font-scale, 1)) !important' }],
  76. ['leading-18', { 'line-height': 'calc(18px * var(--font-scale, 1)) !important' }],
  77. ['leading-20', { 'line-height': 'calc(20px * var(--font-scale, 1)) !important' }],
  78. ['leading-22', { 'line-height': 'calc(22px * var(--font-scale, 1)) !important' }],
  79. ['leading-24', { 'line-height': 'calc(24px * var(--font-scale, 1)) !important' }],
  80. ['leading-26', { 'line-height': 'calc(26px * var(--font-scale, 1)) !important' }],
  81. ['leading-28', { 'line-height': 'calc(28px * var(--font-scale, 1)) !important' }],
  82. ['leading-30', { 'line-height': 'calc(30px * var(--font-scale, 1)) !important' }],
  83. ['leading-32', { 'line-height': 'calc(32px * var(--font-scale, 1)) !important' }],
  84. ]
  85. // 动态规则 - 处理任意数值,提供更大的灵活性
  86. const dynamicRules = [
  87. // 处理text-xs, text-sm等预定义尺寸
  88. [/^text-(xs|sm|base|lg|xl)$/, ([_, size]) => {
  89. const sizes = {
  90. xs: '12px',
  91. sm: '14px',
  92. base: '16px',
  93. lg: '18px',
  94. xl: '20px',
  95. }
  96. if (sizes[size]) {
  97. return {
  98. 'font-size': `calc(${sizes[size]} * var(--font-scale, 1)) !important`,
  99. }
  100. }
  101. }],
  102. // 处理line-height
  103. [/^leading-(\d+)$/, ([_, size]) => {
  104. const value = Number.parseInt(size)
  105. if (value > 0) {
  106. return {
  107. 'line-height': `calc(${value}px * var(--font-scale, 1)) !important`,
  108. }
  109. }
  110. }],
  111. ]
  112. // 合并所有规则 - 静态规则优先,动态规则作为补充
  113. const allRules = [...staticFontSizeRules, ...staticLineHeightRules, ...dynamicRules]
  114. return {
  115. name: 'responsive-font-unified-preset',
  116. rules: allRules,
  117. // 快捷方式
  118. shortcuts: [
  119. // 响应式标题
  120. ['responsive-h1', 'text-32px font-bold'],
  121. ['responsive-h2', 'text-24px font-bold'],
  122. ['responsive-h3', 'text-18px font-semibold'],
  123. ['responsive-h4', 'text-16px font-semibold'],
  124. ['responsive-h5', 'text-14px font-medium'],
  125. ['responsive-h6', 'text-12px font-medium'],
  126. // 响应式正文
  127. ['responsive-text', 'text-14px'],
  128. ['responsive-text-sm', 'text-12px'],
  129. ['responsive-text-lg', 'text-16px'],
  130. // 响应式辅助文本
  131. ['responsive-caption', 'text-12px text-gray-500'],
  132. ],
  133. }
  134. })
  135. export default responsiveFontUnifiedPreset