Skip to content

Commit 0b42925

Browse files
committed
Ensure classFunctions completions work inside <script> tags
1 parent 9f9208a commit 0b42925

File tree

3 files changed

+81
-4
lines changed

3 files changed

+81
-4
lines changed

packages/tailwindcss-language-server/tests/completions/completions.test.js

Lines changed: 62 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import { test, expect, describe } from 'vitest'
1+
import { test, expect } from 'vitest'
22
import { withFixture } from '../common'
3-
import { css, defineTest } from '../../src/testing'
3+
import { css, defineTest, html, js } from '../../src/testing'
44
import { createClient } from '../utils/client'
55

66
function buildCompletion(c) {
@@ -738,3 +738,63 @@ defineTest({
738738
expect(completion?.items.length).toBe(12289)
739739
},
740740
})
741+
742+
defineTest({
743+
name: 'v4: Completions show inside class functions in JS/TS files',
744+
fs: {
745+
'app.css': css`
746+
@import 'tailwindcss';
747+
`,
748+
},
749+
prepare: async ({ root }) => ({ client: await createClient({ root }) }),
750+
handle: async ({ client }) => {
751+
let document = await client.open({
752+
settings: {
753+
tailwindCSS: {
754+
classFunctions: ['clsx'],
755+
},
756+
},
757+
lang: 'javascript',
758+
text: js`
759+
let classes = clsx('');
760+
`,
761+
})
762+
763+
// let classes = clsx('');
764+
// ^
765+
let completion = await document.completions({ line: 0, character: 20 })
766+
767+
expect(completion?.items.length).toBe(12289)
768+
},
769+
})
770+
771+
defineTest({
772+
name: 'v4: Completions show inside class functions in JS/TS contexts',
773+
fs: {
774+
'app.css': css`
775+
@import 'tailwindcss';
776+
`,
777+
},
778+
prepare: async ({ root }) => ({ client: await createClient({ root }) }),
779+
handle: async ({ client }) => {
780+
let document = await client.open({
781+
settings: {
782+
tailwindCSS: {
783+
classFunctions: ['clsx'],
784+
},
785+
},
786+
lang: 'html',
787+
text: html`
788+
<script>
789+
let classes = clsx('')
790+
</script>
791+
`,
792+
})
793+
794+
// let classes = clsx('')
795+
// ^
796+
let completion = await document.completions({ line: 1, character: 22 })
797+
798+
expect(completion?.items.length).toBe(12289)
799+
},
800+
})

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import isObject from './util/isObject'
2222
import { braceLevel, parenLevel } from './util/braceLevel'
2323
import * as emmetHelper from 'vscode-emmet-helper-bundled'
2424
import { isValidLocationForEmmetAbbreviation } from './util/isValidLocationForEmmetAbbreviation'
25-
import { isJsDoc, isJsxContext } from './util/js'
25+
import { isJsContext, isJsDoc, isJsxContext } from './util/js'
2626
import { naturalExpand } from './util/naturalExpand'
2727
import * as semver from './util/semver'
2828
import { getTextWithoutComments } from './util/doc'
@@ -986,7 +986,11 @@ async function provideClassNameCompletions(
986986
return provideAtApplyCompletions(state, document, position, context)
987987
}
988988

989-
if (isHtmlContext(state, document, position) || isJsxContext(state, document, position)) {
989+
if (
990+
isHtmlContext(state, document, position) ||
991+
isJsContext(state, document, position) ||
992+
isJsxContext(state, document, position)
993+
) {
990994
return provideClassAttributeCompletions(state, document, position, context)
991995
}
992996

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,19 @@ export function isJsDoc(state: State, doc: TextDocument): boolean {
1212
return [...jsLanguages, ...userJsLanguages].indexOf(doc.languageId) !== -1
1313
}
1414

15+
export function isJsContext(state: State, doc: TextDocument, position: Position): boolean {
16+
let str = doc.getText({
17+
start: { line: 0, character: 0 },
18+
end: position,
19+
})
20+
21+
let boundaries = getLanguageBoundaries(state, doc, str)
22+
23+
return boundaries
24+
? ['js', 'ts', 'jsx', 'tsx'].includes(boundaries[boundaries.length - 1].type)
25+
: false
26+
}
27+
1528
export function isJsxContext(state: State, doc: TextDocument, position: Position): boolean {
1629
let str = doc.getText({
1730
start: { line: 0, character: 0 },

0 commit comments

Comments
 (0)