Skip to content

Commit 84661b9

Browse files
committed
feat: add singleQuote option to allow custom style for keys with dashes
1 parent 7b200ab commit 84661b9

File tree

6 files changed

+57
-3
lines changed

6 files changed

+57
-3
lines changed

README.md

+5
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,10 @@ export const SomeComponent: string;
106106

107107
See also [webpack css-loader's camelCase option](https://github.com/webpack/css-loader#camelcase).
108108

109+
#### Use single quotes to class names in the .d.ts files
110+
111+
With `-sq` or `--singleQuote`, you can configure what quote to use. Useful when tools like prettier format your .d.ts files.
112+
109113
## API
110114

111115
```sh
@@ -132,6 +136,7 @@ You can set the following options:
132136
* `option.searchDir`: Directory which includes target `*.css` files(default: `'./'`).
133137
* `option.outDir`: Output directory(default: `option.searchDir`).
134138
* `option.camelCase`: Camelize CSS class tokens.
139+
* `option.singleQuote`: Use single quotes on dashed keys.
135140
* `option.EOL`: EOL (end of line) for the generated `d.ts` files. Possible values `'\n'` or `'\r\n'`(default: `os.EOL`).
136141

137142
#### `create(filepath, contents) => Promise(dtsContent)`

src/cli.ts

+5
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ const yarg = yargs.usage('Create .css.d.ts from CSS modules *.css files.\nUsage:
1414
.alias('o', 'outDir').describe('o', 'Output directory')
1515
.alias('w', 'watch').describe('w', 'Watch input directory\'s css files or pattern').boolean('w')
1616
.alias('c', 'camelCase').describe('c', 'Convert CSS class tokens to camelcase')
17+
.alias('sq', 'singleQuote').describe(
18+
'sq',
19+
'Use single quotes for writing the keys when they have a dash'
20+
)
1721
.alias('d', 'dropExtension').describe('d', 'Drop the input files extension').boolean('d')
1822
.alias('s', 'silent').describe('s', 'Silent output. Do not show "files written" messages').boolean('s')
1923
.alias('h', 'help').help('h')
@@ -45,6 +49,7 @@ async function main(): Promise<void> {
4549
outDir: argv.o,
4650
watch: argv.w,
4751
camelCase: argv.c,
52+
singleQuote: argv.sq,
4853
dropExtension: argv.d,
4954
silent: argv.s
5055
});

src/dts-content.ts

+6-2
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,15 @@ interface DtsContentOptions {
1717
rawTokenList: string[];
1818
resultList: string[];
1919
EOL: string;
20+
singleQuote?: boolean;
2021
}
2122

2223
export class DtsContent {
2324
private dropExtension: boolean;
2425
private rootDir: string;
2526
private searchDir: string;
2627
private outDir: string;
28+
private singleQuote?: boolean;
2729
private rInputPath: string;
2830
private rawTokenList: string[];
2931
private resultList: string[];
@@ -34,6 +36,7 @@ export class DtsContent {
3436
this.rootDir = options.rootDir;
3537
this.searchDir = options.searchDir;
3638
this.outDir = options.outDir;
39+
this.singleQuote = options.singleQuote;
3740
this.rInputPath = options.rInputPath;
3841
this.rawTokenList = options.rawTokenList;
3942
this.resultList = options.resultList;
@@ -46,13 +49,14 @@ export class DtsContent {
4649

4750
public get formatted(): string {
4851
if(!this.resultList || !this.resultList.length) return '';
49-
return [
52+
const data = [
5053
'declare const styles: {',
5154
...this.resultList.map(line => ' ' + line),
5255
'};',
5356
'export = styles;',
5457
''
55-
].join(os.EOL) + this.EOL;
58+
].join(this.EOL);
59+
return this.singleQuote ? data.replace(/\"/g, "'") : data;
5660
}
5761

5862
public get tokens(): string[] {

src/dts-creator.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ interface DtsCreatorOptions {
1414
searchDir?: string;
1515
outDir?: string;
1616
camelCase?: CamelCaseOption;
17+
singleQuote?: boolean;
1718
dropExtension?: boolean;
1819
EOL?: string;
1920
loaderPlugins?: Plugin<any>[];
@@ -26,6 +27,7 @@ export class DtsCreator {
2627
private loader: FileSystemLoader;
2728
private inputDirectory: string;
2829
private outputDirectory: string;
30+
private singleQuote?: boolean;
2931
private camelCase: boolean | 'dashes' | undefined;
3032
private dropExtension: boolean;
3133
private EOL: string;
@@ -38,6 +40,7 @@ export class DtsCreator {
3840
this.loader = new FileSystemLoader(this.rootDir, options.loaderPlugins);
3941
this.inputDirectory = path.join(this.rootDir, this.searchDir);
4042
this.outputDirectory = path.join(this.rootDir, this.outDir);
43+
this.singleQuote = options.singleQuote;
4144
this.camelCase = options.camelCase;
4245
this.dropExtension = !!options.dropExtension;
4346
this.EOL = options.EOL || os.EOL;
@@ -63,10 +66,11 @@ export class DtsCreator {
6366

6467
const result = keys
6568
.map(k => convertKey(k))
66-
.map(k => 'readonly "' + k + '": string;')
69+
.map(k => `readonly ${k.includes('-') ? `"${k}"` : k}: string;`);
6770

6871
const content = new DtsContent({
6972
dropExtension: this.dropExtension,
73+
singleQuote: this.singleQuote,
7074
rootDir: this.rootDir,
7175
searchDir: this.searchDir,
7276
outDir: this.outDir,

src/run.ts

+2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ interface RunOptions {
1414
outDir?: string;
1515
watch?: boolean;
1616
camelCase?: boolean;
17+
singleQuote?: boolean;
1718
dropExtension?: boolean;
1819
silent?: boolean;
1920
}
@@ -27,6 +28,7 @@ export async function run(searchDir: string, options: RunOptions = {}): Promise<
2728
outDir: options.outDir,
2829
camelCase: options.camelCase,
2930
dropExtension: options.dropExtension,
31+
singleQuote: options.singleQuote,
3032
});
3133

3234
const writeFile = async (f: string): Promise<void> => {

test/dts-creator.spec.ts

+34
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,40 @@ export = styles;
179179
});
180180
});
181181

182+
describe('#singleQuote option', () => {
183+
it('singleQuote == undefined: returns same as before', done => {
184+
new DtsCreator().create('test/kebabed.css').then(content => {
185+
assert.equal(
186+
content.formatted,
187+
`\
188+
declare const styles: {
189+
readonly "my-class": string;
190+
};
191+
export = styles;
192+
`
193+
);
194+
done();
195+
});
196+
});
197+
198+
it('singleQuote == true: returns kebab keys with single quote', done => {
199+
new DtsCreator({ singleQuote: true, EOL: '\n' })
200+
.create('test/kebabedUpperCase.css')
201+
.then(content => {
202+
assert.equal(
203+
content.formatted,
204+
`\
205+
declare const styles: {
206+
readonly 'My-class': string;
207+
};
208+
export = styles;
209+
`
210+
);
211+
done();
212+
});
213+
});
214+
});
215+
182216
describe('#writeFile', () => {
183217
it('accepts a postprocessor function', done => {
184218
new DtsCreator()

0 commit comments

Comments
 (0)