Skip to content

Commit a06c4d1

Browse files
vozzensindresorhus
andauthored
Add locale option (#75)
Co-authored-by: Sindre Sorhus <[email protected]>
1 parent 20591fb commit a06c4d1

File tree

5 files changed

+78
-10
lines changed

5 files changed

+78
-10
lines changed

index.d.ts

+27
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,30 @@ declare namespace camelcase {
66
@default false
77
*/
88
readonly pascalCase?: boolean;
9+
10+
/**
11+
The locale parameter indicates the locale to be used to convert to upper/lower case according to any locale-specific case mappings. If multiple locales are given in an array, the best available locale is used.
12+
13+
Default: The host environment’s current locale.
14+
15+
@example
16+
```
17+
import camelCase = require('camelcase');
18+
19+
camelCase('lorem-ipsum', {locale: 'en-US'});
20+
//=> 'loremIpsum'
21+
22+
camelCase('lorem-ipsum', {locale: 'tr-TR'});
23+
//=> 'loremİpsum'
24+
25+
camelCase('lorem-ipsum', {locale: ['en-US', 'en-GB']});
26+
//=> 'loremIpsum'
27+
28+
camelCase('lorem-ipsum', {locale: ['tr', 'TR', 'tr-TR']});
29+
//=> 'loremİpsum'
30+
```
31+
*/
32+
readonly locale?: string | readonly string[];
933
}
1034
}
1135

@@ -51,6 +75,9 @@ camelCase(['foo', 'bar']);
5175
5276
camelCase(['__foo__', '--bar'], {pascalCase: true});
5377
//=> 'FooBar'
78+
79+
camelCase('lorem-ipsum', {locale: 'en-US'});
80+
//=> 'loremIpsum'
5481
```
5582
*/
5683
declare function camelcase(

index.js

+10-10
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
'use strict';
22

3-
const preserveCamelCase = string => {
3+
const preserveCamelCase = (string, locale) => {
44
let isLastCharLower = false;
55
let isLastCharUpper = false;
66
let isLastLastCharUpper = false;
@@ -20,9 +20,9 @@ const preserveCamelCase = string => {
2020
isLastCharUpper = false;
2121
isLastCharLower = true;
2222
} else {
23-
isLastCharLower = character.toLocaleLowerCase() === character && character.toLocaleUpperCase() !== character;
23+
isLastCharLower = character.toLocaleLowerCase(locale) === character && character.toLocaleUpperCase(locale) !== character;
2424
isLastLastCharUpper = isLastCharUpper;
25-
isLastCharUpper = character.toLocaleUpperCase() === character && character.toLocaleLowerCase() !== character;
25+
isLastCharUpper = character.toLocaleUpperCase(locale) === character && character.toLocaleLowerCase(locale) !== character;
2626
}
2727
}
2828

@@ -39,7 +39,7 @@ const camelCase = (input, options) => {
3939
...options
4040
};
4141

42-
const postProcess = x => options.pascalCase ? x.charAt(0).toLocaleUpperCase() + x.slice(1) : x;
42+
const postProcess = x => options.pascalCase ? x.charAt(0).toLocaleUpperCase(options.locale) + x.slice(1) : x;
4343

4444
if (Array.isArray(input)) {
4545
input = input.map(x => x.trim())
@@ -54,20 +54,20 @@ const camelCase = (input, options) => {
5454
}
5555

5656
if (input.length === 1) {
57-
return options.pascalCase ? input.toLocaleUpperCase() : input.toLocaleLowerCase();
57+
return options.pascalCase ? input.toLocaleUpperCase(options.locale) : input.toLocaleLowerCase(options.locale);
5858
}
5959

60-
const hasUpperCase = input !== input.toLocaleLowerCase();
60+
const hasUpperCase = input !== input.toLocaleLowerCase(options.locale);
6161

6262
if (hasUpperCase) {
63-
input = preserveCamelCase(input);
63+
input = preserveCamelCase(input, options.locale);
6464
}
6565

6666
input = input
6767
.replace(/^[_.\- ]+/, '')
68-
.toLocaleLowerCase()
69-
.replace(/[_.\- ]+([\p{Alpha}\p{N}_]|$)/gu, (_, p1) => p1.toLocaleUpperCase())
70-
.replace(/\d+([\p{Alpha}\p{N}_]|$)/gu, m => m.toLocaleUpperCase());
68+
.toLocaleLowerCase(options.locale)
69+
.replace(/[_.\- ]+([\p{Alpha}\p{N}_]|$)/gu, (_, p1) => p1.toLocaleUpperCase(options.locale))
70+
.replace(/\d+([\p{Alpha}\p{N}_]|$)/gu, m => m.toLocaleUpperCase(options.locale));
7171

7272
return postProcess(input);
7373
};

index.test-d.ts

+4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ import camelCase = require('.');
33

44
expectType<string>(camelCase('foo-bar'));
55
expectType<string>(camelCase('розовый_пушистый_единороги'));
6+
expectType<string>(camelCase('Foo-Bar', {locale: ['tr']}));
7+
expectType<string>(camelCase('Foo-Bar', {locale: ['tr', 'TR', 'tr-TR']}));
8+
expectType<string>(camelCase('Foo-Bar', {pascalCase: true, locale: ['tr']}));
9+
expectType<string>(camelCase('Foo-Bar', {pascalCase: true, locale: ['tr', 'TR', 'tr-TR']}));
610
expectType<string>(camelCase('Foo-Bar', {pascalCase: true}));
711
expectType<string>(camelCase(['foo', 'bar']));
812
expectType<string>(camelCase(['__foo__', '--bar'], {pascalCase: true}));

readme.md

+26
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ camelCase(['foo', 'bar']);
4848

4949
camelCase(['__foo__', '--bar'], {pascalCase: true});
5050
//=> 'FooBar'
51+
52+
camelCase('lorem-ipsum', {locale: 'en-US'});
53+
//=> 'loremIpsum'
5154
```
5255

