The CS3 component architecture makes use of TextFormats for all the text-styling needs. This decision was (likely) made to simplify the API, but still allow full control over the formatting of the text.

Natively, there is zero support for CSS styling, in fact, setting a styleSheet on the textField of a component (all components expose their textField instances) results in a run-time error, since TextFormats can not be set on textFields with a styleSheet.

But fear not! Not only are the components easy to extend, but it is not at all difficult to add CSS support to any component. In this example, I have added a styleSheet component style to a TextArea, which plays nicely with the built-in TextFormat. Rather than just posting the source code, I have broken down how the implementation works to provide some insight on how the components work, and how this sort of approach can be applied to any component, for almost any task.

UPDATE: As Freddy pointed out in the comments, once the TextArea has a CSS styleSheet applied to it, it will no longer be editable. Unfortunately this is a limitation of flash, as TextFields with styleSheets are not editable.

Extend the Component

The easiest way to do this is to duplicate the component, and put a new class on it. This will copy the component definition and live preview, and maintain all the component parameters on the instances. You can delete the original component too, since all the skins, and code (compiled in the ComponentShim component in the library) will not be removed.

  1. Duplicate the TextArea Component
  2. Export the new Clip for ActionScript, and set the class to "CSSTextArea"

Set up the class

Create the class which extends TextArea. For this example, I am using CSSTextArea.as, and not putting it in a package for simplicity sake. Make sure the class name and package matches the one you put on the TextArea, and that it's in your project's classpath.

package {
 	import fl.controls.TextArea;	
 	public class CSSTextArea extends TextArea {		
  		public function CSSTextArea() {
   			super();
   		}	
  	}	
}

Add the styleSheet component style

Styles in the CS3 components are ridiculously simple, and in my opinion a pleasure to implement and use (except when they aren't). The basic idea is that each component class has a "definition" of styles that it is interested in. It exposes this by means of the getStyleDefinition() static method. If you don't specify this method, the StyleManager will walk the inheritance chain until it finds one. Also, if you want to add to an existing definition, there is a nifty method you can use called "mergeStyles", which you can merge component definitions. We can use this functionality to define a new "styleSheet" style, and merge it with TextArea's existing styles. Note that we even though we are defining it with a default value of null, it still tells the StyleManager to listen for "styleSheet" style changes on an instance, component, or global level.

private static var defaultStyles:Object = {
 	styleSheet: null
}
public static function getDefaultStyles():Object {
 	return UIComponent.mergeStyles(defaultStyles, TextArea.getStyleDefinition());
}

Don't forget to import fl.core.UIComponent

The code that makes it work

Even though we have defined the styleSheet style, this component is functionally identical to the TextArea. In order to apply it, we have to override the method of TextArea that does the TextFormat work. Luckily, all the classes are included in the installation directory (Adobe Flash CS3/Configuration/Component Source/ActionScript 3.0/User Interface/). Also, most of the textFormatting happens in an isolated method, drawTextFormat. This might not be true for all components, but it shouldn't be too different.

For this example, we want to maintain TextFormat styling, but also add in CSS styling. This means that we will use TextFormat unless the styleSheet style has been defined. Also, we want to maintain the font embedding, and any HTML formatting. If the CSS style isn't defined, we can just default to the TextArea's method.

override protected function drawTextFormat():void {
 	var styleSheet:StyleSheet = getStyleValue("styleSheet") as StyleSheet;
 	textField.styleSheet = styleSheet;
 	if (styleSheet == null) {
  		super.drawTextFormat();
  	} else {
  		setEmbedFont();
  		if (_html) { textField.htmlText = _savedHTML; }
  	}
}

Don't forget to import the flash.text.StyleSheet class

Applying a StyleSheet

All we do now is create a StyleSheet, and apply it to our CSSTextArea. As I mentioned earlier, this can be done on an instance, component, or global basis.

var style:StyleSheet = new StyleSheet();
style.setStyle(".heading", {fontWeight:"bold", color:"#FF0000", fontSize:22});
style.setStyle("body", {fontStyle:"italic"});

t.htmlText = "<body><span class='heading'>Hello</span> World...</body>";

import fl.managers.StyleManager;
t.setStyle("styleSheet", style); // instance
StyleManager.setComponentStyle(CSSTextArea, "styleSheet", style); // All CSSTextArea components
StyleManager.setStyle("styleSheet", style); // All components (who support the style)

Download the CSSTextArea source