Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for static theme option #1176

Merged
merged 5 commits into from
Feb 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions packages/tailwindcss-language-service/src/completionProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2002,6 +2002,17 @@ async function provideThemeDirectiveCompletions(
},
sortText: '-000001',
},
{
label: 'static',
documentation: {
kind: 'markdown',
value:
directive === 'import'
? `Always emit imported theme values into the CSS file instead of only when used.`
: `Always emit these theme values into the CSS file instead of only when used.`,
},
sortText: '-000001',
},
{
label: 'default',
documentation: {
Expand Down
96 changes: 96 additions & 0 deletions packages/tailwindcss-language-service/src/hoverProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { addPixelEquivalentsToValue } from './util/pixelEquivalents'
import { getTextWithoutComments } from './util/doc'
import braces from 'braces'
import { absoluteRange } from './util/absoluteRange'
import { segment } from './util/segment'

export async function doHover(
state: State,
Expand All @@ -27,6 +28,7 @@ export async function doHover(
): Promise<Hover> {
return (
(await provideClassNameHover(state, document, position)) ||
(await provideThemeDirectiveHover(state, document, position)) ||
(await provideCssHelperHover(state, document, position)) ||
(await provideSourceGlobHover(state, document, position))
)
Expand Down Expand Up @@ -203,3 +205,97 @@ async function provideSourceGlobHover(

return null
}

// Provide completions for directives that take file paths
const PATTERN_AT_THEME = /@(?<directive>theme)\s+(?<parts>[^{]+)\s*\{/dg
const PATTERN_IMPORT_THEME = /@(?<directive>import)\s*[^;]+?theme\((?<parts>[^)]+)\)/dg

async function provideThemeDirectiveHover(
state: State,
document: TextDocument,
position: Position,
): Promise<Hover> {
if (!state.v4) return null

let range = {
start: { line: position.line, character: 0 },
end: { line: position.line + 1, character: 0 },
}

let text = getTextWithoutComments(document, 'css', range)

let matches = [...findAll(PATTERN_IMPORT_THEME, text), ...findAll(PATTERN_AT_THEME, text)]

for (let match of matches) {
let directive = match.groups.directive
let parts = match.groups.parts

// Find the option under the cursor
let options: { name: string; range: Range }[] = []

let offset = match.indices.groups.parts[0]

for (let part of segment(parts, ' ')) {
let length = part.length
part = part.trim()

if (part !== '') {
options.push({
name: part,
range: absoluteRange(
{
start: indexToPosition(text, offset),
end: indexToPosition(text, offset + part.length),
},
range,
),
})
}

offset += length + 1
}

let option = options.find((option) => isWithinRange(position, option.range))
if (!option) return null

let markdown = getThemeMarkdown(directive, option.name)
if (!markdown) return null

return {
range: option.range,
contents: markdown,
}
}

return null
}

function getThemeMarkdown(directive: string, name: string) {
let options = {
reference: markdown([
directive === 'import'
? `Don't emit CSS variables for imported theme values.`
: `Don't emit CSS variables for these theme values.`,
]),

inline: markdown([
directive === 'import'
? `Inline imported theme values into generated utilities instead of using \`var(…)\`.`
: `Inline these theme values into generated utilities instead of using \`var(…)\`.`,
]),

static: markdown([
directive === 'import'
? `Always emit imported theme values into the CSS file instead of only when used.`
: `Always emit these theme values into the CSS file instead of only when used.`,
]),

default: markdown([
directive === 'import'
? `Allow imported theme values to be overridden by JS configs and plugins.`
: `Allow these theme values to be overridden by JS configs and plugins.`,
]),
}

return options[name]
}
2 changes: 2 additions & 0 deletions packages/vscode-tailwindcss/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

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

## 0.14.3

Expand Down
4 changes: 4 additions & 0 deletions packages/vscode-tailwindcss/syntaxes/at-rules.tmLanguage.json
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,10 @@
"match": "inline",
"name": "variable.other.css"
},
{
"match": "static",
"name": "variable.other.css"
},
{
"match": "default",
"name": "variable.other.css"
Expand Down