5356
## API
@@ -71,6 +74,29 @@ Default: `false`
7174

7275
Uppercase the first character: `foo-bar``FooBar`
7376

77+
##### locale
78+
79+
Type: `string | string[]`\
80+
Default: The host environment’s current locale.
81+
82+
The locale parameter indicates the locale to be used to convert to upper/lower case according to any locale-specific case mappings. If multiple locales are given in an array, the best available locale is used.
83+
84+
```js
85+
const camelCase = require('camelcase');
86+
87+
camelCase('lorem-ipsum', {locale: 'en-US'});
88+
//=> 'loremIpsum'
89+
90+
camelCase('lorem-ipsum', {locale: 'tr-TR'});
91+
//=> 'loremİpsum'
92+
93+
camelCase('lorem-ipsum', {locale: ['en-US', 'en-GB']});
94+
//=> 'loremIpsum'
95+
96+
camelCase('lorem-ipsum', {locale: ['tr', 'TR', 'tr-TR']});
97+
//=> 'loremİpsum'
98+
```
99+
74100
## camelcase for enterprise
75101

76102
Available as part of the Tidelift Subscription.

test.js

+11
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,17 @@ test('camelCase with pascalCase option', t => {
130130
t.is(camelCase('桑德_在这里。', {pascalCase: true}), '桑德在这里。');
131131
});
132132

133+
test('camelCase with locale option', t => {
134+
t.is(camelCase('lorem-ipsum', {locale: 'tr-TR'}), 'loremİpsum');
135+
t.is(camelCase('lorem-ipsum', {locale: 'en-EN'}), 'loremIpsum');
136+
t.is(camelCase('lorem-ipsum', {locale: ['tr', 'TR', 'tr-TR']}), 'loremİpsum');
137+
t.is(camelCase('lorem-ipsum', {locale: ['en-EN', 'en-GB']}), 'loremIpsum');
138+
t.is(camelCase('ipsum-dolor', {pascalCase: true, locale: 'tr-TR'}), 'İpsumDolor');
139+
t.is(camelCase('ipsum-dolor', {pascalCase: true, locale: 'en-EN'}), 'IpsumDolor');
140+
t.is(camelCase('ipsum-dolor', {pascalCase: true, locale: ['tr', 'TR', 'tr-TR']}), 'İpsumDolor');
141+
t.is(camelCase('ipsum-dolor', {pascalCase: true, locale: ['en-EN', 'en-GB']}), 'IpsumDolor');
142+
});
143+
133144
test('invalid input', t => {
134145
t.throws(() => {
135146
camelCase(1);

0 commit comments

Comments
 (0)