Skip to content

Commit 460d921

Browse files
authored
Include pixel equivalents in more places (#775)
* Show pixel equivalents for more `rem`/`em` values * Add pixel equivalents to media query variant completions
1 parent 5e9cce6 commit 460d921

File tree

7 files changed

+263
-47
lines changed

7 files changed

+263
-47
lines changed

package-lock.json

Lines changed: 64 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/tailwindcss-language-service/package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414
"prepublishOnly": "npm run build"
1515
},
1616
"dependencies": {
17+
"@csstools/media-query-list-parser": "2.0.4",
18+
"@csstools/css-parser-algorithms": "2.1.1",
19+
"@csstools/css-tokenizer": "2.1.1",
1720
"@types/culori": "^2.0.0",
1821
"@types/moo": "0.5.3",
1922
"@types/semver": "7.3.10",
@@ -28,6 +31,7 @@
2831
"moo": "0.5.1",
2932
"postcss": "8.3.9",
3033
"postcss-selector-parser": "6.0.2",
34+
"postcss-value-parser": "4.2.0",
3135
"semver": "7.3.7",
3236
"sift-string": "0.0.2",
3337
"stringify-object": "3.3.0",

packages/tailwindcss-language-service/src/completionProvider.ts

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,14 @@ import { ensureArray } from './util/array'
2828
import { getClassAttributeLexer, getComputedClassAttributeLexer } from './util/lexers'
2929
import { validateApply } from './util/validateApply'
3030
import { flagEnabled } from './util/flagEnabled'
31-
import { remToPx } from './util/remToPx'
3231
import * as jit from './util/jit'
3332
import { getVariantsFromClassName } from './util/getVariantsFromClassName'
3433
import * as culori from 'culori'
3534
import Regex from 'becke-ch--regex--s0-0-v1--base--pl--lib'
35+
import {
36+
addPixelEquivalentsToMediaQuery,
37+
addPixelEquivalentsToValue,
38+
} from './util/pixelEquivalents'
3639

3740
let isUtil = (className) =>
3841
Array.isArray(className.__info)
@@ -43,6 +46,7 @@ export function completionsFromClassList(
4346
state: State,
4447
classList: string,
4548
classListRange: Range,
49+
rootFontSize: number,
4650
filter?: (item: CompletionItem) => boolean,
4751
context?: CompletionContext
4852
): CompletionList {
@@ -190,7 +194,10 @@ export function completionsFromClassList(
190194
items.push(
191195
variantItem({
192196
label: `${variant.name}${sep}`,
193-
detail: variant.selectors().join(', '),
197+
detail: variant
198+
.selectors()
199+
.map((selector) => addPixelEquivalentsToMediaQuery(selector, rootFontSize))
200+
.join(', '),
194201
textEditText: resultingVariants[resultingVariants.length - 1] + sep,
195202
additionalTextEdits:
196203
shouldSortVariants && resultingVariants.length > 1
@@ -430,10 +437,9 @@ async function provideClassAttributeCompletions(
430437
end: position,
431438
})
432439

433-
let matches = matchClassAttributes(
434-
str,
435-
(await state.editor.getConfiguration(document.uri)).tailwindCSS.classAttributes
436-
)
440+
let settings = (await state.editor.getConfiguration(document.uri)).tailwindCSS
441+
442+
let matches = matchClassAttributes(str, settings.classAttributes)
437443

438444
if (matches.length === 0) {
439445
return null
@@ -470,6 +476,7 @@ async function provideClassAttributeCompletions(
470476
},
471477
end: position,
472478
},
479+
settings.rootFontSize,
473480
undefined,
474481
context
475482
)
@@ -544,6 +551,7 @@ async function provideCustomClassNameCompletions(
544551
},
545552
end: position,
546553
},
554+
settings.tailwindCSS.rootFontSize,
547555
undefined,
548556
context
549557
)
@@ -555,12 +563,13 @@ async function provideCustomClassNameCompletions(
555563
return null
556564
}
557565

558-
function provideAtApplyCompletions(
566+
async function provideAtApplyCompletions(
559567
state: State,
560568
document: TextDocument,
561569
position: Position,
562570
context?: CompletionContext
563-
): CompletionList {
571+
): Promise<CompletionList> {
572+
let settings = (await state.editor.getConfiguration(document.uri)).tailwindCSS
564573
let str = document.getText({
565574
start: { line: Math.max(position.line - 30, 0), character: 0 },
566575
end: position,
@@ -584,6 +593,7 @@ function provideAtApplyCompletions(
584593
},
585594
end: position,
586595
},
596+
settings.rootFontSize,
587597
(item) => {
588598
if (item.kind === 9) {
589599
return (
@@ -1318,13 +1328,18 @@ async function provideEmmetCompletions(
13181328
const parts = emmetItems.items[0].label.split('.')
13191329
if (parts.length < 2) return null
13201330

1321-
return completionsFromClassList(state, parts[parts.length - 1], {
1322-
start: {
1323-
line: position.line,
1324-
character: position.character - parts[parts.length - 1].length,
1331+
return completionsFromClassList(
1332+
state,
1333+
parts[parts.length - 1],
1334+
{
1335+
start: {
1336+
line: position.line,
1337+
character: position.character - parts[parts.length - 1].length,
1338+
},
1339+
end: position,
13251340
},
1326-
end: position,
1327-
})
1341+
settings.tailwindCSS.rootFontSize
1342+
)
13281343
}
13291344

13301345
export async function doComplete(
@@ -1444,10 +1459,10 @@ function stringifyDecls(obj: any, settings: Settings): string {
14441459
.map((prop) =>
14451460
ensureArray(obj[prop])
14461461
.map((value) => {
1447-
const px = settings.tailwindCSS.showPixelEquivalents
1448-
? remToPx(value, settings.tailwindCSS.rootFontSize)
1449-
: undefined
1450-
return `${prop}: ${value}${px ? `/* ${px} */` : ''};`
1462+
if (settings.tailwindCSS.showPixelEquivalents) {
1463+
value = addPixelEquivalentsToValue(value, settings.tailwindCSS.rootFontSize)
1464+
}
1465+
return `${prop}: ${value};`
14511466
})
14521467
.join(' ')
14531468
)

packages/tailwindcss-language-service/src/util/jit.ts

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { State } from './state'
22
import type { Container, Document, Root, Rule, Node, AtRule } from 'postcss'
3-
import { remToPx } from './remToPx'
3+
import { addPixelEquivalentsToCss, addPixelEquivalentsToValue } from './pixelEquivalents'
44

55
export function bigSign(bigIntValue) {
66
// @ts-ignore
@@ -41,17 +41,13 @@ export async function stringifyRoot(state: State, root: Root, uri?: string): Pro
4141
node.remove()
4242
})
4343

44+
let css = clone.toString()
45+
4446
if (settings.tailwindCSS.showPixelEquivalents) {
45-
clone.walkDecls((decl) => {
46-
let px = remToPx(decl.value, settings.tailwindCSS.rootFontSize)
47-
if (px) {
48-
decl.value = `${decl.value}/* ${px} */`
49-
}
50-
})
47+
css = addPixelEquivalentsToCss(css, settings.tailwindCSS.rootFontSize)
5148
}
5249

53-
return clone
54-
.toString()
50+
return css
5551
.replace(/([^;{}\s])(\n\s*})/g, (_match, before, after) => `${before};${after}`)
5652
.replace(/^(?: )+/gm, (indent: string) =>
5753
' '.repeat((indent.length / 4) * settings.editor.tabSize)
@@ -70,10 +66,10 @@ export async function stringifyDecls(state: State, rule: Rule, uri?: string): Pr
7066

7167
let result = []
7268
rule.walkDecls(({ prop, value }) => {
73-
let px = settings.tailwindCSS.showPixelEquivalents
74-
? remToPx(value, settings.tailwindCSS.rootFontSize)
75-
: undefined
76-
result.push(`${prop}: ${value}${px ? `/* ${px} */` : ''};`)
69+
if (settings.tailwindCSS.showPixelEquivalents) {
70+
value = addPixelEquivalentsToValue(value, settings.tailwindCSS.rootFontSize)
71+
}
72+
result.push(`${prop}: ${value};`)
7773
})
7874
return result.join(' ')
7975
}

0 commit comments

Comments
 (0)