|
| 1 | +const postcss = require('postcss') |
| 2 | + |
| 3 | +const defaults = { |
| 4 | + rootSelector: ':root', |
| 5 | + unit: 'lh', |
| 6 | + lineHeight: 1.5 |
| 7 | +} |
| 8 | + |
| 9 | +module.exports = postcss.plugin('lh', (opts = defaults) => { |
| 10 | + const options = Object.assign(defaults, opts) |
| 11 | + |
| 12 | + return css => { |
| 13 | + const lineHeight = getLineHeight(css, options) |
| 14 | + const lhReg = new RegExp('\\d*\\.?\\d+' + options.unit, 'gi') |
| 15 | + |
| 16 | + css.replaceValues(lhReg, { fast: options.unit }, (val) => { |
| 17 | + return lhToRem(parseFloat(val), lineHeight) |
| 18 | + }) |
| 19 | + } |
| 20 | +}) |
| 21 | + |
| 22 | +function getLineHeight (css, opts) { |
| 23 | + // Start with the default line-height |
| 24 | + let lineHeight = opts.lineHeight |
| 25 | + |
| 26 | + // Walk over all the root selectors |
| 27 | + css.walkRules(opts.rootSelector, rule => { |
| 28 | + // Omit the process if the selector is inside a print media query |
| 29 | + if (rule.parent && rule.parent.params === 'print') return |
| 30 | + |
| 31 | + // Walk over all the font or line-height properties |
| 32 | + rule.walkDecls(/font$|line-height/, decl => { |
| 33 | + // Matches {$1:font-size}{$2:unit}/{$3:line-height} when the property is 'font' |
| 34 | + const fontProps = decl.value.match(/(\d+|\d+?\.\d+)(r?em|px|%)(?:\s*\/\s*)(\d+|\d+?\.\d+)\s+/) || [] |
| 35 | + |
| 36 | + lineHeight = fontProps[3] || decl.value |
| 37 | + }) |
| 38 | + }) |
| 39 | + |
| 40 | + return lineHeight |
| 41 | +} |
| 42 | + |
| 43 | +function lhToRem(val, lineHeight) { |
| 44 | + return parseFloat((lineHeight * val).toFixed(3)) + 'rem' |
| 45 | +} |
0 commit comments