ESLint plugin that enforces static analysis requirements for React Native platform color APIs
npx @tessl/cli install tessl/npm-react-native-community--eslint-plugin@1.3.0ESLint plugin that enforces static analysis requirements for React Native platform color APIs. This plugin ensures that calls to PlatformColor() and DynamicColorIOS() use only literal arguments, enabling static analysis optimizations for color-related APIs in React Native applications.
npm install --save-dev @react-native-community/eslint-pluginThe plugin is used in ESLint configuration rather than imported directly in code:
{
"plugins": ["@react-native-community"]
}For programmatic access to rules:
const { rules } = require("@react-native-community/eslint-plugin");CommonJS:
const plugin = require("@react-native-community/eslint-plugin");
const platformColorsRule = plugin.rules["platform-colors"];Add the plugin to your ESLint configuration and enable the rule:
{
"plugins": ["@react-native-community"],
"rules": {
"@react-native-community/platform-colors": "error"
}
}The rule will then enforce proper usage of platform color APIs:
// ✅ Valid - literal arguments
const color1 = PlatformColor('labelColor');
const color2 = PlatformColor('controlAccentColor', 'controlColor');
const color3 = DynamicColorIOS({light: 'black', dark: 'white'});
// ❌ Invalid - variable arguments not allowed
const colorName = 'labelColor';
const color4 = PlatformColor(colorName); // ESLint error
// ❌ Invalid - no arguments
const color5 = PlatformColor(); // ESLint errorThe main plugin export providing access to all ESLint rules.
/**
* Main plugin export containing all ESLint rules
*/
interface ESLintPlugin {
rules: {
"platform-colors": ESLintRule;
};
}ESLint rule that validates PlatformColor() and DynamicColorIOS() function calls to ensure they use literal arguments for static analysis.
/**
* ESLint rule for platform color validation
*/
interface ESLintRule {
meta: RuleMeta;
create: (context: ESLintContext) => RuleVisitor;
}
interface RuleMeta {
type: "problem";
docs: {
description: string;
};
messages: {
platformColorArgsLength: string;
platformColorArgTypes: string;
dynamicColorIOSArg: string;
dynamicColorIOSValue: string;
};
schema: [];
}
interface RuleVisitor {
CallExpression: (node: CallExpressionNode) => void;
}The rule enforces the following requirements:
PlatformColor() callsError messages provided by the platform-colors rule for different validation failures.
interface RuleMessages {
/** Error when PlatformColor() is called with no arguments */
platformColorArgsLength: "PlatformColor() must have at least one argument that is a literal.";
/** Error when PlatformColor() arguments are not literals */
platformColorArgTypes: "PlatformColor() every argument must be a literal.";
/** Error when DynamicColorIOS() doesn't take a single object argument */
dynamicColorIOSArg: "DynamicColorIOS() must take a single argument of type Object";
/** Error when DynamicColorIOS() object properties are not literals or PlatformColor calls */
dynamicColorIOSValue: "DynamicColorIOS() value must be either a literal or a PlatformColor() call.";
}Basic ESLint configuration with the plugin:
{
"extends": ["@react-native-community"],
"plugins": ["@react-native-community"],
"rules": {
"@react-native-community/platform-colors": "error"
}
}Examples of platform color usage that pass validation:
// Single platform color
const labelColor = PlatformColor('labelColor');
// Multiple fallback colors
const accentColor = PlatformColor('controlAccentColor', 'controlColor');
// Dynamic color with literals
const adaptiveColor = DynamicColorIOS({
light: 'black',
dark: 'white'
});
// Dynamic color with PlatformColor calls
const systemAdaptiveColor = DynamicColorIOS({
light: PlatformColor('black'),
dark: PlatformColor('white'),
highContrastLight: PlatformColor('black'),
highContrastDark: PlatformColor('white')
});Examples that will trigger ESLint errors:
// ❌ No arguments
const color1 = PlatformColor();
// ❌ Variable argument
const colorName = 'labelColor';
const color2 = PlatformColor(colorName);
// ❌ Non-object argument to DynamicColorIOS
const colorConfig = {light: 'black', dark: 'white'};
const color3 = DynamicColorIOS(colorConfig);
// ❌ Variable property values
const lightColor = 'black';
const color4 = DynamicColorIOS({
light: lightColor,
dark: 'white'
});/**
* ESLint context object passed to rule create function
*/
interface ESLintContext {
/** Report a rule violation */
report(descriptor: {
node: ASTNode;
messageId: string;
}): void;
}
/**
* AST node representing a function call expression
*/
interface CallExpressionNode {
type: "CallExpression";
callee: {
name: string;
};
arguments: ArgumentNode[];
}
/**
* AST node representing function arguments
*/
interface ArgumentNode {
type: "Literal" | "ObjectExpression" | string;
properties?: PropertyNode[];
}
/**
* AST node representing object properties
*/
interface PropertyNode {
type: "Property";
value: {
type: "Literal" | "CallExpression" | string;
callee?: {
name: string;
};
};
}