You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

tailwind.config.js 4.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. import {readFileSync} from 'node:fs';
  2. import {env} from 'node:process';
  3. import {parse} from 'postcss';
  4. import plugin from 'tailwindcss/plugin.js';
  5. const isProduction = env.NODE_ENV !== 'development';
  6. function extractRootVars(css) {
  7. const root = parse(css);
  8. const vars = new Set();
  9. root.walkRules((rule) => {
  10. if (rule.selector !== ':root') return;
  11. rule.each((decl) => {
  12. if (decl.value && decl.prop.startsWith('--')) {
  13. vars.add(decl.prop.substring(2));
  14. }
  15. });
  16. });
  17. return Array.from(vars);
  18. }
  19. const vars = extractRootVars([
  20. readFileSync(new URL('web_src/css/themes/theme-gitea-light.css', import.meta.url), 'utf8'),
  21. readFileSync(new URL('web_src/css/themes/theme-gitea-dark.css', import.meta.url), 'utf8'),
  22. ].join('\n'));
  23. export default {
  24. prefix: 'tw-',
  25. important: true, // the frameworks are mixed together, so tailwind needs to override other framework's styles
  26. content: [
  27. isProduction && '!./templates/devtest/**/*',
  28. isProduction && '!./web_src/js/standalone/devtest.js',
  29. '!./templates/swagger/v1_json.tmpl',
  30. '!./templates/user/auth/oidc_wellknown.tmpl',
  31. '!**/*_test.go',
  32. '!./modules/{public,options,templates}/bindata.go',
  33. './{build,models,modules,routers,services}/**/*.go',
  34. './templates/**/*.tmpl',
  35. './web_src/js/**/*.{js,vue}',
  36. ].filter(Boolean),
  37. blocklist: [
  38. // classes that don't work without CSS variables from "@tailwind base" which we don't use
  39. 'transform', 'shadow', 'ring', 'blur', 'grayscale', 'invert', '!invert', 'filter', '!filter',
  40. 'backdrop-filter',
  41. // we use double-class tw-hidden defined in web_src/css/helpers.css for increased specificity
  42. 'hidden',
  43. // unneeded classes
  44. '[-a-zA-Z:0-9_.]',
  45. ],
  46. theme: {
  47. colors: {
  48. // make `tw-bg-red` etc work with our CSS variables
  49. ...Object.fromEntries(vars.filter((prop) => prop.startsWith('color-')).map((prop) => {
  50. const color = prop.substring(6);
  51. return [color, `var(--color-${color})`];
  52. })),
  53. inherit: 'inherit',
  54. current: 'currentcolor',
  55. transparent: 'transparent',
  56. },
  57. borderRadius: {
  58. 'none': '0',
  59. 'sm': '2px',
  60. 'DEFAULT': 'var(--border-radius)', // 4px
  61. 'md': 'var(--border-radius-medium)', // 6px
  62. 'lg': '8px',
  63. 'xl': '12px',
  64. '2xl': '16px',
  65. '3xl': '24px',
  66. 'full': 'var(--border-radius-full)',
  67. },
  68. fontFamily: {
  69. sans: 'var(--fonts-regular)',
  70. mono: 'var(--fonts-monospace)',
  71. },
  72. fontWeight: {
  73. light: 'var(--font-weight-light)',
  74. normal: 'var(--font-weight-normal)',
  75. medium: 'var(--font-weight-medium)',
  76. semibold: 'var(--font-weight-semibold)',
  77. bold: 'var(--font-weight-bold)',
  78. },
  79. fontSize: { // not using `rem` units because our root is currently 14px
  80. 'xs': '12px',
  81. 'sm': '14px',
  82. 'base': '16px',
  83. 'lg': '18px',
  84. 'xl': '20px',
  85. '2xl': '24px',
  86. '3xl': '30px',
  87. '4xl': '36px',
  88. '5xl': '48px',
  89. '6xl': '60px',
  90. '7xl': '72px',
  91. '8xl': '96px',
  92. '9xl': '128px',
  93. ...Object.fromEntries(Array.from({length: 100}, (_, i) => {
  94. return [`${i}`, `${i === 0 ? '0' : `${i}px`}`];
  95. })),
  96. },
  97. },
  98. plugins: [
  99. plugin(({addUtilities}) => {
  100. addUtilities({
  101. // tw-hidden must win all other "display: xxx !important" classes to get the chance to "hide" an element.
  102. // do not use:
  103. // * "[hidden]" attribute: it's too weak, can not be applied to an element with "display: flex"
  104. // * ".hidden" class: it has been polluted by Fomantic UI in many cases
  105. // * inline style="display: none": it's difficult to tweak
  106. // * jQuery's show/hide/toggle: it can not show/hide elements with "display: xxx !important"
  107. // only use:
  108. // * this ".tw-hidden" class
  109. // * showElem/hideElem/toggleElem functions in "utils/dom.js"
  110. '.hidden.hidden': {
  111. 'display': 'none',
  112. },
  113. // proposed class from https://github.com/tailwindlabs/tailwindcss/pull/12128
  114. '.break-anywhere': {
  115. 'overflow-wrap': 'anywhere',
  116. },
  117. });
  118. }),
  119. ],
  120. };