Skip to content

Commit 4a1f940

Browse files
committed
feat: add text case converter component
1 parent 192f33f commit 4a1f940

File tree

1 file changed

+159
-0
lines changed
  • apps/developer-hub/src/components/Case

1 file changed

+159
-0
lines changed
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
export const CASE_VARIANTS = [
2+
"Uppercase",
3+
"Lowercase",
4+
"Title Case",
5+
"APA Title Case",
6+
"Sentence Case",
7+
"Snake Case",
8+
"Kebab Case",
9+
"Pascal Case",
10+
"Camel Case",
11+
"Train Case",
12+
"Macro Case",
13+
] as const;
14+
15+
export type CaseVariant = (typeof CASE_VARIANTS)[number];
16+
17+
type Props = {
18+
children: string;
19+
variant: CaseVariant;
20+
};
21+
22+
export const Case = ({ children, variant }: Props) => {
23+
const convertedText = convertCase(children, variant);
24+
return <>{convertedText}</>;
25+
};
26+
27+
const convertCase = (text: string, variant: CaseVariant): string => {
28+
switch (variant) {
29+
case "Uppercase":
30+
return text.toUpperCase();
31+
case "Lowercase":
32+
return text.toLowerCase();
33+
case "Title Case":
34+
return toTitleCase(text);
35+
case "APA Title Case":
36+
return toAPATitleCase(text);
37+
case "Sentence Case":
38+
return toSentenceCase(text);
39+
case "Snake Case":
40+
return toSnakeCase(text);
41+
case "Kebab Case":
42+
return toKebabCase(text);
43+
case "Pascal Case":
44+
return toPascalCase(text);
45+
case "Camel Case":
46+
return toCamelCase(text);
47+
case "Train Case":
48+
return toTrainCase(text);
49+
case "Macro Case":
50+
return toMacroCase(text);
51+
default:
52+
return text;
53+
}
54+
};
55+
56+
// Convert to Title Case (capitalize first letter of each word)
57+
const toTitleCase = (text: string): string => {
58+
return text
59+
.toLowerCase()
60+
.split(" ")
61+
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
62+
.join(" ");
63+
};
64+
65+
// Convert to APA Title Case (capitalize first letter of each word except articles, prepositions, and conjunctions)
66+
const toAPATitleCase = (text: string): string => {
67+
const minorWords = [
68+
"a",
69+
"an",
70+
"the",
71+
"and",
72+
"but",
73+
"or",
74+
"for",
75+
"nor",
76+
"on",
77+
"at",
78+
"to",
79+
"from",
80+
"by",
81+
"in",
82+
"of",
83+
];
84+
85+
const words = text.toLowerCase().split(" ");
86+
87+
// Always capitalize the first and last word
88+
return words
89+
.map((word, index) => {
90+
// Always capitalize first and last word
91+
if (index === 0 || index === words.length - 1) {
92+
return word.charAt(0).toUpperCase() + word.slice(1);
93+
}
94+
95+
// Check if the word is a minor word
96+
if (minorWords.includes(word)) {
97+
return word;
98+
}
99+
100+
// Capitalize other words
101+
return word.charAt(0).toUpperCase() + word.slice(1);
102+
})
103+
.join(" ");
104+
};
105+
106+
// Convert to Sentence Case (capitalize only the first letter of the first word)
107+
const toSentenceCase = (text: string): string => {
108+
if (!text) return text;
109+
return text.charAt(0).toUpperCase() + text.slice(1).toLowerCase();
110+
};
111+
112+
// Convert to Snake Case (lowercase with underscores between words)
113+
const toSnakeCase = (text: string): string => {
114+
return text
115+
.replace(/([A-Z])/g, " $1") // Add space before capital letters
116+
.trim()
117+
.toLowerCase()
118+
.replace(/[^\w\s]/g, "") // Remove special characters
119+
.replace(/\s+/g, "_"); // Replace spaces with underscores
120+
};
121+
122+
// Convert to Kebab Case (lowercase with hyphens between words)
123+
const toKebabCase = (text: string): string => {
124+
return text
125+
.replace(/([A-Z])/g, " $1") // Add space before capital letters
126+
.trim()
127+
.toLowerCase()
128+
.replace(/[^\w\s]/g, "") // Remove special characters
129+
.replace(/\s+/g, "-"); // Replace spaces with hyphens
130+
};
131+
132+
// Convert to Pascal Case (capitalize first letter of each word, no spaces)
133+
const toPascalCase = (text: string): string => {
134+
return text
135+
.replace(/[^\w\s]/g, "") // Remove special characters
136+
.split(/\s+/)
137+
.map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
138+
.join("");
139+
};
140+
141+
// Convert to Camel Case (first word lowercase, capitalize first letter of subsequent words, no spaces)
142+
const toCamelCase = (text: string): string => {
143+
const pascalCase = toPascalCase(text);
144+
return pascalCase.charAt(0).toLowerCase() + pascalCase.slice(1);
145+
};
146+
147+
// Convert to Train Case (capitalize first letter of each word, hyphens between words)
148+
const toTrainCase = (text: string): string => {
149+
return text
150+
.replace(/[^\w\s]/g, "") // Remove special characters
151+
.split(/\s+/)
152+
.map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
153+
.join("-");
154+
};
155+
156+
// Convert to Macro Case (uppercase with underscores between words)
157+
const toMacroCase = (text: string): string => {
158+
return toSnakeCase(text).toUpperCase();
159+
};

0 commit comments

Comments
 (0)