Flutter ColorFiltered Localization: Color Matrix Effects for Multilingual Apps
ColorFiltered applies color matrix transformations to its child widget, enabling grayscale conversions, color adjustments, sepia tones, and dynamic color effects. When combined with localization, ColorFiltered creates accessible visual states, cultural color adaptations, and context-aware visual feedback that works seamlessly across different languages and regions. This guide covers comprehensive strategies for localizing ColorFiltered widgets in Flutter multilingual applications.
Understanding ColorFiltered Localization
ColorFiltered widgets require localization for:
- Accessibility states: Visual indicators for disabled or inactive content
- Cultural color meanings: Adapting color effects for regional preferences
- Status indicators: Color-coded states with localized descriptions
- Image treatments: Culturally appropriate image processing
- Theme adaptations: Color effects that match locale preferences
- Loading states: Desaturated placeholders with localized text
Basic ColorFiltered with Localized Content
Start with a simple grayscale toggle example:
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
class LocalizedColorFilteredDemo extends StatefulWidget {
const LocalizedColorFilteredDemo({super.key});
@override
State<LocalizedColorFilteredDemo> createState() => _LocalizedColorFilteredDemoState();
}
class _LocalizedColorFilteredDemoState extends State<LocalizedColorFilteredDemo> {
bool _isEnabled = true;
@override
Widget build(BuildContext context) {
final l10n = AppLocalizations.of(context)!;
return Scaffold(
appBar: AppBar(title: Text(l10n.colorFilterDemoTitle)),
body: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SwitchListTile(
title: Text(l10n.enableContentLabel),
subtitle: Text(
_isEnabled
? l10n.contentEnabledStatus
: l10n.contentDisabledStatus,
),
value: _isEnabled,
onChanged: (value) => setState(() => _isEnabled = value),
),
const SizedBox(height: 24),
Expanded(
child: Semantics(
label: _isEnabled
? l10n.contentActiveAccessibility
: l10n.contentInactiveAccessibility,
child: ColorFiltered(
colorFilter: _isEnabled
? const ColorFilter.mode(
Colors.transparent,
BlendMode.multiply,
)
: const ColorFilter.matrix(<double>[
0.2126, 0.7152, 0.0722, 0, 0,
0.2126, 0.7152, 0.0722, 0, 0,
0.2126, 0.7152, 0.0722, 0, 0,
0, 0, 0, 1, 0,
]),
child: _buildContentCard(context, l10n),
),
),
),
],
),
),
);
}
Widget _buildContentCard(BuildContext context, AppLocalizations l10n) {
return Card(
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ClipRRect(
borderRadius: BorderRadius.circular(12),
child: Image.network(
'https://picsum.photos/400/200',
width: double.infinity,
height: 150,
fit: BoxFit.cover,
),
),
const SizedBox(height: 16),
Text(
l10n.featureCardTitle,
style: Theme.of(context).textTheme.headlineSmall,
),
const SizedBox(height: 8),
Text(
l10n.featureCardDescription,
style: Theme.of(context).textTheme.bodyMedium,
),
const SizedBox(height: 16),
ElevatedButton(
onPressed: _isEnabled ? () {} : null,
child: Text(l10n.learnMoreButton),
),
],
),
),
);
}
}
ARB File Structure for ColorFiltered
{
"colorFilterDemoTitle": "Color Effects",
"@colorFilterDemoTitle": {
"description": "Title for color filter demo page"
},
"enableContentLabel": "Enable Content",
"contentEnabledStatus": "Content is active and interactive",
"contentDisabledStatus": "Content is disabled and shown in grayscale",
"contentActiveAccessibility": "Content section is currently active",
"contentInactiveAccessibility": "Content section is currently disabled, shown in grayscale",
"featureCardTitle": "Premium Feature",
"featureCardDescription": "Unlock advanced capabilities with our premium subscription plan.",
"learnMoreButton": "Learn More"
}
Disabled State Indicator
Create a disabled overlay with localized messaging:
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
class LocalizedDisabledOverlay extends StatelessWidget {
final Widget child;
final bool isDisabled;
final String? disabledReason;
const LocalizedDisabledOverlay({
super.key,
required this.child,
required this.isDisabled,
this.disabledReason,
});
static const ColorFilter _grayscaleFilter = ColorFilter.matrix(<double>[
0.2126, 0.7152, 0.0722, 0, 0,
0.2126, 0.7152, 0.0722, 0, 0,
0.2126, 0.7152, 0.0722, 0, 0,
0, 0, 0, 0.6, 0,
]);
@override
Widget build(BuildContext context) {
final l10n = AppLocalizations.of(context)!;
if (!isDisabled) {
return child;
}
return Semantics(
label: disabledReason ?? l10n.disabledContentAccessibility,
child: Stack(
children: [
ColorFiltered(
colorFilter: _grayscaleFilter,
child: IgnorePointer(child: child),
),
Positioned.fill(
child: Container(
color: Colors.black.withOpacity(0.1),
child: Center(
child: Container(
padding: const EdgeInsets.symmetric(
horizontal: 24,
vertical: 12,
),
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surface,
borderRadius: BorderRadius.circular(8),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.1),
blurRadius: 8,
offset: const Offset(0, 2),
),
],
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(
Icons.lock_outline,
color: Theme.of(context).colorScheme.onSurfaceVariant,
),
const SizedBox(width: 8),
Text(
disabledReason ?? l10n.contentLockedMessage,
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
color: Theme.of(context).colorScheme.onSurfaceVariant,
),
),
],
),
),
),
),
),
],
),
);
}
}
class SubscriptionGatedContent extends StatelessWidget {
final bool hasSubscription;
const SubscriptionGatedContent({
super.key,
required this.hasSubscription,
});
@override
Widget build(BuildContext context) {
final l10n = AppLocalizations.of(context)!;
return LocalizedDisabledOverlay(
isDisabled: !hasSubscription,
disabledReason: l10n.subscriptionRequired,
child: Card(
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Icon(
Icons.star,
color: Colors.amber,
),
const SizedBox(width: 8),
Text(
l10n.premiumContentTitle,
style: Theme.of(context).textTheme.titleLarge,
),
],
),
const SizedBox(height: 12),
Text(l10n.premiumContentDescription),
const SizedBox(height: 16),
Row(
children: [
ElevatedButton(
onPressed: () {},
child: Text(l10n.viewContentButton),
),
const SizedBox(width: 8),
TextButton(
onPressed: () {},
child: Text(l10n.shareButton),
),
],
),
],
),
),
),
);
}
}
Sepia and Vintage Effects
Create culturally appropriate image filters:
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
enum ImageFilterType {
none,
grayscale,
sepia,
vintage,
cool,
warm,
}
class LocalizedImageFilters extends StatefulWidget {
const LocalizedImageFilters({super.key});
@override
State<LocalizedImageFilters> createState() => _LocalizedImageFiltersState();
}
class _LocalizedImageFiltersState extends State<LocalizedImageFilters> {
ImageFilterType _selectedFilter = ImageFilterType.none;
ColorFilter? _getColorFilter(ImageFilterType type) {
switch (type) {
case ImageFilterType.none:
return null;
case ImageFilterType.grayscale:
return const ColorFilter.matrix(<double>[
0.2126, 0.7152, 0.0722, 0, 0,
0.2126, 0.7152, 0.0722, 0, 0,
0.2126, 0.7152, 0.0722, 0, 0,
0, 0, 0, 1, 0,
]);
case ImageFilterType.sepia:
return const ColorFilter.matrix(<double>[
0.393, 0.769, 0.189, 0, 0,
0.349, 0.686, 0.168, 0, 0,
0.272, 0.534, 0.131, 0, 0,
0, 0, 0, 1, 0,
]);
case ImageFilterType.vintage:
return const ColorFilter.matrix(<double>[
0.9, 0.5, 0.1, 0, 0,
0.3, 0.8, 0.1, 0, 0,
0.2, 0.3, 0.5, 0, 0,
0, 0, 0, 1, 0,
]);
case ImageFilterType.cool:
return const ColorFilter.matrix(<double>[
1, 0, 0, 0, 0,
0, 1, 0, 0, 0,
0, 0, 1.2, 0, 20,
0, 0, 0, 1, 0,
]);
case ImageFilterType.warm:
return const ColorFilter.matrix(<double>[
1.2, 0, 0, 0, 20,
0, 1, 0, 0, 0,
0, 0, 0.9, 0, 0,
0, 0, 0, 1, 0,
]);
}
}
String _getFilterName(AppLocalizations l10n, ImageFilterType type) {
switch (type) {
case ImageFilterType.none:
return l10n.filterNone;
case ImageFilterType.grayscale:
return l10n.filterGrayscale;
case ImageFilterType.sepia:
return l10n.filterSepia;
case ImageFilterType.vintage:
return l10n.filterVintage;
case ImageFilterType.cool:
return l10n.filterCool;
case ImageFilterType.warm:
return l10n.filterWarm;
}
}
@override
Widget build(BuildContext context) {
final l10n = AppLocalizations.of(context)!;
return Scaffold(
appBar: AppBar(title: Text(l10n.imageFiltersTitle)),
body: Column(
children: [
Expanded(
child: Padding(
padding: const EdgeInsets.all(16),
child: Semantics(
label: l10n.filteredImageAccessibility(
_getFilterName(l10n, _selectedFilter),
),
child: ClipRRect(
borderRadius: BorderRadius.circular(16),
child: _selectedFilter == ImageFilterType.none
? Image.network(
'https://picsum.photos/600/800',
fit: BoxFit.cover,
width: double.infinity,
)
: ColorFiltered(
colorFilter: _getColorFilter(_selectedFilter)!,
child: Image.network(
'https://picsum.photos/600/800',
fit: BoxFit.cover,
width: double.infinity,
),
),
),
),
),
),
Container(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
l10n.selectFilterLabel,
style: Theme.of(context).textTheme.titleMedium,
),
const SizedBox(height: 12),
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: ImageFilterType.values.map((filter) {
final isSelected = _selectedFilter == filter;
return Padding(
padding: const EdgeInsets.only(right: 8),
child: FilterChip(
selected: isSelected,
label: Text(_getFilterName(l10n, filter)),
onSelected: (selected) {
setState(() => _selectedFilter = filter);
},
),
);
}).toList(),
),
),
],
),
),
],
),
);
}
}
Status Color Indicators
Create color-coded status with cultural awareness:
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
enum TaskStatus {
pending,
inProgress,
completed,
failed,
onHold,
}
class LocalizedStatusIndicator extends StatelessWidget {
final TaskStatus status;
final Widget child;
const LocalizedStatusIndicator({
super.key,
required this.status,
required this.child,
});
ColorFilter _getStatusFilter(TaskStatus status) {
switch (status) {
case TaskStatus.pending:
// Slightly desaturated
return const ColorFilter.matrix(<double>[
0.8, 0.1, 0.1, 0, 0,
0.1, 0.8, 0.1, 0, 0,
0.1, 0.1, 0.8, 0, 0,
0, 0, 0, 0.8, 0,
]);
case TaskStatus.inProgress:
// Normal colors
return const ColorFilter.mode(
Colors.transparent,
BlendMode.multiply,
);
case TaskStatus.completed:
// Green tint
return const ColorFilter.matrix(<double>[
0.8, 0, 0, 0, 0,
0.1, 1.1, 0.1, 0, 20,
0, 0, 0.8, 0, 0,
0, 0, 0, 1, 0,
]);
case TaskStatus.failed:
// Red tint
return const ColorFilter.matrix(<double>[
1.2, 0, 0, 0, 30,
0, 0.8, 0, 0, 0,
0, 0, 0.8, 0, 0,
0, 0, 0, 1, 0,
]);
case TaskStatus.onHold:
// Grayscale with slight yellow
return const ColorFilter.matrix(<double>[
0.4, 0.4, 0.2, 0, 20,
0.4, 0.4, 0.2, 0, 20,
0.2, 0.2, 0.2, 0, 0,
0, 0, 0, 0.7, 0,
]);
}
}
@override
Widget build(BuildContext context) {
final l10n = AppLocalizations.of(context)!;
return Semantics(
label: _getStatusAccessibility(l10n, status),
child: ColorFiltered(
colorFilter: _getStatusFilter(status),
child: child,
),
);
}
String _getStatusAccessibility(AppLocalizations l10n, TaskStatus status) {
switch (status) {
case TaskStatus.pending:
return l10n.statusPendingAccessibility;
case TaskStatus.inProgress:
return l10n.statusInProgressAccessibility;
case TaskStatus.completed:
return l10n.statusCompletedAccessibility;
case TaskStatus.failed:
return l10n.statusFailedAccessibility;
case TaskStatus.onHold:
return l10n.statusOnHoldAccessibility;
}
}
}
class TaskListDemo extends StatelessWidget {
const TaskListDemo({super.key});
@override
Widget build(BuildContext context) {
final l10n = AppLocalizations.of(context)!;
final tasks = [
(l10n.taskDesign, TaskStatus.completed),
(l10n.taskDevelopment, TaskStatus.inProgress),
(l10n.taskTesting, TaskStatus.pending),
(l10n.taskDeployment, TaskStatus.onHold),
(l10n.taskReview, TaskStatus.failed),
];
return Scaffold(
appBar: AppBar(title: Text(l10n.taskListTitle)),
body: ListView.builder(
padding: const EdgeInsets.all(16),
itemCount: tasks.length,
itemBuilder: (context, index) {
final (title, status) = tasks[index];
return LocalizedStatusIndicator(
status: status,
child: Card(
margin: const EdgeInsets.only(bottom: 12),
child: ListTile(
leading: _buildStatusIcon(status),
title: Text(title),
subtitle: Text(_getStatusLabel(l10n, status)),
trailing: const Icon(Icons.chevron_right),
),
),
);
},
),
);
}
Widget _buildStatusIcon(TaskStatus status) {
IconData icon;
Color color;
switch (status) {
case TaskStatus.pending:
icon = Icons.schedule;
color = Colors.grey;
break;
case TaskStatus.inProgress:
icon = Icons.play_circle_outline;
color = Colors.blue;
break;
case TaskStatus.completed:
icon = Icons.check_circle;
color = Colors.green;
break;
case TaskStatus.failed:
icon = Icons.error;
color = Colors.red;
break;
case TaskStatus.onHold:
icon = Icons.pause_circle_outline;
color = Colors.orange;
break;
}
return Icon(icon, color: color);
}
String _getStatusLabel(AppLocalizations l10n, TaskStatus status) {
switch (status) {
case TaskStatus.pending:
return l10n.statusPending;
case TaskStatus.inProgress:
return l10n.statusInProgress;
case TaskStatus.completed:
return l10n.statusCompleted;
case TaskStatus.failed:
return l10n.statusFailed;
case TaskStatus.onHold:
return l10n.statusOnHold;
}
}
}
Accessibility Mode Filter
Create high contrast and accessibility filters:
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
enum AccessibilityMode {
normal,
highContrast,
grayscale,
invertColors,
reducedColors,
}
class LocalizedAccessibilityFilter extends StatelessWidget {
final AccessibilityMode mode;
final Widget child;
const LocalizedAccessibilityFilter({
super.key,
required this.mode,
required this.child,
});
ColorFilter? _getAccessibilityFilter(AccessibilityMode mode) {
switch (mode) {
case AccessibilityMode.normal:
return null;
case AccessibilityMode.highContrast:
return const ColorFilter.matrix(<double>[
1.5, -0.25, -0.25, 0, 0,
-0.25, 1.5, -0.25, 0, 0,
-0.25, -0.25, 1.5, 0, 0,
0, 0, 0, 1, 0,
]);
case AccessibilityMode.grayscale:
return const ColorFilter.matrix(<double>[
0.2126, 0.7152, 0.0722, 0, 0,
0.2126, 0.7152, 0.0722, 0, 0,
0.2126, 0.7152, 0.0722, 0, 0,
0, 0, 0, 1, 0,
]);
case AccessibilityMode.invertColors:
return const ColorFilter.matrix(<double>[
-1, 0, 0, 0, 255,
0, -1, 0, 0, 255,
0, 0, -1, 0, 255,
0, 0, 0, 1, 0,
]);
case AccessibilityMode.reducedColors:
return const ColorFilter.matrix(<double>[
0.5, 0.25, 0.25, 0, 0,
0.25, 0.5, 0.25, 0, 0,
0.25, 0.25, 0.5, 0, 0,
0, 0, 0, 1, 0,
]);
}
}
@override
Widget build(BuildContext context) {
final filter = _getAccessibilityFilter(mode);
if (filter == null) {
return child;
}
return ColorFiltered(
colorFilter: filter,
child: child,
);
}
}
class AccessibilitySettingsDemo extends StatefulWidget {
const AccessibilitySettingsDemo({super.key});
@override
State<AccessibilitySettingsDemo> createState() => _AccessibilitySettingsDemoState();
}
class _AccessibilitySettingsDemoState extends State<AccessibilitySettingsDemo> {
AccessibilityMode _currentMode = AccessibilityMode.normal;
@override
Widget build(BuildContext context) {
final l10n = AppLocalizations.of(context)!;
return Scaffold(
appBar: AppBar(title: Text(l10n.accessibilitySettingsTitle)),
body: Column(
children: [
Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
l10n.colorModeLabel,
style: Theme.of(context).textTheme.titleMedium,
),
const SizedBox(height: 12),
Wrap(
spacing: 8,
runSpacing: 8,
children: AccessibilityMode.values.map((mode) {
return ChoiceChip(
selected: _currentMode == mode,
label: Text(_getModeName(l10n, mode)),
onSelected: (selected) {
if (selected) {
setState(() => _currentMode = mode);
}
},
);
}).toList(),
),
],
),
),
const Divider(),
Expanded(
child: LocalizedAccessibilityFilter(
mode: _currentMode,
child: ListView(
padding: const EdgeInsets.all(16),
children: [
_buildSampleCard(
context,
l10n,
l10n.sampleCard1Title,
l10n.sampleCard1Description,
Colors.blue,
Icons.favorite,
),
const SizedBox(height: 12),
_buildSampleCard(
context,
l10n,
l10n.sampleCard2Title,
l10n.sampleCard2Description,
Colors.green,
Icons.star,
),
const SizedBox(height: 12),
_buildSampleCard(
context,
l10n,
l10n.sampleCard3Title,
l10n.sampleCard3Description,
Colors.orange,
Icons.bookmark,
),
],
),
),
),
],
),
);
}
String _getModeName(AppLocalizations l10n, AccessibilityMode mode) {
switch (mode) {
case AccessibilityMode.normal:
return l10n.modeNormal;
case AccessibilityMode.highContrast:
return l10n.modeHighContrast;
case AccessibilityMode.grayscale:
return l10n.modeGrayscale;
case AccessibilityMode.invertColors:
return l10n.modeInverted;
case AccessibilityMode.reducedColors:
return l10n.modeReducedColors;
}
}
Widget _buildSampleCard(
BuildContext context,
AppLocalizations l10n,
String title,
String description,
Color accentColor,
IconData icon,
) {
return Card(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
height: 100,
decoration: BoxDecoration(
color: accentColor,
borderRadius: const BorderRadius.vertical(
top: Radius.circular(12),
),
),
child: Center(
child: Icon(
icon,
size: 48,
color: Colors.white,
),
),
),
Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
title,
style: Theme.of(context).textTheme.titleMedium,
),
const SizedBox(height: 8),
Text(description),
],
),
),
],
),
);
}
}
Animated Color Transitions
Create smooth filter transitions:
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
class LocalizedAnimatedColorFilter extends StatefulWidget {
final bool isActive;
final Widget child;
const LocalizedAnimatedColorFilter({
super.key,
required this.isActive,
required this.child,
});
@override
State<LocalizedAnimatedColorFilter> createState() =>
_LocalizedAnimatedColorFilterState();
}
class _LocalizedAnimatedColorFilterState
extends State<LocalizedAnimatedColorFilter>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation<double> _animation;
@override
void initState() {
super.initState();
_controller = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 300),
);
_animation = CurvedAnimation(
parent: _controller,
curve: Curves.easeInOut,
);
if (!widget.isActive) {
_controller.value = 1.0;
}
}
@override
void didUpdateWidget(LocalizedAnimatedColorFilter oldWidget) {
super.didUpdateWidget(oldWidget);
if (widget.isActive != oldWidget.isActive) {
if (widget.isActive) {
_controller.reverse();
} else {
_controller.forward();
}
}
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
List<double> _interpolateMatrix(double t) {
// Identity matrix
const identity = <double>[
1, 0, 0, 0, 0,
0, 1, 0, 0, 0,
0, 0, 1, 0, 0,
0, 0, 0, 1, 0,
];
// Grayscale matrix
const grayscale = <double>[
0.2126, 0.7152, 0.0722, 0, 0,
0.2126, 0.7152, 0.0722, 0, 0,
0.2126, 0.7152, 0.0722, 0, 0,
0, 0, 0, 0.6, 0,
];
return List.generate(20, (i) {
return identity[i] + (grayscale[i] - identity[i]) * t;
});
}
@override
Widget build(BuildContext context) {
final l10n = AppLocalizations.of(context)!;
return AnimatedBuilder(
animation: _animation,
builder: (context, child) {
return Semantics(
label: widget.isActive
? l10n.contentActiveAccessibility
: l10n.contentInactiveAccessibility,
child: ColorFiltered(
colorFilter: ColorFilter.matrix(_interpolateMatrix(_animation.value)),
child: child,
),
);
},
child: widget.child,
);
}
}
class AnimatedFilterDemo extends StatefulWidget {
const AnimatedFilterDemo({super.key});
@override
State<AnimatedFilterDemo> createState() => _AnimatedFilterDemoState();
}
class _AnimatedFilterDemoState extends State<AnimatedFilterDemo> {
final List<bool> _itemStates = List.generate(5, (_) => true);
@override
Widget build(BuildContext context) {
final l10n = AppLocalizations.of(context)!;
return Scaffold(
appBar: AppBar(title: Text(l10n.animatedFilterTitle)),
body: ListView.builder(
padding: const EdgeInsets.all(16),
itemCount: _itemStates.length,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.only(bottom: 12),
child: LocalizedAnimatedColorFilter(
isActive: _itemStates[index],
child: Card(
child: ListTile(
leading: const CircleAvatar(
backgroundImage: NetworkImage('https://picsum.photos/100'),
),
title: Text(l10n.itemTitle(index + 1)),
subtitle: Text(
_itemStates[index]
? l10n.itemActiveStatus
: l10n.itemInactiveStatus,
),
trailing: Switch(
value: _itemStates[index],
onChanged: (value) {
setState(() => _itemStates[index] = value);
},
),
),
),
),
);
},
),
);
}
}
Complete ARB File for ColorFiltered
{
"@@locale": "en",
"colorFilterDemoTitle": "Color Effects",
"enableContentLabel": "Enable Content",
"contentEnabledStatus": "Content is active and interactive",
"contentDisabledStatus": "Content is disabled and shown in grayscale",
"contentActiveAccessibility": "Content section is currently active",
"contentInactiveAccessibility": "Content section is currently disabled",
"featureCardTitle": "Premium Feature",
"featureCardDescription": "Unlock advanced capabilities with our premium subscription plan.",
"learnMoreButton": "Learn More",
"disabledContentAccessibility": "This content is currently disabled",
"contentLockedMessage": "Content Locked",
"subscriptionRequired": "Premium subscription required",
"premiumContentTitle": "Premium Content",
"premiumContentDescription": "Exclusive features and content for premium members.",
"viewContentButton": "View",
"shareButton": "Share",
"imageFiltersTitle": "Image Filters",
"filteredImageAccessibility": "Image with {filterName} filter applied",
"@filteredImageAccessibility": {
"placeholders": {
"filterName": {"type": "String"}
}
},
"selectFilterLabel": "Select Filter",
"filterNone": "Original",
"filterGrayscale": "Grayscale",
"filterSepia": "Sepia",
"filterVintage": "Vintage",
"filterCool": "Cool",
"filterWarm": "Warm",
"taskListTitle": "Task Progress",
"taskDesign": "UI Design",
"taskDevelopment": "Development",
"taskTesting": "Testing",
"taskDeployment": "Deployment",
"taskReview": "Code Review",
"statusPending": "Pending",
"statusInProgress": "In Progress",
"statusCompleted": "Completed",
"statusFailed": "Failed",
"statusOnHold": "On Hold",
"statusPendingAccessibility": "Task status: pending",
"statusInProgressAccessibility": "Task status: in progress",
"statusCompletedAccessibility": "Task status: completed",
"statusFailedAccessibility": "Task status: failed",
"statusOnHoldAccessibility": "Task status: on hold",
"accessibilitySettingsTitle": "Display Settings",
"colorModeLabel": "Color Mode",
"modeNormal": "Normal",
"modeHighContrast": "High Contrast",
"modeGrayscale": "Grayscale",
"modeInverted": "Inverted",
"modeReducedColors": "Reduced Colors",
"sampleCard1Title": "Favorites",
"sampleCard1Description": "Your favorite items and bookmarks",
"sampleCard2Title": "Featured",
"sampleCard2Description": "Highlighted content and recommendations",
"sampleCard3Title": "Saved",
"sampleCard3Description": "Items saved for later viewing",
"animatedFilterTitle": "Toggle Items",
"itemTitle": "Item {number}",
"@itemTitle": {
"placeholders": {
"number": {"type": "int"}
}
},
"itemActiveStatus": "Active",
"itemInactiveStatus": "Inactive"
}
Best Practices Summary
- Provide accessibility descriptions: Always describe what color effects mean for screen reader users
- Use appropriate blend modes: Choose blend modes that preserve readability
- Animate transitions: Smooth color filter changes are less jarring
- Consider color blindness: Test filters with various color vision deficiencies
- Maintain contrast: Ensure text remains readable after filter application
- Cultural awareness: Color meanings vary across cultures
- Performance optimization: Use const color filters where possible
- Combine with semantics: Explain visual state changes to assistive technologies
- Test across themes: Verify filters work in both light and dark modes
- Provide alternatives: Offer text labels alongside color-coded information
Conclusion
ColorFiltered enables powerful visual treatments like grayscale states, sepia effects, status indicators, and accessibility modes that enhance multilingual applications. By providing proper accessibility labels and considering cultural color associations, you can build applications that communicate effectively through color while remaining accessible to all users. The key is balancing visual feedback with clear textual descriptions that translate well across languages.
Remember to test your color filters across different devices and with various accessibility settings to ensure your visual treatments work well for all users regardless of their language or abilities.