Framework for transforming cascading style sheets (CSS) from left-to-right (LTR) to right-to-left (RTL)
—
RTLCSS provides extensive configuration options to customize transformation behavior, including built-in options, custom plugins, and processing hooks.
Core configuration options that control RTLCSS transformation behavior.
interface RTLCSSOptions {
/** Enable automatic CSS class renaming using string maps */
autoRename?: boolean;
/** Strict mode for auto-renaming - requires matching pairs */
autoRenameStrict?: boolean;
/** Plugin/directive blacklist to disable specific features */
blacklist?: { [pluginName: string]: { [directiveName: string]: boolean } };
/** Remove directive comments after processing */
clean?: boolean;
/** Greedy string matching mode for broader replacements */
greedy?: boolean;
/** Process URLs in CSS rules and at-rules */
processUrls?: boolean | { atrule?: boolean };
/** Custom string replacement mappings */
stringMap?: StringMapEntry[];
/** Use calc() function for flipping length values */
useCalc?: boolean;
/** Property name aliases for custom properties */
aliases?: { [property: string]: string };
/** Process environment-specific values like safe-area-inset */
processEnv?: boolean;
}Default Options:
const defaultOptions = {
autoRename: false,
autoRenameStrict: false,
blacklist: {},
clean: true,
greedy: false,
processUrls: false,
stringMap: [],
useCalc: false,
aliases: {},
processEnv: true
};Usage Examples:
const rtlcss = require("rtlcss");
// Basic options
const options = {
autoRename: true,
clean: false,
processUrls: true
};
const result = rtlcss.process(css, options);
// Advanced options with custom string maps
const advancedOptions = {
autoRename: true,
autoRenameStrict: true,
greedy: true,
stringMap: [
{
name: 'theme-names',
search: ['light-theme', 'dark-theme'],
replace: ['مظهر-فاتح', 'مظهر-داكن'],
priority: 100,
options: { scope: 'selector' }
}
],
aliases: {
'custom-margin-start': 'margin-left',
'custom-margin-end': 'margin-right'
},
blacklist: {
rtlcss: {
ignore: false,
rename: true // Disable rename directive
}
}
};Custom string replacement system for transforming text in CSS selectors and URLs.
interface StringMapEntry {
/** Unique identifier for the string map */
name: string;
/** Processing priority (lower numbers processed first) */
priority: number;
/** String or array of strings to search for */
search: string | string[];
/** Replacement string or array of replacement strings */
replace: string | string[];
/** Stop processing other maps if this one matches */
exclusive?: boolean;
/** Scope and case sensitivity options */
options?: StringMapOptions;
}
interface StringMapOptions {
/** Where to apply the string map */
scope?: '*' | 'url' | 'selector';
/** Case-insensitive matching */
ignoreCase?: boolean;
/** Use greedy matching (overrides global greedy setting) */
greedy?: boolean;
}Built-in String Maps:
RTLCSS automatically includes these string maps if not explicitly provided:
// Left-right transformation
{
name: 'left-right',
priority: 100,
search: ['left', 'Left', 'LEFT'],
replace: ['right', 'Right', 'RIGHT'],
options: { scope: '*', ignoreCase: false }
}
// LTR-RTL transformation
{
name: 'ltr-rtl',
priority: 100,
search: ['ltr', 'Ltr', 'LTR'],
replace: ['rtl', 'Rtl', 'RTL'],
options: { scope: '*', ignoreCase: false }
}Usage Examples:
const stringMaps = [
{
name: 'navigation',
priority: 50,
search: ['nav-left', 'nav-right'],
replace: ['nav-start', 'nav-end'],
options: { scope: 'selector', ignoreCase: true }
},
{
name: 'images',
priority: 75,
search: '/images/ltr/',
replace: '/images/rtl/',
options: { scope: 'url' }
},
{
name: 'exclusive-brand',
priority: 25,
search: 'brand-primary',
replace: 'علامة-أساسية',
exclusive: true, // Stop processing other maps
options: { scope: 'selector' }
}
];
const result = rtlcss.process(css, { stringMap: stringMaps });Load configuration from files or create configurations programmatically.
const configLoader = require("rtlcss/lib/config-loader");
/**
* Load configuration from file or search for config files
* @param configFilePath - Explicit path to config file
* @param cwd - Current working directory for config search
* @param overrides - Override values to merge with loaded config
* @returns Configuration object or null if not found
*/
function load(configFilePath?: string, cwd?: string, overrides?: any): RTLCSSConfiguration | null;Configuration Sources (searched in order):
.rtlcssrc file (current/parent directories).rtlcss.json file (current/parent directories)rtlcssConfig property in package.jsonUsage Examples:
const configLoader = require("rtlcss/lib/config-loader");
// Load from specific file
const config = configLoader.load('./my-rtlcss-config.json');
// Search for config in current directory
const config = configLoader.load();
// Search with overrides
const config = configLoader.load(null, process.cwd(), {
options: { autoRename: true }
});
// Use loaded config
if (config) {
const processor = rtlcss.configure(config);
const result = processor.process(css).css;
}Example Configuration Files:
.rtlcssrc:
{
"options": {
"autoRename": true,
"clean": false,
"stringMap": [
{
"name": "custom-directions",
"search": ["start", "end"],
"replace": ["بداية", "نهاية"],
"priority": 100
}
]
},
"plugins": [],
"hooks": {}
}package.json:
{
"name": "my-app",
"rtlcssConfig": {
"options": {
"processUrls": true,
"autoRename": true
}
}
}Extend RTLCSS functionality with custom plugins.
interface RTLCSSPlugin {
/** Unique plugin identifier */
name: string;
/** Processing priority (lower numbers processed first) */
priority: number;
/** Control and value directives */
directives?: {
control?: { [name: string]: DirectiveHandler };
value?: DirectiveHandler[];
};
/** CSS property processors */
processors?: PropertyProcessor[];
}
interface PropertyProcessor {
/** Regular expression matching CSS properties */
expr: RegExp;
/** Processing function for matched properties */
action: (prop: string, value: string, context: ProcessingContext) => PropertyResult;
}
interface PropertyResult {
/** Transformed property name */
prop: string;
/** Transformed property value */
value: string;
}Usage Examples:
// Custom plugin for handling CSS Grid properties
const gridPlugin = {
name: 'css-grid',
priority: 75,
processors: [
{
expr: /^grid-template-areas$/,
action: (prop, value, context) => {
// Reverse grid template areas for RTL
const reversedValue = value
.split('\n')
.map(line => line.trim().split(' ').reverse().join(' '))
.join('\n');
return { prop: prop, value: reversedValue };
}
},
{
expr: /^grid-column-(start|end)$/,
action: (prop, value, context) => {
// Swap grid column start/end
const newProp = prop.includes('start')
? prop.replace('start', 'end')
: prop.replace('end', 'start');
return { prop: newProp, value: value };
}
}
]
};
// Use custom plugin
const result = rtlcss.process(css, {}, [gridPlugin]);Install with Tessl CLI
npx tessl i tessl/npm-rtlcss