tailwind.config.js 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. const plugin = require('tailwindcss/plugin');
  2. const vanillaRTL = require('tailwindcss-vanilla-rtl');
  3. /**
  4. * Design Tokens
  5. */
  6. const { staticColors, transparencies } = require('./src/tokens/colors');
  7. const {
  8. generateColorVariables,
  9. generateThemeColorVariables,
  10. } = require('./src/tokens/colorVariables');
  11. const colorThemes = require('./src/tokens/colorThemes');
  12. const {
  13. fontFamily,
  14. fontSize,
  15. fontWeight,
  16. letterSpacing,
  17. lineHeight,
  18. listStyleType,
  19. typeScale,
  20. } = require('./src/tokens/typography');
  21. const { breakpoints } = require('./src/tokens/breakpoints');
  22. const {
  23. borderRadius,
  24. borderWidth,
  25. boxShadow,
  26. } = require('./src/tokens/objectStyles');
  27. const { spacing } = require('./src/tokens/spacing');
  28. /**
  29. * Plugins
  30. */
  31. const scrollbarThin = require('./src/plugins/scrollbarThin');
  32. /**
  33. * Functions
  34. * themeColors: For converting our design tokens into a format that tailwind accepts
  35. */
  36. const themeColors = Object.fromEntries(
  37. Object.entries(staticColors).map(([key, hues]) => {
  38. const shades = Object.fromEntries(
  39. Object.entries(hues).map(([k, shade]) => [
  40. k,
  41. `var(${shade.cssVariable})`,
  42. ]),
  43. );
  44. return [key, shades];
  45. }),
  46. );
  47. const lightThemeColors = colorThemes.light.reduce((colorTokens, category) => {
  48. Object.entries(category.tokens).forEach(([name, token]) => {
  49. // eslint-disable-next-line no-param-reassign
  50. colorTokens[name] = `var(${token.cssVariable})`;
  51. });
  52. return colorTokens;
  53. }, {});
  54. /**
  55. * Root Tailwind config, reusable for other projects.
  56. */
  57. module.exports = {
  58. prefix: 'w-',
  59. theme: {
  60. screens: {
  61. ...breakpoints,
  62. },
  63. colors: {
  64. ...themeColors,
  65. ...lightThemeColors,
  66. 'white-10': 'var(--w-color-white-10)',
  67. 'white-15': 'var(--w-color-white-15)',
  68. 'white-50': 'var(--w-color-white-50)',
  69. 'white-80': 'var(--w-color-white-80)',
  70. 'black-5': 'var(--w-color-black-5)',
  71. 'black-10': 'var(--w-color-black-10)',
  72. 'black-20': 'var(--w-color-black-20)',
  73. 'black-25': 'var(--w-color-black-25)',
  74. 'black-35': 'var(--w-color-black-35)',
  75. 'black-50': 'var(--w-color-black-50)',
  76. // Color keywords.
  77. 'inherit': 'inherit',
  78. 'current': 'currentColor',
  79. 'transparent': 'transparent',
  80. /* allow system colours https://www.w3.org/TR/css-color-4/#css-system-colors */
  81. 'LinkText': 'LinkText',
  82. 'ButtonText': 'ButtonText',
  83. },
  84. fontFamily: {
  85. sans: 'var(--w-font-sans)',
  86. mono: 'var(--w-font-mono)',
  87. },
  88. fontSize,
  89. fontWeight,
  90. lineHeight,
  91. listStyleType,
  92. letterSpacing,
  93. borderRadius,
  94. borderWidth,
  95. boxShadow: {
  96. ...boxShadow,
  97. none: 'none',
  98. },
  99. spacing: {
  100. ...spacing,
  101. 'slim-header': '50px',
  102. },
  103. extend: {
  104. outlineOffset: {
  105. inside: '-3px',
  106. },
  107. transitionProperty: {
  108. sidebar:
  109. 'inset-inline-start, padding-inline-start, width, transform, margin-top, min-height',
  110. },
  111. zIndex: {
  112. 'header': '100',
  113. 'sidebar': '110',
  114. 'sidebar-toggle': '120',
  115. 'dialog': '130',
  116. },
  117. keyframes: {
  118. 'fade-in': {
  119. '0%': { opacity: 0 },
  120. '100%': { opacity: 1 },
  121. },
  122. },
  123. animation: {
  124. 'fade-in': 'fade-in 150ms both',
  125. },
  126. },
  127. },
  128. plugins: [
  129. typeScale,
  130. vanillaRTL,
  131. scrollbarThin,
  132. /**
  133. * forced-colors media query for Windows High-Contrast mode support
  134. * See:
  135. * - https://developer.mozilla.org/en-US/docs/Web/CSS/@media/forced-colors
  136. * - https://github.com/tailwindlabs/tailwindcss/blob/v3.0.23/src/corePlugins.js#L168-L171
  137. */
  138. plugin(({ addVariant }) => {
  139. addVariant('forced-colors', '@media (forced-colors: active)');
  140. }),
  141. /**
  142. * TypeScale plugin.
  143. * This plugin generates component classes using tailwind's theme values for each object inside of the typeScale configuration.
  144. * We have the `w-` prefix added in the configuration for documentation purposes, it needs to be removed here before Tailwind adds it back.
  145. */
  146. plugin(({ addComponents, theme }) => {
  147. const scale = {};
  148. Object.entries(typeScale).forEach(([name, styles]) => {
  149. scale[`.${name.replace('w-', '')}`] = Object.fromEntries(
  150. Object.entries(styles).map(([key, value]) => [key, theme(value)]),
  151. );
  152. });
  153. addComponents(scale);
  154. }),
  155. /**
  156. * CSS Custom properties defined from our design tokens.
  157. */
  158. plugin(({ addBase }) => {
  159. addBase({
  160. /** Support for web components */
  161. ':root, :host': {
  162. '--w-font-sans': fontFamily.sans.join(', '),
  163. '--w-font-mono': fontFamily.mono.join(', '),
  164. '--w-density-factor': '1',
  165. ...transparencies,
  166. ...generateColorVariables(staticColors),
  167. ...generateThemeColorVariables(colorThemes.light),
  168. 'color-scheme': 'light',
  169. },
  170. '.w-theme-system': {
  171. '@media (prefers-color-scheme: dark)': {
  172. ...generateThemeColorVariables(colorThemes.dark),
  173. 'color-scheme': 'dark',
  174. },
  175. },
  176. '.w-theme-dark': {
  177. ...generateThemeColorVariables(colorThemes.dark),
  178. 'color-scheme': 'dark',
  179. },
  180. '.w-density-snug': {
  181. '--w-density-factor': '0.5',
  182. },
  183. });
  184. }),
  185. /** Support for aria-expanded=true variant */
  186. plugin(({ addVariant }) => {
  187. addVariant('expanded', '&[aria-expanded=true]');
  188. }),
  189. /** Support for increased contrast theme */
  190. plugin(({ addVariant }) => {
  191. addVariant('more-contrast', [
  192. '.contrast-more &',
  193. '@media (prefers-contrast: more) { .contrast-system & }',
  194. ]);
  195. }),
  196. ],
  197. corePlugins: {
  198. ...vanillaRTL.disabledCorePlugins,
  199. // Disable float and clear. Use Flexbox or Grid instead.
  200. float: false,
  201. clear: false,
  202. // Disable text-transform so we don’t rely on uppercasing text.
  203. textTransform: false,
  204. },
  205. variants: {
  206. extend: {
  207. backgroundColor: ['forced-colors'],
  208. width: ['forced-colors'],
  209. height: ['forced-colors'],
  210. },
  211. },
  212. };