Skip to content

Commit d32a3ed

Browse files
Add support for static theme option (#1176)
IntelliSense part of tailwindlabs/tailwindcss#16211
1 parent 0a2138d commit d32a3ed

File tree

4 files changed

+113
-0
lines changed

4 files changed

+113
-0
lines changed

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

+11
Original file line numberDiff line numberDiff line change
@@ -2002,6 +2002,17 @@ async function provideThemeDirectiveCompletions(
20022002
},
20032003
sortText: '-000001',
20042004
},
2005+
{
2006+
label: 'static',
2007+
documentation: {
2008+
kind: 'markdown',
2009+
value:
2010+
directive === 'import'
2011+
? `Always emit imported theme values into the CSS file instead of only when used.`
2012+
: `Always emit these theme values into the CSS file instead of only when used.`,
2013+
},
2014+
sortText: '-000001',
2015+
},
20052016
{
20062017
label: 'default',
20072018
documentation: {

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

+96
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import { addPixelEquivalentsToValue } from './util/pixelEquivalents'
1919
import { getTextWithoutComments } from './util/doc'
2020
import braces from 'braces'
2121
import { absoluteRange } from './util/absoluteRange'
22+
import { segment } from './util/segment'
2223

2324
export async function doHover(
2425
state: State,
@@ -27,6 +28,7 @@ export async function doHover(
2728
): Promise<Hover> {
2829
return (
2930
(await provideClassNameHover(state, document, position)) ||
31+
(await provideThemeDirectiveHover(state, document, position)) ||
3032
(await provideCssHelperHover(state, document, position)) ||
3133
(await provideSourceGlobHover(state, document, position))
3234
)
@@ -203,3 +205,97 @@ async function provideSourceGlobHover(
203205

204206
return null
205207
}
208+
209+
// Provide completions for directives that take file paths
210+
const PATTERN_AT_THEME = /@(?<directive>theme)\s+(?<parts>[^{]+)\s*\{/dg
211+
const PATTERN_IMPORT_THEME = /@(?<directive>import)\s*[^;]+?theme\((?<parts>[^)]+)\)/dg
212+
213+
async function provideThemeDirectiveHover(
214+
state: State,
215+
document: TextDocument,
216+
position: Position,
217+
): Promise<Hover> {
218+
if (!state.v4) return null
219+
220+
let range = {
221+
start: { line: position.line, character: 0 },
222+
end: { line: position.line + 1, character: 0 },
223+
}
224+
225+
let text = getTextWithoutComments(document, 'css', range)
226+
227+
let matches = [...findAll(PATTERN_IMPORT_THEME, text), ...findAll(PATTERN_AT_THEME, text)]
228+
229+
for (let match of matches) {
230+
let directive = match.groups.directive
231+
let parts = match.groups.parts
232+
233+
// Find the option under the cursor
234+
let options: { name: string; range: Range }[] = []
235+
236+
let offset = match.indices.groups.parts[0]
237+
238+
for (let part of segment(parts, ' ')) {
239+
let length = part.length
240+
part = part.trim()
241+
242+
if (part !== '') {
243+
options.push({
244+
name: part,
245+
range: absoluteRange(
246+
{
247+
start: indexToPosition(text, offset),
248+
end: indexToPosition(text, offset + part.length),
249+
},
250+
range,
251+
),
252+
})
253+
}
254+
255+
offset += length + 1
256+
}
257+
258+
let option = options.find((option) => isWithinRange(position, option.range))
259+
if (!option) return null
260+
261+
let markdown = getThemeMarkdown(directive, option.name)
262+
if (!markdown) return null
263+
264+
return {
265+
range: option.range,
266+
contents: markdown,
267+
}
268+
}
269+
270+
return null
271+
}
272+
273+
function getThemeMarkdown(directive: string, name: string) {
274+
let options = {
275+
reference: markdown([
276+
directive === 'import'
277+
? `Don't emit CSS variables for imported theme values.`
278+
: `Don't emit CSS variables for these theme values.`,
279+
]),
280+
281+
inline: markdown([
282+
directive === 'import'
283+
? `Inline imported theme values into generated utilities instead of using \`var(…)\`.`
284+
: `Inline these theme values into generated utilities instead of using \`var(…)\`.`,
285+
]),
286+
287+
static: markdown([
288+
directive === 'import'
289+
? `Always emit imported theme values into the CSS file instead of only when used.`
290+
: `Always emit these theme values into the CSS file instead of only when used.`,
291+
]),
292+
293+
default: markdown([
294+
directive === 'import'
295+
? `Allow imported theme values to be overridden by JS configs and plugins.`
296+
: `Allow these theme values to be overridden by JS configs and plugins.`,
297+
]),
298+
}
299+
300+
return options[name]
301+
}

packages/vscode-tailwindcss/CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
- Ensure hover information for `theme(…)` and other functions are shown when used in `@media` queries ([#1172](https://github.com/tailwindlabs/tailwindcss-intellisense/pull/1172))
66
- Treat `<script lang=“tsx”>` as containing JSX ([#1175](https://github.com/tailwindlabs/tailwindcss-intellisense/pull/1175))
7+
- Add support for `static` theme option ([#1176](https://github.com/tailwindlabs/tailwindcss-intellisense/pull/1176))
8+
- Add details about theme options when hovering ([#1176](https://github.com/tailwindlabs/tailwindcss-intellisense/pull/1176))
79

810
## 0.14.3
911

packages/vscode-tailwindcss/syntaxes/at-rules.tmLanguage.json

+4
Original file line numberDiff line numberDiff line change
@@ -592,6 +592,10 @@
592592
"match": "inline",
593593
"name": "variable.other.css"
594594
},
595+
{
596+
"match": "static",
597+
"name": "variable.other.css"
598+
},
595599
{
596600
"match": "default",
597601
"name": "variable.other.css"

0 commit comments

Comments
 (0)