Include pixel equivalents in more places (#775)
* Show pixel equivalents for more `rem`/`em` values * Add pixel equivalents to media query variant completionsmaster
parent
5e9cce64ef
commit
460d921ca3
|
@ -6,6 +6,9 @@
|
||||||
"": {
|
"": {
|
||||||
"name": "root",
|
"name": "root",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@csstools/css-parser-algorithms": "2.1.1",
|
||||||
|
"@csstools/css-tokenizer": "2.1.1",
|
||||||
|
"@csstools/media-query-list-parser": "2.0.4",
|
||||||
"@parcel/watcher": "2.0.3",
|
"@parcel/watcher": "2.0.3",
|
||||||
"@tailwindcss/aspect-ratio": "0.4.2",
|
"@tailwindcss/aspect-ratio": "0.4.2",
|
||||||
"@tailwindcss/container-queries": "0.1.0",
|
"@tailwindcss/container-queries": "0.1.0",
|
||||||
|
@ -46,6 +49,7 @@
|
||||||
"postcss": "8.3.9",
|
"postcss": "8.3.9",
|
||||||
"postcss-load-config": "3.0.1",
|
"postcss-load-config": "3.0.1",
|
||||||
"postcss-selector-parser": "6.0.2",
|
"postcss-selector-parser": "6.0.2",
|
||||||
|
"postcss-value-parser": "4.2.0",
|
||||||
"prettier": "2.3.0",
|
"prettier": "2.3.0",
|
||||||
"resolve": "1.20.0",
|
"resolve": "1.20.0",
|
||||||
"rimraf": "3.0.2",
|
"rimraf": "3.0.2",
|
||||||
|
@ -1716,6 +1720,49 @@
|
||||||
"node": ">=0.1.95"
|
"node": ">=0.1.95"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@csstools/css-parser-algorithms": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.1.1.tgz",
|
||||||
|
"integrity": "sha512-viRnRh02AgO4mwIQb2xQNJju0i+Fh9roNgmbR5xEuG7J3TGgxjnE95HnBLgsFJOJOksvcfxOUCgODcft6Y07cA==",
|
||||||
|
"engines": {
|
||||||
|
"node": "^14 || ^16 || >=18"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/csstools"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@csstools/css-tokenizer": "^2.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@csstools/css-tokenizer": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-2.1.1.tgz",
|
||||||
|
"integrity": "sha512-GbrTj2Z8MCTUv+52GE0RbFGM527xuXZ0Xa5g0Z+YN573uveS4G0qi6WNOMyz3yrFM/jaILTTwJ0+umx81EzqfA==",
|
||||||
|
"engines": {
|
||||||
|
"node": "^14 || ^16 || >=18"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/csstools"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@csstools/media-query-list-parser": {
|
||||||
|
"version": "2.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-2.0.4.tgz",
|
||||||
|
"integrity": "sha512-GyYot6jHgcSDZZ+tLSnrzkR7aJhF2ZW6d+CXH66mjy5WpAQhZD4HDke2OQ36SivGRWlZJpAz7TzbW6OKlEpxAA==",
|
||||||
|
"engines": {
|
||||||
|
"node": "^14 || ^16 || >=18"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/csstools"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@csstools/css-parser-algorithms": "^2.1.1",
|
||||||
|
"@csstools/css-tokenizer": "^2.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@evocateur/libnpmaccess": {
|
"node_modules/@evocateur/libnpmaccess": {
|
||||||
"version": "3.1.2",
|
"version": "3.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/@evocateur/libnpmaccess/-/libnpmaccess-3.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/@evocateur/libnpmaccess/-/libnpmaccess-3.1.2.tgz",
|
||||||
|
@ -22936,6 +22983,23 @@
|
||||||
"minimist": "^1.2.0"
|
"minimist": "^1.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@csstools/css-parser-algorithms": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.1.1.tgz",
|
||||||
|
"integrity": "sha512-viRnRh02AgO4mwIQb2xQNJju0i+Fh9roNgmbR5xEuG7J3TGgxjnE95HnBLgsFJOJOksvcfxOUCgODcft6Y07cA==",
|
||||||
|
"requires": {}
|
||||||
|
},
|
||||||
|
"@csstools/css-tokenizer": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-2.1.1.tgz",
|
||||||
|
"integrity": "sha512-GbrTj2Z8MCTUv+52GE0RbFGM527xuXZ0Xa5g0Z+YN573uveS4G0qi6WNOMyz3yrFM/jaILTTwJ0+umx81EzqfA=="
|
||||||
|
},
|
||||||
|
"@csstools/media-query-list-parser": {
|
||||||
|
"version": "2.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-2.0.4.tgz",
|
||||||
|
"integrity": "sha512-GyYot6jHgcSDZZ+tLSnrzkR7aJhF2ZW6d+CXH66mjy5WpAQhZD4HDke2OQ36SivGRWlZJpAz7TzbW6OKlEpxAA==",
|
||||||
|
"requires": {}
|
||||||
|
},
|
||||||
"@evocateur/libnpmaccess": {
|
"@evocateur/libnpmaccess": {
|
||||||
"version": "3.1.2",
|
"version": "3.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/@evocateur/libnpmaccess/-/libnpmaccess-3.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/@evocateur/libnpmaccess/-/libnpmaccess-3.1.2.tgz",
|
||||||
|
|
|
@ -14,6 +14,9 @@
|
||||||
"prepublishOnly": "npm run build"
|
"prepublishOnly": "npm run build"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@csstools/media-query-list-parser": "2.0.4",
|
||||||
|
"@csstools/css-parser-algorithms": "2.1.1",
|
||||||
|
"@csstools/css-tokenizer": "2.1.1",
|
||||||
"@types/culori": "^2.0.0",
|
"@types/culori": "^2.0.0",
|
||||||
"@types/moo": "0.5.3",
|
"@types/moo": "0.5.3",
|
||||||
"@types/semver": "7.3.10",
|
"@types/semver": "7.3.10",
|
||||||
|
@ -28,6 +31,7 @@
|
||||||
"moo": "0.5.1",
|
"moo": "0.5.1",
|
||||||
"postcss": "8.3.9",
|
"postcss": "8.3.9",
|
||||||
"postcss-selector-parser": "6.0.2",
|
"postcss-selector-parser": "6.0.2",
|
||||||
|
"postcss-value-parser": "4.2.0",
|
||||||
"semver": "7.3.7",
|
"semver": "7.3.7",
|
||||||
"sift-string": "0.0.2",
|
"sift-string": "0.0.2",
|
||||||
"stringify-object": "3.3.0",
|
"stringify-object": "3.3.0",
|
||||||
|
|
|
@ -28,11 +28,14 @@ import { ensureArray } from './util/array'
|
||||||
import { getClassAttributeLexer, getComputedClassAttributeLexer } from './util/lexers'
|
import { getClassAttributeLexer, getComputedClassAttributeLexer } from './util/lexers'
|
||||||
import { validateApply } from './util/validateApply'
|
import { validateApply } from './util/validateApply'
|
||||||
import { flagEnabled } from './util/flagEnabled'
|
import { flagEnabled } from './util/flagEnabled'
|
||||||
import { remToPx } from './util/remToPx'
|
|
||||||
import * as jit from './util/jit'
|
import * as jit from './util/jit'
|
||||||
import { getVariantsFromClassName } from './util/getVariantsFromClassName'
|
import { getVariantsFromClassName } from './util/getVariantsFromClassName'
|
||||||
import * as culori from 'culori'
|
import * as culori from 'culori'
|
||||||
import Regex from 'becke-ch--regex--s0-0-v1--base--pl--lib'
|
import Regex from 'becke-ch--regex--s0-0-v1--base--pl--lib'
|
||||||
|
import {
|
||||||
|
addPixelEquivalentsToMediaQuery,
|
||||||
|
addPixelEquivalentsToValue,
|
||||||
|
} from './util/pixelEquivalents'
|
||||||
|
|
||||||
let isUtil = (className) =>
|
let isUtil = (className) =>
|
||||||
Array.isArray(className.__info)
|
Array.isArray(className.__info)
|
||||||
|
@ -43,6 +46,7 @@ export function completionsFromClassList(
|
||||||
state: State,
|
state: State,
|
||||||
classList: string,
|
classList: string,
|
||||||
classListRange: Range,
|
classListRange: Range,
|
||||||
|
rootFontSize: number,
|
||||||
filter?: (item: CompletionItem) => boolean,
|
filter?: (item: CompletionItem) => boolean,
|
||||||
context?: CompletionContext
|
context?: CompletionContext
|
||||||
): CompletionList {
|
): CompletionList {
|
||||||
|
@ -190,7 +194,10 @@ export function completionsFromClassList(
|
||||||
items.push(
|
items.push(
|
||||||
variantItem({
|
variantItem({
|
||||||
label: `${variant.name}${sep}`,
|
label: `${variant.name}${sep}`,
|
||||||
detail: variant.selectors().join(', '),
|
detail: variant
|
||||||
|
.selectors()
|
||||||
|
.map((selector) => addPixelEquivalentsToMediaQuery(selector, rootFontSize))
|
||||||
|
.join(', '),
|
||||||
textEditText: resultingVariants[resultingVariants.length - 1] + sep,
|
textEditText: resultingVariants[resultingVariants.length - 1] + sep,
|
||||||
additionalTextEdits:
|
additionalTextEdits:
|
||||||
shouldSortVariants && resultingVariants.length > 1
|
shouldSortVariants && resultingVariants.length > 1
|
||||||
|
@ -430,10 +437,9 @@ async function provideClassAttributeCompletions(
|
||||||
end: position,
|
end: position,
|
||||||
})
|
})
|
||||||
|
|
||||||
let matches = matchClassAttributes(
|
let settings = (await state.editor.getConfiguration(document.uri)).tailwindCSS
|
||||||
str,
|
|
||||||
(await state.editor.getConfiguration(document.uri)).tailwindCSS.classAttributes
|
let matches = matchClassAttributes(str, settings.classAttributes)
|
||||||
)
|
|
||||||
|
|
||||||
if (matches.length === 0) {
|
if (matches.length === 0) {
|
||||||
return null
|
return null
|
||||||
|
@ -470,6 +476,7 @@ async function provideClassAttributeCompletions(
|
||||||
},
|
},
|
||||||
end: position,
|
end: position,
|
||||||
},
|
},
|
||||||
|
settings.rootFontSize,
|
||||||
undefined,
|
undefined,
|
||||||
context
|
context
|
||||||
)
|
)
|
||||||
|
@ -544,6 +551,7 @@ async function provideCustomClassNameCompletions(
|
||||||
},
|
},
|
||||||
end: position,
|
end: position,
|
||||||
},
|
},
|
||||||
|
settings.tailwindCSS.rootFontSize,
|
||||||
undefined,
|
undefined,
|
||||||
context
|
context
|
||||||
)
|
)
|
||||||
|
@ -555,12 +563,13 @@ async function provideCustomClassNameCompletions(
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
function provideAtApplyCompletions(
|
async function provideAtApplyCompletions(
|
||||||
state: State,
|
state: State,
|
||||||
document: TextDocument,
|
document: TextDocument,
|
||||||
position: Position,
|
position: Position,
|
||||||
context?: CompletionContext
|
context?: CompletionContext
|
||||||
): CompletionList {
|
): Promise<CompletionList> {
|
||||||
|
let settings = (await state.editor.getConfiguration(document.uri)).tailwindCSS
|
||||||
let str = document.getText({
|
let str = document.getText({
|
||||||
start: { line: Math.max(position.line - 30, 0), character: 0 },
|
start: { line: Math.max(position.line - 30, 0), character: 0 },
|
||||||
end: position,
|
end: position,
|
||||||
|
@ -584,6 +593,7 @@ function provideAtApplyCompletions(
|
||||||
},
|
},
|
||||||
end: position,
|
end: position,
|
||||||
},
|
},
|
||||||
|
settings.rootFontSize,
|
||||||
(item) => {
|
(item) => {
|
||||||
if (item.kind === 9) {
|
if (item.kind === 9) {
|
||||||
return (
|
return (
|
||||||
|
@ -1318,13 +1328,18 @@ async function provideEmmetCompletions(
|
||||||
const parts = emmetItems.items[0].label.split('.')
|
const parts = emmetItems.items[0].label.split('.')
|
||||||
if (parts.length < 2) return null
|
if (parts.length < 2) return null
|
||||||
|
|
||||||
return completionsFromClassList(state, parts[parts.length - 1], {
|
return completionsFromClassList(
|
||||||
start: {
|
state,
|
||||||
line: position.line,
|
parts[parts.length - 1],
|
||||||
character: position.character - parts[parts.length - 1].length,
|
{
|
||||||
|
start: {
|
||||||
|
line: position.line,
|
||||||
|
character: position.character - parts[parts.length - 1].length,
|
||||||
|
},
|
||||||
|
end: position,
|
||||||
},
|
},
|
||||||
end: position,
|
settings.tailwindCSS.rootFontSize
|
||||||
})
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function doComplete(
|
export async function doComplete(
|
||||||
|
@ -1444,10 +1459,10 @@ function stringifyDecls(obj: any, settings: Settings): string {
|
||||||
.map((prop) =>
|
.map((prop) =>
|
||||||
ensureArray(obj[prop])
|
ensureArray(obj[prop])
|
||||||
.map((value) => {
|
.map((value) => {
|
||||||
const px = settings.tailwindCSS.showPixelEquivalents
|
if (settings.tailwindCSS.showPixelEquivalents) {
|
||||||
? remToPx(value, settings.tailwindCSS.rootFontSize)
|
value = addPixelEquivalentsToValue(value, settings.tailwindCSS.rootFontSize)
|
||||||
: undefined
|
}
|
||||||
return `${prop}: ${value}${px ? `/* ${px} */` : ''};`
|
return `${prop}: ${value};`
|
||||||
})
|
})
|
||||||
.join(' ')
|
.join(' ')
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { State } from './state'
|
import { State } from './state'
|
||||||
import type { Container, Document, Root, Rule, Node, AtRule } from 'postcss'
|
import type { Container, Document, Root, Rule, Node, AtRule } from 'postcss'
|
||||||
import { remToPx } from './remToPx'
|
import { addPixelEquivalentsToCss, addPixelEquivalentsToValue } from './pixelEquivalents'
|
||||||
|
|
||||||
export function bigSign(bigIntValue) {
|
export function bigSign(bigIntValue) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
|
@ -41,17 +41,13 @@ export async function stringifyRoot(state: State, root: Root, uri?: string): Pro
|
||||||
node.remove()
|
node.remove()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
let css = clone.toString()
|
||||||
|
|
||||||
if (settings.tailwindCSS.showPixelEquivalents) {
|
if (settings.tailwindCSS.showPixelEquivalents) {
|
||||||
clone.walkDecls((decl) => {
|
css = addPixelEquivalentsToCss(css, settings.tailwindCSS.rootFontSize)
|
||||||
let px = remToPx(decl.value, settings.tailwindCSS.rootFontSize)
|
|
||||||
if (px) {
|
|
||||||
decl.value = `${decl.value}/* ${px} */`
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return clone
|
return css
|
||||||
.toString()
|
|
||||||
.replace(/([^;{}\s])(\n\s*})/g, (_match, before, after) => `${before};${after}`)
|
.replace(/([^;{}\s])(\n\s*})/g, (_match, before, after) => `${before};${after}`)
|
||||||
.replace(/^(?: )+/gm, (indent: string) =>
|
.replace(/^(?: )+/gm, (indent: string) =>
|
||||||
' '.repeat((indent.length / 4) * settings.editor.tabSize)
|
' '.repeat((indent.length / 4) * settings.editor.tabSize)
|
||||||
|
@ -70,10 +66,10 @@ export async function stringifyDecls(state: State, rule: Rule, uri?: string): Pr
|
||||||
|
|
||||||
let result = []
|
let result = []
|
||||||
rule.walkDecls(({ prop, value }) => {
|
rule.walkDecls(({ prop, value }) => {
|
||||||
let px = settings.tailwindCSS.showPixelEquivalents
|
if (settings.tailwindCSS.showPixelEquivalents) {
|
||||||
? remToPx(value, settings.tailwindCSS.rootFontSize)
|
value = addPixelEquivalentsToValue(value, settings.tailwindCSS.rootFontSize)
|
||||||
: undefined
|
}
|
||||||
result.push(`${prop}: ${value}${px ? `/* ${px} */` : ''};`)
|
result.push(`${prop}: ${value};`)
|
||||||
})
|
})
|
||||||
return result.join(' ')
|
return result.join(' ')
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,147 @@
|
||||||
|
import type { Plugin } from 'postcss'
|
||||||
|
import parseValue from 'postcss-value-parser'
|
||||||
|
import { parse as parseMediaQueryList } from '@csstools/media-query-list-parser'
|
||||||
|
import postcss from 'postcss'
|
||||||
|
import { isTokenNode } from '@csstools/css-parser-algorithms'
|
||||||
|
|
||||||
|
type Comment = { index: number; value: string }
|
||||||
|
|
||||||
|
export function addPixelEquivalentsToValue(value: string, rootFontSize: number): string {
|
||||||
|
if (!value.includes('rem')) {
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
parseValue(value).walk((node) => {
|
||||||
|
if (node.type !== 'word') {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
let unit = parseValue.unit(node.value)
|
||||||
|
if (!unit || unit.unit !== 'rem') {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
let commentStr = `/* ${parseFloat(unit.number) * rootFontSize}px */`
|
||||||
|
value = value.slice(0, node.sourceEndIndex) + commentStr + value.slice(node.sourceEndIndex)
|
||||||
|
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
export function addPixelEquivalentsToCss(css: string, rootFontSize: number): string {
|
||||||
|
if (!css.includes('em')) {
|
||||||
|
return css
|
||||||
|
}
|
||||||
|
|
||||||
|
let comments: Comment[] = []
|
||||||
|
|
||||||
|
try {
|
||||||
|
postcss([postcssPlugin({ comments, rootFontSize })]).process(css, { from: undefined }).css
|
||||||
|
} catch {
|
||||||
|
return css
|
||||||
|
}
|
||||||
|
|
||||||
|
return applyComments(css, comments)
|
||||||
|
}
|
||||||
|
|
||||||
|
function applyComments(str: string, comments: Comment[]): string {
|
||||||
|
let offset = 0
|
||||||
|
|
||||||
|
for (let comment of comments) {
|
||||||
|
let index = comment.index + offset
|
||||||
|
let commentStr = `/* ${comment.value} */`
|
||||||
|
str = str.slice(0, index) + commentStr + str.slice(index)
|
||||||
|
offset += commentStr.length
|
||||||
|
}
|
||||||
|
|
||||||
|
return str
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPixelEquivalentsForMediaQuery(params: string, rootFontSize: number): Comment[] {
|
||||||
|
let comments: Comment[] = []
|
||||||
|
|
||||||
|
try {
|
||||||
|
parseMediaQueryList(params).forEach((mediaQuery) => {
|
||||||
|
mediaQuery.walk(({ node }) => {
|
||||||
|
if (
|
||||||
|
isTokenNode(node) &&
|
||||||
|
node.type === 'token' &&
|
||||||
|
node.value[0] === 'dimension-token' &&
|
||||||
|
(node.value[4].type === 'integer' || node.value[4].type === 'number') &&
|
||||||
|
(node.value[4].unit === 'rem' || node.value[4].unit === 'em')
|
||||||
|
) {
|
||||||
|
comments.push({
|
||||||
|
index: params.length - (params.length - node.value[3] - 1),
|
||||||
|
value: `${node.value[4].value * rootFontSize}px`,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
} catch {}
|
||||||
|
|
||||||
|
return comments
|
||||||
|
}
|
||||||
|
|
||||||
|
export function addPixelEquivalentsToMediaQuery(query: string, rootFontSize: number): string {
|
||||||
|
return query.replace(/(?<=^\s*@media\s*).*?$/, (params) => {
|
||||||
|
let comments = getPixelEquivalentsForMediaQuery(params, rootFontSize)
|
||||||
|
return applyComments(params, comments)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function postcssPlugin({
|
||||||
|
comments,
|
||||||
|
rootFontSize,
|
||||||
|
}: {
|
||||||
|
comments: Comment[]
|
||||||
|
rootFontSize: number
|
||||||
|
}): Plugin {
|
||||||
|
return {
|
||||||
|
postcssPlugin: 'plugin',
|
||||||
|
AtRule: {
|
||||||
|
media(atRule) {
|
||||||
|
if (!atRule.params.includes('em')) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
comments.push(
|
||||||
|
...getPixelEquivalentsForMediaQuery(atRule.params, rootFontSize).map(
|
||||||
|
({ index, value }) => ({
|
||||||
|
index: index + atRule.source.start.offset + `@media${atRule.raws.afterName}`.length,
|
||||||
|
value,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Declaration(decl) {
|
||||||
|
if (!decl.value.includes('rem')) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
parseValue(decl.value).walk((node) => {
|
||||||
|
if (node.type !== 'word') {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
let unit = parseValue.unit(node.value)
|
||||||
|
if (!unit || unit.unit !== 'rem') {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
comments.push({
|
||||||
|
index:
|
||||||
|
decl.source.start.offset +
|
||||||
|
`${decl.prop}${decl.raws.between}`.length +
|
||||||
|
node.sourceEndIndex,
|
||||||
|
value: `${parseFloat(unit.number) * rootFontSize}px`,
|
||||||
|
})
|
||||||
|
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
postcssPlugin.postcss = true
|
|
@ -1,9 +0,0 @@
|
||||||
export function remToPx(value: string, rootSize: number = 16): string | undefined {
|
|
||||||
if (/^-?[0-9.]+rem$/.test(value)) {
|
|
||||||
let number = parseFloat(value.substr(0, value.length - 3))
|
|
||||||
if (!isNaN(number)) {
|
|
||||||
return `${number * rootSize}px`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return undefined
|
|
||||||
}
|
|
|
@ -2,10 +2,10 @@ import removeMeta from './removeMeta'
|
||||||
import dlv from 'dlv'
|
import dlv from 'dlv'
|
||||||
import escapeClassName from 'css.escape'
|
import escapeClassName from 'css.escape'
|
||||||
import { ensureArray } from './array'
|
import { ensureArray } from './array'
|
||||||
import { remToPx } from './remToPx'
|
|
||||||
import stringifyObject from 'stringify-object'
|
import stringifyObject from 'stringify-object'
|
||||||
import isObject from './isObject'
|
import isObject from './isObject'
|
||||||
import { Settings } from './state'
|
import { Settings } from './state'
|
||||||
|
import { addPixelEquivalentsToCss } from './pixelEquivalents'
|
||||||
|
|
||||||
export function stringifyConfigValue(x: any): string {
|
export function stringifyConfigValue(x: any): string {
|
||||||
if (isObject(x)) return `${Object.keys(x).length} values`
|
if (isObject(x)) return `${Object.keys(x).length} values`
|
||||||
|
@ -45,12 +45,7 @@ export function stringifyCss(className: string, obj: any, settings: Settings): s
|
||||||
const indentStr = indent.repeat(context.length)
|
const indentStr = indent.repeat(context.length)
|
||||||
const decls = props.reduce((acc, curr, i) => {
|
const decls = props.reduce((acc, curr, i) => {
|
||||||
const propStr = ensureArray(obj[curr])
|
const propStr = ensureArray(obj[curr])
|
||||||
.map((val) => {
|
.map((val) => `${indentStr + indent}${curr}: ${val};`)
|
||||||
const px = settings.tailwindCSS.showPixelEquivalents
|
|
||||||
? remToPx(val, settings.tailwindCSS.rootFontSize)
|
|
||||||
: undefined
|
|
||||||
return `${indentStr + indent}${curr}: ${val}${px ? `/* ${px} */` : ''};`
|
|
||||||
})
|
|
||||||
.join('\n')
|
.join('\n')
|
||||||
return `${acc}${i === 0 ? '' : '\n'}${propStr}`
|
return `${acc}${i === 0 ? '' : '\n'}${propStr}`
|
||||||
}, '')
|
}, '')
|
||||||
|
@ -60,6 +55,10 @@ export function stringifyCss(className: string, obj: any, settings: Settings): s
|
||||||
css += `${indent.repeat(i)}\n}`
|
css += `${indent.repeat(i)}\n}`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (settings.tailwindCSS.showPixelEquivalents) {
|
||||||
|
return addPixelEquivalentsToCss(css, settings.tailwindCSS.rootFontSize)
|
||||||
|
}
|
||||||
|
|
||||||
return css
|
return css
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue