Skip to content

Commit c41ee42

Browse files
authored
feat: add new allow unknown classnames feature (#182)
1 parent 4969ba6 commit c41ee42

8 files changed

+36
-34
lines changed

.prettierignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
pnpm-lock.yaml
22
/dist/
3+
*.snap

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ Please note that no options are required. However, depending on your configurati
9999

100100
| Option | Default value | Description |
101101
| -------------------------- | ---------------------------------- | ------------------------------------------------------------------------------------------------------ |
102+
| `allowUnknownClassnames` | `false` | Disables TypeScript warnings on unknown classnames (for default imports only). |
102103
| `classnameTransform` | `asIs` | See [`classnameTransform`](#classnameTransform) below. |
103104
| `customMatcher` | `"\\.module\\.(c\|le\|sa\|sc)ss$"` | Changes the file extensions that this plugin processes. |
104105
| `customRenderer` | `false` | See [`customRenderer`](#customRenderer) below. |

src/helpers/__tests__/__snapshots__/getDtsSnapshot.test.ts.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ exports[`utils / cssSnapshots with a custom renderer should process a file and l
99
}
1010
`;
1111

12-
exports[`utils / cssSnapshots with allowAdditionalClasses enabled should return a dts file that allows any string value 1`] = `
12+
exports[`utils / cssSnapshots with allowUnknownClassnames enabled should return a dts file that allows any string value 1`] = `
1313
"declare let classes: {
1414
'localClassInsideGlobal': string;
1515
'localClass': string;

src/helpers/__tests__/classTransforms.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { transformClasses } from '../classTransforms';
22
import { ClassnameTransformOptions } from '../../options';
33

44
describe('utils / classTransforms', () => {
5-
const classNames = [
5+
const classnames = [
66
'class-name-a',
77
'classNameB',
88
'class-Name-C',
@@ -18,14 +18,14 @@ describe('utils / classTransforms', () => {
1818

1919
it('should not transform classes when no option is set', () => {
2020
const transformer = transformClasses();
21-
const transformedClasses = classNames.map(transformer);
21+
const transformedClasses = classnames.map(transformer);
2222
expect(transformedClasses).toMatchSnapshot();
2323
});
2424

2525
tests.forEach((option) => {
2626
it(`should transform classes correctly when \`classnameTransform\` set to \`${option}\``, () => {
2727
const transformer = transformClasses(option);
28-
const transformedClasses = classNames.map(transformer);
28+
const transformedClasses = classnames.map(transformer);
2929
expect(transformedClasses).toMatchSnapshot();
3030
});
3131
});

src/helpers/__tests__/getDtsSnapshot.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -291,12 +291,12 @@ describe('utils / cssSnapshots', () => {
291291
});
292292
});
293293

294-
describe('with allowAdditionalClasses enabled', () => {
294+
describe('with allowUnknownClassnames enabled', () => {
295295
const fileName = join(__dirname, 'fixtures', 'test.module.scss');
296296
const css = readFileSync(fileName, 'utf8');
297297
const options: Options = {
298298
classnameTransform: 'camelCaseOnly',
299-
allowAdditionalClasses: true,
299+
allowUnknownClassnames: true,
300300
};
301301

302302
const cssExports = getCssExports({

src/helpers/classTransforms.ts

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,42 +4,42 @@ import { ClassnameTransformOptions } from '../options';
44
// The below is based on the CSS Modules implementation found here:
55
// https://github.com/webpack-contrib/css-loader
66

7-
const dashCase = (className: string): string =>
8-
className.replace(/-+(\w)/g, (_match: string, firstLetter: string) =>
7+
const dashCase = (classname: string): string =>
8+
classname.replace(/-+(\w)/g, (_match: string, firstLetter: string) =>
99
firstLetter.toUpperCase(),
1010
);
1111

1212
export const transformClasses =
1313
(camelCaseOption?: ClassnameTransformOptions) =>
14-
(className: string): string[] => {
14+
(classname: string): string[] => {
1515
const entries: string[] = [];
1616

1717
switch (camelCaseOption) {
1818
case 'camelCase': {
19-
entries.push(className);
20-
const targetClassName = camelCase(className);
21-
if (targetClassName !== className) {
19+
entries.push(classname);
20+
const targetClassName = camelCase(classname);
21+
if (targetClassName !== classname) {
2222
entries.push(targetClassName);
2323
}
2424
break;
2525
}
2626
case 'camelCaseOnly':
27-
entries.push(camelCase(className));
27+
entries.push(camelCase(classname));
2828
break;
2929
case 'dashes': {
30-
entries.push(className);
31-
const targetClassName = dashCase(className);
32-
if (targetClassName !== className) {
30+
entries.push(classname);
31+
const targetClassName = dashCase(classname);
32+
if (targetClassName !== classname) {
3333
entries.push(targetClassName);
3434
}
3535
break;
3636
}
3737
case 'dashesOnly':
38-
entries.push(dashCase(className));
38+
entries.push(dashCase(classname));
3939
break;
4040
case 'asIs':
4141
default:
42-
entries.push(className);
42+
entries.push(classname);
4343
break;
4444
}
4545

src/helpers/createDtsExports.ts

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ import { CSSExportsWithSourceMap } from './getCssExports';
55
import { VALID_VARIABLE_REGEXP } from './validVarRegexp';
66
import { Logger } from './logger';
77

8-
const isValidVariable = (className: string) =>
9-
VALID_VARIABLE_REGEXP.test(className);
8+
const isValidVariable = (classname: string) =>
9+
VALID_VARIABLE_REGEXP.test(classname);
1010

1111
const flattenClassNames = (
1212
previousValue: string[] = [],
@@ -28,22 +28,22 @@ export const createDtsExports = ({
2828

2929
const possiblyUndefined = Boolean(options.noUncheckedIndexedAccess);
3030

31-
const classNameToProperty = (className: string) =>
32-
`'${className}'${possiblyUndefined ? '?' : ''}: string;`;
33-
const classNameToNamedExport = (className: string) =>
34-
`export let ${className}${possiblyUndefined ? '?' : ''}: string;`;
31+
const classnameToProperty = (classname: string) =>
32+
`'${classname}'${possiblyUndefined ? '?' : ''}: string;`;
33+
const classnameToNamedExport = (classname: string) =>
34+
`export let ${classname}${possiblyUndefined ? '?' : ''}: string;`;
3535

3636
const processedClasses = Object.keys(classes)
3737
.map(transformClasses(options.classnameTransform))
3838
.reduce(flattenClassNames, []);
3939
const filteredClasses = processedClasses
4040
.filter(isValidVariable)
41-
.map(classNameToNamedExport);
41+
.map(classnameToNamedExport);
4242

4343
let dts = `\
4444
declare let classes: {
45-
${processedClasses.map(classNameToProperty).join('\n ')}${
46-
options.allowAdditionalClasses ? '\n [key: string]: string;' : ''
45+
${processedClasses.map(classnameToProperty).join('\n ')}${
46+
options.allowUnknownClassnames ? '\n [key: string]: string;' : ''
4747
}
4848
};
4949
export default classes;
@@ -65,15 +65,15 @@ export default classes;
6565

6666
// Create a list of filtered classnames and hashed classnames.
6767
const filteredClasses = Object.entries(cssExports.classes)
68-
.map(([className, hashedClassName]) => [
68+
.map(([classname, hashedClassname]) => [
6969
// TODO: Improve this. It may return multiple valid classnames and we
7070
// want to handle all of those.
71-
transformClasses(options.classnameTransform)(className)[0],
72-
hashedClassName,
71+
transformClasses(options.classnameTransform)(classname)[0],
72+
hashedClassname,
7373
])
74-
.filter(([className]) => isValidVariable(className));
74+
.filter(([classname]) => isValidVariable(classname));
7575

76-
filteredClasses.forEach(([className, hashedClassName]) => {
76+
filteredClasses.forEach(([classname, hashedClassName]) => {
7777
const matchedLine = cssLines.findIndex((line) =>
7878
line.includes(hashedClassName),
7979
);
@@ -85,7 +85,7 @@ export default classes;
8585
column: matchedColumn >= 0 ? matchedColumn : 0,
8686
});
8787
dtsLines[lineNumber ? lineNumber - 1 : 0] +=
88-
classNameToNamedExport(className);
88+
classnameToNamedExport(classname);
8989
});
9090

9191
dts = dtsLines.join('\n');

src/options.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export interface RendererOptions {
2020
}
2121

2222
export interface Options {
23-
allowAdditionalClasses?: boolean;
23+
allowUnknownClassnames?: boolean;
2424
classnameTransform?: ClassnameTransformOptions;
2525
customMatcher?: string;
2626
customRenderer?: string;

0 commit comments

Comments
 (0)