Skip to content

Commit 2e460bf

Browse files
authored
Fix className completion entry to support single quotes (#175)
* Refactor tests * Add test for className completion * Fix className completion entry to support single quotes
1 parent 773ed57 commit 2e460bf

3 files changed

Lines changed: 40 additions & 4 deletions

File tree

.changeset/social-hoops-flash.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@css-modules-kit/ts-plugin': patch
3+
---
4+
5+
Fix className completion entry to support single quotes

packages/ts-plugin/e2e/completion.test.ts

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ describe('Completion', async () => {
2525
styles;
2626
const jsx = <div className />;
2727
`,
28+
'b.tsx': dedent`
29+
import styles from './b.module.css';
30+
const jsx = <div className />;
31+
`,
2832
'a.module.css': '',
2933
'b.module.css': '',
3034
'tsconfig.json': dedent`
@@ -48,11 +52,13 @@ describe('Completion', async () => {
4852
includeCompletionsWithSnippetText: true,
4953
includeCompletionsWithInsertText: true,
5054
jsxAttributeCompletionStyle: 'auto',
55+
quotePreference: 'single',
5156
},
5257
});
5358
test.each([
5459
{
5560
name: 'styles',
61+
entryName: 'styles',
5662
file: iff.paths['a.tsx'],
5763
line: 1,
5864
offset: 7,
@@ -62,18 +68,43 @@ describe('Completion', async () => {
6268
],
6369
},
6470
{
65-
name: 'className',
71+
name: "className with `quotePreference: 'double'`",
72+
entryName: 'className',
73+
quotePreference: 'double' as const,
6674
file: iff.paths['a.tsx'],
6775
line: 2,
6876
offset: 27,
6977
expected: [{ name: 'className', insertText: 'className={$1}', sortText: expect.anything() }],
7078
},
71-
])('Completions for $name', async ({ name, file, line, offset, expected }) => {
79+
{
80+
name: "className with `quotePreference: 'single'`",
81+
entryName: 'className',
82+
quotePreference: 'single' as const,
83+
file: iff.paths['b.tsx'],
84+
line: 2,
85+
offset: 27,
86+
expected: [{ name: 'className', insertText: 'className={$1}', sortText: expect.anything() }],
87+
},
88+
])('Completions for $name', async ({ entryName, quotePreference, file, line, offset, expected }) => {
89+
await tsserver.sendConfigure({
90+
preferences: {
91+
quotePreference: quotePreference ?? 'auto',
92+
},
93+
});
7294
const res = await tsserver.sendCompletionInfo({
7395
file,
7496
line,
7597
offset,
7698
});
77-
expect(simplifyEntry(res.body?.entries.filter((entry) => entry.name === name) ?? [])).toStrictEqual(expected);
99+
expect(
100+
simplifyEntry(res.body?.entries.filter((entry) => entry.name === entryName) ?? []).sort(compareEntries),
101+
).toStrictEqual(expected.sort(compareEntries));
78102
});
79103
});
104+
105+
function compareEntries(
106+
a: Partial<ts.server.protocol.CompletionEntry>,
107+
b: Partial<ts.server.protocol.CompletionEntry>,
108+
) {
109+
return a.sortText?.localeCompare(b.sortText ?? '') || 0;
110+
}

packages/ts-plugin/src/language-service/feature/completion.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ function isClassNamePropEntry(entry: ts.CompletionEntry) {
4242
return (
4343
entry.name === 'className' &&
4444
entry.kind === ts.ScriptElementKind.memberVariableElement &&
45-
entry.insertText === 'className="$1"' &&
45+
(entry.insertText === 'className="$1"' || entry.insertText === "className='$1'") &&
4646
entry.isSnippet
4747
);
4848
}

0 commit comments

Comments
 (0)