String manipulation utilities including case conversion and length calculation with ANSI code and Unicode support. These functions are essential for form field processing, data transformation, and internationalization.
Advanced string length calculation that handles ANSI escape codes and Unicode properly.
/**
* Calculate the visual length of a string, excluding ANSI escape codes and handling Unicode correctly
* @param input - String to measure
* @returns Visual length of the string
*/
function stringLength(input: string): number;Usage Examples:
import { stringLength } from "@formily/shared";
// Basic string length
console.log(stringLength("hello")); // 5
// ANSI escape codes are excluded from length
const coloredText = "\x1b[31mRed Text\x1b[0m"; // Red colored text
console.log(coloredText.length); // 18 (includes ANSI codes)
console.log(stringLength(coloredText)); // 8 (visual length only)
// Unicode characters (astral characters) handled correctly
const emoji = "👨💻"; // Man technologist emoji (composite character)
console.log(emoji.length); // 5 (JavaScript counts code units)
console.log(stringLength(emoji)); // 1 (visual length)
const mixedUnicode = "Hello 👋 World 🌍";
console.log(mixedUnicode.length); // 15
console.log(stringLength(mixedUnicode)); // 13 (correct visual length)
// Complex terminal output
const terminalOutput = "\x1b[32m✓\x1b[0m Success: \x1b[1mBuild completed\x1b[0m";
console.log(stringLength(terminalOutput)); // Visual length without color codesComprehensive case conversion utilities for different naming conventions.
/**
* Convert string to camelCase
* @param str - String to convert
* @returns String in camelCase format
*/
function camelCase(str: string): string;
/**
* Convert string to PascalCase
* @param str - String to convert
* @returns String in PascalCase format
*/
function pascalCase(str: string): string;
/**
* Convert string to param-case (kebab-case)
* @param str - String to convert
* @returns String in param-case format
*/
function paramCase(str: string): string;
/**
* Convert string to lower case
* @param str - String to convert
* @returns String in lower case
*/
function lowerCase(str: string): string;
/**
* Convert string to UPPER CASE
* @param str - String to convert
* @returns String in upper case
*/
function upperCase(str: string): string;Usage Examples:
import {
camelCase, pascalCase, paramCase,
lowerCase, upperCase
} from "@formily/shared";
// Basic case conversion
const input = "hello-world_example";
console.log(camelCase(input)); // "helloWorldExample"
console.log(pascalCase(input)); // "HelloWorldExample"
console.log(paramCase(input)); // "hello-world-example"
console.log(lowerCase(input)); // "hello world example"
console.log(upperCase(input)); // "HELLO WORLD EXAMPLE"
// Form field name conversion
const formFields = [
"first-name",
"last_name",
"email-address",
"phone_number"
];
// Convert to camelCase for JavaScript
const jsFields = formFields.map(camelCase);
// Result: ["firstName", "lastName", "emailAddress", "phoneNumber"]
// Convert to param-case for HTML attributes
const htmlAttrs = jsFields.map(paramCase);
// Result: ["first-name", "last-name", "email-address", "phone-number"]
// API response transformation
function transformApiResponse(data: Record<string, any>): Record<string, any> {
const transformed: Record<string, any> = {};
for (const [key, value] of Object.entries(data)) {
// Convert snake_case API keys to camelCase
const camelKey = camelCase(key);
transformed[camelKey] = value;
}
return transformed;
}
// Usage
const apiData = {
user_id: 123,
first_name: "John",
last_name: "Doe",
email_address: "john@example.com"
};
const jsData = transformApiResponse(apiData);
/*
Result: {
userId: 123,
firstName: "John",
lastName: "Doe",
emailAddress: "john@example.com"
}
*/import { camelCase, paramCase, stringLength } from "@formily/shared";
// Form validation with proper length checking
function validateFormField(value: string, maxLength: number): boolean {
// Use stringLength for accurate character counting
return stringLength(value) <= maxLength;
}
// Handles Unicode properly
const unicodeInput = "Café 🌟 München"; // Contains accented chars and emoji
console.log(validateFormField(unicodeInput, 15)); // true (visual length: 13)
// CSS class name generation
function generateCSSClassName(componentName: string, modifier?: string): string {
const baseClass = paramCase(componentName);
if (modifier) {
return `${baseClass}--${paramCase(modifier)}`;
}
return baseClass;
}
// Usage
console.log(generateCSSClassName("FormInput")); // "form-input"
console.log(generateCSSClassName("FormInput", "isDisabled")); // "form-input--is-disabled"
// Database column to JavaScript property mapping
function mapDatabaseColumns(rows: Record<string, any>[]): Record<string, any>[] {
return rows.map(row => {
const mappedRow: Record<string, any> = {};
for (const [column, value] of Object.entries(row)) {
// Convert database snake_case to JavaScript camelCase
mappedRow[camelCase(column)] = value;
}
return mappedRow;
});
}
// Usage
const dbRows = [
{ user_id: 1, first_name: "Alice", created_at: "2023-01-01" },
{ user_id: 2, first_name: "Bob", created_at: "2023-01-02" }
];
const jsRows = mapDatabaseColumns(dbRows);
/*
Result: [
{ userId: 1, firstName: "Alice", createdAt: "2023-01-01" },
{ userId: 2, firstName: "Bob", createdAt: "2023-01-02" }
]
*/
// URL slug generation
function createUrlSlug(title: string): string {
return paramCase(title)
.replace(/[^a-z0-9-]/g, '') // Remove non-alphanumeric except hyphens
.replace(/-+/g, '-') // Collapse multiple hyphens
.replace(/^-|-$/g, ''); // Remove leading/trailing hyphens
}
// Usage
console.log(createUrlSlug("My Blog Post Title!")); // "my-blog-post-title"
console.log(createUrlSlug("Hello World???")); // "hello-world"
// Configuration key normalization
function normalizeConfigKeys(config: Record<string, any>, format: 'camel' | 'param' = 'camel'): Record<string, any> {
const normalized: Record<string, any> = {};
const converter = format === 'camel' ? camelCase : paramCase;
for (const [key, value] of Object.entries(config)) {
const normalizedKey = converter(key);
if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
// Recursively normalize nested objects
normalized[normalizedKey] = normalizeConfigKeys(value, format);
} else {
normalized[normalizedKey] = value;
}
}
return normalized;
}
// Usage
const rawConfig = {
"database-host": "localhost",
"database_port": 5432,
"api_settings": {
"max_connections": 100,
"timeout-seconds": 30
}
};
const camelConfig = normalizeConfigKeys(rawConfig, 'camel');
/*
Result: {
databaseHost: "localhost",
databasePort: 5432,
apiSettings: {
maxConnections: 100,
timeoutSeconds: 30
}
}
*/
const paramConfig = normalizeConfigKeys(rawConfig, 'param');
/*
Result: {
"database-host": "localhost",
"database-port": 5432,
"api-settings": {
"max-connections": 100,
"timeout-seconds": 30
}
}
*/The string processing utilities in @formily/shared use well-tested external libraries for case conversion:
camel-case librarypascal-case libraryparam-case librarylower-case libraryupper-case libraryThe stringLength function includes:
These utilities are particularly useful for: