This is an automated email from the ASF dual-hosted git repository.
greg-dove pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/royale-asjs.git
The following commit(s) were added to refs/heads/develop by this push:
new 204195cac6 cumulative WIP on Toast and Color utils, and Icons.
Resolving contrast colors within theme still needs some attention.
204195cac6 is described below
commit 204195cac6d4ba23ab80a8547ff9128f896d52a8
Author: greg-dove <[email protected]>
AuthorDate: Mon Apr 20 15:43:44 2026 +1200
cumulative WIP on Toast and Color utils, and Icons. Resolving contrast
colors within theme still needs some attention.
---
.../projects/Style/src/main/resources/defaults.css | 3 +
.../Style/src/main/resources/style-manifest.xml | 9 +
.../royale/org/apache/royale/style/Application.as | 8 +
.../royale/org/apache/royale/style/StyleUIBase.as | 2 +-
.../main/royale/org/apache/royale/style/Toast.as | 304 ++++++++++++++++
.../org/apache/royale/style/colors/CSSColor.as | 369 --------------------
.../org/apache/royale/style/colors/ColorSwatch.as | 64 +++-
.../style/colors/{CSSColor.as => ColorUtils.as} | 251 ++++++++++++--
.../apache/royale/style/colors/ThemeColorSet.as | 96 ++++--
.../org/apache/royale/style/elements/Textarea.as | 82 +++++
.../org/apache/royale/style/skins/CheckBoxSkin.as | 11 +-
.../layout/InsetBlock.as => skins/IToastSkin.as} | 26 +-
.../org/apache/royale/style/skins/ToastSkin.as | 381 +++++++++++++++++++++
.../royale/style/stylebeads/anim/Animation.as | 16 +-
.../InsetBlockEnd.as => anim/AnimationDuration.as} | 21 +-
.../AnimationIterationCount.as} | 24 +-
.../{Animation.as => AnimationTimingFunction.as} | 86 ++---
.../style/stylebeads/anim/CustomAnimation.as | 105 ++++++
.../{layout/InsetBlockEnd.as => anim/Keyframes.as} | 44 ++-
.../royale/style/stylebeads/layout/Bottom.as | 4 +-
.../apache/royale/style/stylebeads/layout/Inset.as | 4 +-
.../royale/style/stylebeads/layout/InsetBase.as | 9 +-
.../royale/style/stylebeads/layout/InsetBlock.as | 4 +-
.../style/stylebeads/layout/InsetBlockEnd.as | 4 +-
.../style/stylebeads/layout/InsetBlockStart.as | 4 +-
.../style/stylebeads/layout/InsetInlineEnd.as | 4 +-
.../style/stylebeads/layout/InsetInlineStart.as | 4 +-
.../apache/royale/style/stylebeads/layout/Left.as | 4 +-
.../apache/royale/style/stylebeads/layout/Right.as | 4 +-
.../apache/royale/style/stylebeads/layout/Top.as | 4 +-
.../attribute/NotDataState.as} | 32 +-
.../org/apache/royale/style/support/Icons.as | 92 +++++
32 files changed, 1508 insertions(+), 567 deletions(-)
diff --git a/frameworks/projects/Style/src/main/resources/defaults.css
b/frameworks/projects/Style/src/main/resources/defaults.css
index d4b34cc9a9..2afbdea9b7 100644
--- a/frameworks/projects/Style/src/main/resources/defaults.css
+++ b/frameworks/projects/Style/src/main/resources/defaults.css
@@ -224,3 +224,6 @@ Tree
IViewportModel:
ClassReference("org.apache.royale.html.beads.models.ViewportModel");
}
+Toast {
+ IStyleSkin: ClassReference("org.apache.royale.style.skins.ToastSkin");
+}
diff --git a/frameworks/projects/Style/src/main/resources/style-manifest.xml
b/frameworks/projects/Style/src/main/resources/style-manifest.xml
index 7e3f6b0265..fc09f8cedd 100644
--- a/frameworks/projects/Style/src/main/resources/style-manifest.xml
+++ b/frameworks/projects/Style/src/main/resources/style-manifest.xml
@@ -60,6 +60,7 @@
<component id="FlexLayout" class="org.apache.royale.style.beads.FlexLayout"/>
<component id="Link" class="org.apache.royale.style.Link"/>
<component id="HoverState"
class="org.apache.royale.style.stylebeads.states.HoverState"/>
+ <component id="Toast" class="org.apache.royale.style.Toast"/>
<component id="Group" class="org.apache.royale.style.Group"/>
<component id="DataContainer" class="org.apache.royale.style.DataContainer"/>
<component id="List" class="org.apache.royale.style.List"/>
@@ -73,6 +74,7 @@
<component id="ListView" class="org.apache.royale.style.beads.ListView"/>
<component id="DataState"
class="org.apache.royale.style.stylebeads.states.attribute.DataState"/>
+ <component id="NotDataState"
class="org.apache.royale.style.stylebeads.states.attribute.NotDataState"/>
<component id="AriaState"
class="org.apache.royale.style.stylebeads.states.attribute.AriaState"/>
<component id="InertState"
class="org.apache.royale.style.stylebeads.states.attribute.InertState"/>
<component id="FocusWithinState"
class="org.apache.royale.style.stylebeads.states.FocusWithinState"/>
@@ -88,6 +90,7 @@
<component id="MarkerState"
class="org.apache.royale.style.stylebeads.states.pseudo.MarkerState"/>
<component id="PlaceholderState"
class="org.apache.royale.style.stylebeads.states.pseudo.PlaceholderState"/>
<component id="SelectionState"
class="org.apache.royale.style.stylebeads.states.pseudo.SelectionState"/>
+ <component id="NotState"
class="org.apache.royale.style.stylebeads.states.NotState"/>
<component id="PeerPseudo"
class="org.apache.royale.style.stylebeads.states.PeerPseudo"/>
<component id="BackgroundStyle"
class="org.apache.royale.style.stylebeads.BackgroundStyle"/>
@@ -143,6 +146,11 @@
<component id="WordBreak"
class="org.apache.royale.style.stylebeads.typography.WordBreak"/>
<component id="Animation"
class="org.apache.royale.style.stylebeads.anim.Animation"/>
+ <component id="CustomAnimation"
class="org.apache.royale.style.stylebeads.anim.CustomAnimation"/>
+ <component id="Keyframes"
class="org.apache.royale.style.stylebeads.anim.Keyframes"/>
+ <component id="AnimationDuration"
class="org.apache.royale.style.stylebeads.anim.AnimationDuration"/>
+ <component id="AnimationTimingFunction"
class="org.apache.royale.style.stylebeads.anim.AnimationTimingFunction"/>
+ <component id="Transition"
class="org.apache.royale.style.stylebeads.anim.Transition"/>
<component id="TransitionBehavior"
class="org.apache.royale.style.stylebeads.anim.TransitionBehavior"/>
<component id="TransitionDelay"
class="org.apache.royale.style.stylebeads.anim.TransitionDelay"/>
<component id="TransitionDuration"
class="org.apache.royale.style.stylebeads.anim.TransitionDuration"/>
@@ -322,5 +330,6 @@
<component id="StepsSkin" class="org.apache.royale.style.skins.StepsSkin"/>
<component id="StepSkin" class="org.apache.royale.style.skins.StepSkin"/>
<component id="IStepSkin" class="org.apache.royale.style.skins.IStepSkin"/>
+ <component id="ToastSkin" class="org.apache.royale.style.skins.ToastSkin"/>
</componentPackage>
diff --git
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/Application.as
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/Application.as
index 7fbb61f955..145cec936f 100644
---
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/Application.as
+++
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/Application.as
@@ -27,11 +27,19 @@ package org.apache.royale.style
public class Application extends org.apache.royale.core.Application
{
+ private static var _current:org.apache.royale.style.Application;
+ /**
+ * Global getter to get a reference to the top-level application
+ */
+ public static function get
current():org.apache.royale.style.Application{
+ return _current;
+ }
public function Application()
{
super();
valuesImpl = new AllCSSValuesImpl();
addBead(new ApplicationDataBinding());
+ _current = this;
ThemeManager.instance.registerTheme(new StyleTheme());
}
diff --git
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/StyleUIBase.as
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/StyleUIBase.as
index f0795c507c..56eaf4859f 100644
---
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/StyleUIBase.as
+++
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/StyleUIBase.as
@@ -115,7 +115,7 @@ package org.apache.royale.style
*
* Most components have four possible sizes, but specific
components may choose to support a different set of sizes as needed.
*/
- [Inspectable(category="General", enumeration="sm,md,lg,xl",
defaultValue="md")]
+ [Inspectable(category="General", enumeration="xs,sm,md,lg,xl",
defaultValue="md")]
public function get size():String
{
return _size;
diff --git
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/Toast.as
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/Toast.as
new file mode 100644
index 0000000000..853010e84b
--- /dev/null
+++ b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/Toast.as
@@ -0,0 +1,304 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package org.apache.royale.style
+{
+ import org.apache.royale.core.IHasLabel;
+ import org.apache.royale.core.IPopUpHost;
+ import org.apache.royale.debugging.assert;
+ import org.apache.royale.style.elements.Div;
+ import org.apache.royale.style.skins.IToastSkin;
+ import org.apache.royale.utils.Timer;
+ import org.apache.royale.events.Event;
+
+ COMPILE::SWF{
+ //compilation support only:
+ import flash.utils.setTimeout;
+ }
+
+ COMPILE::JS
+ {
+ import org.apache.royale.core.WrappedHTMLElement;
+ }
+
+ [Event(name="accept", type="org.apache.royale.events.Event")]
+ [Event(name="close", type="org.apache.royale.events.Event")]
+ public class Toast extends StyleUIBase implements IHasLabel
+ {
+
+
+ public function Toast(content:String = null, autoClose:uint=0)
+ {
+ super();
+ if(content){
+ label = content;
+ }
+ this.autoClose = autoClose;
+ }
+
+
+ public static const INFO:String = "info";
+ public static const NEGATIVE:String = "negative";
+ public static const POSITIVE:String = "positive";
+ public static const WARNING:String = "warning";
+ public static const SUCCESS:String = "success";
+
+
+ override public function addedToParent():void{
+ //This should not be added to anything other than an IPopUpHost.
+ //In particular, fx:Declarations nodes in Royale don't work as they
should for Visual components. They should not add to display, but they do.
+ super.addedToParent();
+ if (!(parent is IPopUpHost)) {
+ parent.removeElement(this)
+ }
+ }
+
+ private var _label:String = "";
+ public function get label():String
+ {
+ return _label;
+ }
+
+ public function set label(value:String):void
+ {
+ COMPILE::JS
+ {
+ if(_label != value){
+ _label = value;
+ _contentNode.text = value;
+ }
+ }
+ }
+
+ private var actionButton:IStyleUIBase;
+ private var _action:String;
+ public function get action():String
+ {
+ return _action;
+ }
+
+ public function set action(value:String):void
+ {
+ if (value != _action) {
+ _action = value;
+ updateActionButton();
+ }
+ }
+
+ private function updateActionButton():void{
+ if (actionButton) {
+ actionButton.removeEventListener("click",onAction);
+ body.removeElement(actionButton)
+ }
+ var toastSkin:IToastSkin = skin as IToastSkin;
+ if (_action && toastSkin) {
+ actionButton = toastSkin.getActionButton(_action);
+ actionButton.addEventListener("click",onAction);
+ body.addElement(actionButton)
+ }
+ }
+
+ private function onAction(ev:Event):void{
+ if(_shown){
+ dispatchEvent(new Event("accept"));
+ }
+ hide();
+ }
+
+ private var _flavorIcon:IStyleUIBase;
+ private var _flavor:String;
+ public function get flavor():String
+ {
+ return _flavor;
+ }
+
//"base","primary","secondary","accent","info","success","warning","error","neutral"
+ [Inspectable(category="General",
enumeration="info,success,positive,negative,warning")]
+ /**
+ * Set the flavor of the Toast
+ * One of info, success, positive and negative. warning also appears to be
an option
+ * To set the Toast to the default, specify an empty string
+ */
+ public function set flavor(value:String):void
+ {
+ if(value != _flavor){
+ switch(value){
+ case "info":
+ case "positive":
+ case "success":
+ case "negative":
+ case "error":
+ case "warning":
+ case "":
+ break;
+ default:
+ throw new Error("Unknown flavor: " + value);
+ }
+ _flavor = value;
+
+ if (skin) {
+ updateFlavorIcon();
+ }
+ }
+ }
+
+ private function updateFlavorIcon():void{
+ if (_flavorIcon) {
+ _body.removeElement(_flavorIcon);
+ }
+ var toastSkin:IToastSkin = skin as IToastSkin;
+ _flavorIcon = toastSkin.getIcon(_flavor);
+ if (_flavorIcon) {
+ _body.addElementAt(_flavorIcon,0);
+ }
+ }
+
+ private var timer:Timer;
+ public function show():void{
+ if(_shown){
+ return;
+ }
+ _shown = true;
+ toggleAttribute("data-hiding", false);
+ toggleAttribute("data-showing", true);
+ Application.current.popUpParent.addElement(this);
+ }
+
+ /**
+ * @private
+ * for use from skins when inbound animations are done
+ */
+ public function afterShow():void{
+ if(autoClose){
+ timer = new Timer(autoClose);
+ timer.addEventListener(Timer.TIMER,onTimer)
+ timer.start();
+ }
+ }
+
+ private function onTimer(ev:Event):void{
+ timer.removeEventListener(Timer.TIMER,onTimer);
+ hide();
+ }
+
+ private var _shown:Boolean;
+ public function hide():void{
+ if(!_shown){
+ return;
+ }
+ _shown = false;
+ toggleAttribute("data-showing", false);
+ toggleAttribute("data-hiding", true);
+ dispatchEvent(new Event("close"));
+ }
+
+ /**
+ * @private
+ * for use from skins when outbound animations are done
+ */
+ public function afterHide():void{
+ if (this.parent)
+ Application.current.popUpParent.removeElement(this);
+ toggleAttribute("data-showing", false);
+ toggleAttribute("data-hiding", false);
+ }
+
+ private var _autoClose:uint = 0;
+
+ /**
+ * Number of milliseconds the Toast will remain open.
+ * A value of 0 (default) will cause it to remain open until closed.
+ */
+ public function get autoClose():uint
+ {
+ return _autoClose;
+ }
+
+ public function set autoClose(value:uint):void
+ {
+ _autoClose = value;
+ }
+
+ private var _toast:Div;
+ /**
+ * The container node for all the visual content of the Toast message and
its controls
+ */
+ public function get toast():Div{
+ return _toast;
+ }
+ private var _body:Div;
+ /**
+ * The container node for the message with optional action UI control
+ */
+ public function get body():Div{
+ return _body;
+ }
+
+ private var _contentNode:Div;
+ /**
+ * The message content container - for label property to populate with
text content
+ */
+ public function get contentNode():Div{
+ return _contentNode;
+ }
+
+ private var _buttons:Div;
+ /**
+ * The button container for the toast controls (explicit close button)
+ */
+ public function get buttons():Div{
+ return _buttons;
+ }
+
+ COMPILE::JS
+ override protected function createElement():WrappedHTMLElement{
+ var elem:WrappedHTMLElement = super.createElement();
+ _toast = new Div();
+ _body = new Div();
+ _contentNode = new Div();
+ _body.addElement(_contentNode);
+ _toast.addElement(_body)
+ _buttons = new Div();
+ _toast.addElement(_buttons);
+ elem.appendChild(toast.element);
+ return elem;
+ }
+
+ override protected function applySkin():void{
+ var toastSkin:IToastSkin = skin as IToastSkin;
+ assert(toastSkin is IToastSkin, "Toast requires a skin that implements
IToastSkin");
+ var styles:Array = toastSkin.toastContentStyles || [];
+ _toast.setStyles(styles, true);
+ styles = toastSkin.textLayoutStyles || [];
+ _contentNode.setStyles(styles,true);
+ styles = toastSkin.toastBodyStyles || [];
+ _body.setStyles(styles,true);
+ updateFlavorIcon();
+ if (_action && !actionButton) {
+ updateActionButton()
+ }
+ styles = toastSkin.buttonsLayoutStyles || [];
+ _buttons.setStyles(styles,true);
+ if (!_buttons.numElements) {
+ var button:IStyleUIBase = toastSkin.getCloseButton()
+ button.addEventListener("click",hide);
+ _buttons.addElement(button);
+ }
+ }
+
+ }
+}
\ No newline at end of file
diff --git
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/colors/CSSColor.as
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/colors/CSSColor.as
index 0698f3af04..cc0a8d08c8 100644
---
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/colors/CSSColor.as
+++
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/colors/CSSColor.as
@@ -51,374 +51,5 @@ package org.apache.royale.style.colors
return "";
}
- /**
- * Returns an RGB array on a white -> base -> black ramp.
- * 0 is white, 50 is the input color, 100 is black.
- */
- public static function getVariation(color:uint,
grayValue:Number, darkMode:Boolean = false):Array
- {
- var r:Number = (color >> 16) & 0xFF;
- var g:Number = (color >> 8) & 0xFF;
- var b:Number = color & 0xFF;
-
- //convert to 0 - 1000 range
- var t:Number = pinValue(grayValue, 0, 100) * 10;
-
- //pass through lch color space for shading
- var lch:Array = rgb_ToOKLCH([r,g,b]);
- //shade it
- lch =
lchShade(lch,factorForShadeTableInterpolated(t,darkMode));
- return oklch_ToRGB(lch);
-
- /*var outR:Number;
- var outG:Number;
- var outB:Number;
-
- if (t <= 50)
- {
- var toBase:Number = t / 50;
- outR = 255 + (r - 255) * toBase;
- outG = 255 + (g - 255) * toBase;
- outB = 255 + (b - 255) * toBase;
- }
- else
- {
- var toBlack:Number = (t - 50) / 50;
- outR = r * (1 - toBlack);
- outG = g * (1 - toBlack);
- outB = b * (1 - toBlack);
- }
-
- return [Math.round(outR), Math.round(outG),
Math.round(outB)];*/
- }
-
- /**
- * Convenience helper for callers that have separate channel
values.
- */
- public static function getVariationRGB(r:Number, g:Number,
b:Number, grayValue:Number):Array
- {
- var rr:uint = uint(pinValue(r, 0, 255));
- var gg:uint = uint(pinValue(g, 0, 255));
- var bb:uint = uint(pinValue(b, 0, 255));
- var color:uint = (rr << 16) | (gg << 8) | bb;
- return getVariation(color, grayValue);
- }
-
- /**
- * convert rgb to oklch format
- * @param rgb Array of rgb values in 3 element array
- * @return array of lch values
- */
- public static function rgb_ToOKLCH(rgb:Array):Array {
- var r:uint = rgb[0];
- var g:uint = rgb[1];
- var b:uint = rgb[2];
- //Math.cbrt;
- const cube_root:Function = Math['cbrt'] as Function;
//not yet in Royale js typedefs
- // Normalize
- var R:Number = r / 255;
- var G:Number = g / 255;
- var B:Number = b / 255;
-
- // Convert to linear
- R = srgbToLinear(R);
- G = srgbToLinear(G);
- B = srgbToLinear(B);
-
- // Convert to OKLab
- var l:Number = 0.4122214708 * R + 0.5363325363 * G +
0.0514459929 * B;
- var m:Number = 0.2119034982 * R + 0.6806995451 * G +
0.1073969566 * B;
- var s:Number = 0.0883024619 * R + 0.2817188376 * G +
0.6299787005 * B;
-
- var l_:Number = cube_root(l);
- var m_2:Number = cube_root(m);
- var s_2:Number = cube_root(s);
-
- var L:Number = 0.2104542553 * l_ + 0.7936177850 * m_2 -
0.0040720468 * s_2;
- var a:Number = 1.9779984951 * l_ - 2.4285922050 * m_2 +
0.4505937099 * s_2;
- var b2:Number = 0.0259040371 * l_ + 0.7827717662 * m_2
- 0.8086757660 * s_2;
-
- var C:Number = Math.sqrt(a * a + b2 * b2);
- var H:Number = (Math.atan2(b2, a) * 180 / Math.PI +
360) % 360;
-
- return [L, C, H];
- }
-
- /**
- * convert from lch to rgb
- * @param lch lch values in 3 element array
- * @return rgb values in 3 element array
- */
- public static function oklch_ToRGB(lch:Array):Array {
-
- // --- 1. OKLCH → OKLab ---
- const L:Number = lch[0];
- const C:Number = lch[1];
- const hRad:Number = lch[2] * Math.PI / 180.0;
-
- const a_:Number = C * Math.cos(hRad);
- const b_:Number = C * Math.sin(hRad);
-
- // --- 2. OKLab → LMS (non-linear) ---
- const l_:Number = L + 0.3963377774 * a_ + 0.2158037573
* b_;
- const m_:Number = L - 0.1055613458 * a_ - 0.0638541728
* b_;
- const s_:Number = L - 0.0894841775 * a_ - 1.2914855480
* b_;
-
- // cube them (inverse of cbrt)
- const l:Number = l_ * l_ * l_;
- const m:Number = m_ * m_ * m_;
- const s:Number = s_ * s_ * s_;
-
- // --- 3. LMS → linear RGB ---
- var rLin:Number =
- + 4.0767416621 * l
- - 3.3077115913 * m
- + 0.2309699292 * s;
-
- var gLin:Number =
- - 1.2684380046 * l
- + 2.6097574011 * m
- - 0.3413193965 * s;
-
- var bLin:Number =
- - 0.0041960863 * l
- - 0.7034186147 * m
- + 1.7076147010 * s;
-
- // --- 4. linear RGB → sRGB clamped ---
- var r:uint = uint(pinValue(linearToSrgb(rLin),0,1) *
255);
- var g:uint = uint(pinValue(linearToSrgb(gLin),0,1) *
255);
- var b:uint = uint(pinValue(linearToSrgb(bLin),0,1) *
255);
-
- return [r ,g ,b];
- }
-
- private static function srgbToLinear(x:Number):Number {
- return (x <= 0.04045) ? x / 12.92 : Math.pow((x +
0.055) / 1.055, 2.4);
- }
-
- private static function linearToSrgb(x:Number):Number {
- return (x <= 0.0031308) ? 12.92 * x : 1.055 *
Math.pow(x, 1.0 / 2.4) - 0.055;
- }
-
- /*private static function lerp(a:Number, b:Number,
t:Number):Number {
- return a + (b - a) * t;
- }*/
-
- public static function lchShade(base:Array, factor:Number):Array
- {
- const baseL:Number = base[0];
- const baseC:Number = base[1];
- const baseH:Number = base[2];
-
- // Your table ranges roughly 0.45–1.60.
- // factor > 1 → lighter than base
- // factor < 1 → darker than base
-
- var newL:Number;
- var newC:Number;
-
- if (factor >= 1.0) {
- // LIGHTER SIDE (50–400)
- // Normalize factor so:
- // factor = 1.0 → t = 0 (base)
- // factor = 1.6 → t = 1 (lightest)
- var tLight:Number = (factor - 1.0) / (1.6 -
1.0);
- if (tLight < 0) tLight = 0;
- if (tLight > 1) tLight = 1;
-
- // Move L toward a very light target (~0.97)
- newL = baseL + (0.97 - baseL) * tLight;
-
- // Reduce chroma as we get lighter
- // t = 0 → baseC
- // t = 1 → ~30% of baseC
- newC = baseC * (1.0 - 0.7 * tLight);
- } else {
- // DARKER SIDE (600–900)
- // Normalize factor so:
- // factor = 1.0 → t = 0 (base)
- // factor = 0.45 → t = 1 (darkest)
- var tDark:Number = (1.0 - factor) / (1.0 -
0.45);
- if (tDark < 0) tDark = 0;
- if (tDark > 1) tDark = 1;
-
- // Move L toward a dark target (~0.12)
- newL = baseL + (0.12 - baseL) * tDark;
-
- // Slightly increase chroma as we get darker
- // t = 0 → baseC
- // t = 1 → ~120% of baseC
- newC = baseC * (1.0 + 0.2 * tDark);
- }
-
- return [
- pinValue(newL, 0, 1),
- pinValue(newC, 0, 0.4),
- baseH
- ];
- }
-
- private static const shading_factors:Object = {
- 50: 1.80,
- 100: 1.60,
- 200: 1.40,
- 300: 1.20,
- 400: 1.08,
- 500: 1.00,
- 600: 0.90,
- 700: 0.75,
- 800: 0.60,
- 900: 0.45
- }
-
- private static var inverted_factors:Object;
-
- private static const SHADE_KEYS:Array = [];
- private static const INVERTED_SHADE_KEYS:Array = [];
-
- COMPILE::JS
- private static const lookups:Map = new Map();
- COMPILE::SWF
- private static const lookups:Object = {};
-
- private static function
factorForShadeTableInterpolated(shade:uint, darkMode:Boolean):Number {
- assert(shade>=0 && shade<=1000, 'bad parameter')
- if (darkMode && !inverted_factors) {
- inverted_factors = invertTable(shading_factors);
- trace('inverted', inverted_factors);
- }
- const factors:Object = darkMode ? inverted_factors :
shading_factors;
- const shadeKeys:Array = darkMode ?
CSSColor.INVERTED_SHADE_KEYS : CSSColor.SHADE_KEYS;
- if (!shadeKeys.length) {
- //populate it first time
- COMPILE::JS{
- var keys:Array =
Object.keys(factors).map(function(k:String):int { return uint(k); });
- }
- COMPILE::SWF{
- var keys:Array = [];
- for (var key:String in factors)
keys.push(key);
- keys = keys.map(function(k:String):int
{ return uint(k); });
- }
-
- keys.sort(Array.NUMERIC);
- shadeKeys.push.apply(shadeKeys, keys);
- }
-
- // clamp to valid range
- if (shade <= 50) return factors[50];
- if (shade >= 900) return factors[900];
-
- // exact match
- if (factors[shade] != null)
- return factors[shade];
-
- var resultMap:Object;
- var result:Number;
- COMPILE::JS {
- resultMap = lookups.get(shade);
- if (!resultMap) {
- resultMap = { dark:NaN,light:NaN};
- lookups.set(shade, resultMap);
- }
- }
- COMPILE::SWF {
- resultMap = lookups[shade];
- if (!resultMap) {
- resultMap = { dark:NaN,light:NaN};
- lookups[shade] = resultMap;
- }
- }
- result = darkMode ? resultMap.dark : resultMap.light;
- if (isNaN(result)) {
- // find neighbors
- var lower:int = 50;
- var upper:int = 900;
-
- for (var i:int = 0; i < shadeKeys.length - 1;
i++) {
- var a:int = shadeKeys[i];
- var b:int = shadeKeys[i+1];
-
- if (shade > a && shade < b) {
- lower = a;
- upper = b;
- break;
- }
- }
-
- var f1:Number = factors[lower];
- var f2:Number = factors[upper];
-
- var t:Number = (shade - lower) / (upper -
lower);
- result = f1 + t * (f2 - f1);
-
- if (darkMode) {
- resultMap.dark = result;
- } else {
- resultMap.light = result;
- }
- }
- return result;
- }
-
-
- private static function invertTable(table:Object):Object {
- COMPILE::JS{
- const keys:Array =
Object.keys(table).sort(Array.NUMERIC);
- }
- COMPILE::SWF{
- var keys:Array = [];
- for (var key:String in table) keys.push(key);
- keys = keys.sort(Array.NUMERIC);
- }
-
- const values:Array =
keys.map(function(key:String):Number{return table[key]}).reverse();
-
- const inverted:Object = {};
- for (var i:int = 0; i < keys.length; i++) {
- inverted[keys[i]] = values[i];
- }
- return inverted;
- }
-
-
- /*public static function testRoundTrip():void {
-
- const tests:Array = [
- 0x000000, 0xFFFFFF,
- 0xFF0000, 0x00FF00, 0x0000FF,
- 0xFFFF00, 0xFF00FF, 0x00FFFF,
- 0x808080, 0xC0C0C0, 0x404040
- ];
-
- // add random colors
- for (var i:int = 0; i < 20; i++) {
- tests.push(Math.random() * 0xFFFFFF);
- }
-
- for each (var rgb:uint in tests) {
- var r1:uint = (rgb >> 16) & 0xFF;
- var g1:uint = (rgb >> 8) & 0xFF;
- var b1:uint = rgb & 0xFF;
- var oklch:Array = rgbToOKLCH([r1,g1,b1]);
- var rgb2:Array = oklchToRGB(oklch);
-
- var r2:uint = rgb2[0];
- var g2:uint = rgb2[1];
- var b2:uint = rgb2[2];
-
- var rgbOut:uint = r2<<16 | g2<<8 | b2;
-
- var dr:int = r2 - r1;
- var dg:int = g2 - g1;
- var db:int = b2 - b1;
-
- trace(
- "RGB:", rgb.toString(16),
- "→", rgbOut.toString(16),
- "Δ:", dr, dg, db
- );
- }
- }*/
}
}
\ No newline at end of file
diff --git
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/colors/ColorSwatch.as
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/colors/ColorSwatch.as
index 75581ad554..111a876f28 100644
---
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/colors/ColorSwatch.as
+++
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/colors/ColorSwatch.as
@@ -83,6 +83,51 @@ package org.apache.royale.style.colors
"zinc": 0x71717B
};
+ private static const lchLookups:Object = {init:false};
+ private static function getLCHLookups():Object{
+ if (lchLookups.init === false) {
+ delete lchLookups.init;
+ for (var key:String in BASE_COLORS) {
+ var col:uint = BASE_COLORS[key];
+ lchLookups[key] =
ColorUtils.rgb_ToOKLCH([(col>>16)&0xff,(col>>8)&0xff,col&0xff])
+ }
+ //add white and black
+
+
+ }
+ return lchLookups;
+ }
+
+ public static function estimateFromRGB(rgb:Array,
customOklchLookups:Object = null):ColorSwatch{
+ var BASE_COLORS_OKLCH:Object = customOklchLookups ||
getLCHLookups();
+ var bestName:String = null;
+ var inputAsOKLCH:Array = ColorUtils.rgb_ToOKLCH(rgb);
+ var bestDist:Number = Number.MAX_VALUE;
+ for (var name:String in BASE_COLORS_OKLCH) {
+ var ref:Array = BASE_COLORS_OKLCH[name];
+ var d:Number =
ColorUtils.oklchDistance(inputAsOKLCH, ref);
+ if (d < bestDist) {
+ bestDist = d;
+ bestName = name;
+ }
+ }
+ var base:Array = BASE_COLORS_OKLCH[bestName];
+ var ramp:Object = ColorUtils.getOklchRamp(base);
+ var bestShade:uint = 500;
+ bestDist = Number.MAX_VALUE;
+ for (var shadeKey:String in ramp) {
+ ref = ramp[shadeKey];
+ d = ColorUtils.oklchDistance(inputAsOKLCH, ref);
+ if (d < bestDist)
+ {
+ bestDist = d;
+ bestShade = uint(shadeKey);
+ }
+ }
+ return new ColorSwatch(bestName,bestShade);
+ }
+
+
private static const exceptions:Array = [
"transparent",
"currentColor",
@@ -103,7 +148,7 @@ package org.apache.royale.style.colors
var baseColor:uint = CSSUtils.toColor(base);
// Convert from 50,100,200... to 5,10,20... for easier
math.
// shade = Math.round(shade/10);
- rgb =
CSSColor.getVariation(baseColor,Math.round(shade/10),darkMode);
+ rgb =
ColorUtils.getVariation(baseColor,Math.round(shade/10),darkMode);
assert(opacity >= 0 && opacity <= 100, "Opacity must be
between 0 and 100");
colorBase = swatch;
colorShade = shade;
@@ -127,14 +172,17 @@ package org.apache.royale.style.colors
public var dark:Boolean;
/**
- * create a ColorSwatch variant from this instance
- * @param alternateShade - alternate shade. If you want to keep
the same shade and adjust opacity, set this to NaN
- * @param alternateOpacity - if not set it will inherit the
original value from this instance
- * @return a new ColorSwatch with different shade or opacity
(or both)
- */
- public function getVariant(alternateShade:Number,
alternateOpacity:Number = NaN):ColorSwatch{
+ * create a ColorSwatch variant from this instance
+ * @param alternateShade - alternate shade. If you want to keep the
same shade and adjust opacity, set this to NaN
+ * @param alternateOpacity - if not set it will inherit the original
value from this instance
+ * @param applyDelta if true, the alternate values will be applied as
deltas to existing values to create the variant
+ * @return a new ColorSwatch with different shade or opacity (or both)
+ */
+ public function getVariant(alternateShade:Number,
alternateOpacity:Number = NaN, applyDelta:Boolean = false):ColorSwatch{
if (isNaN(alternateShade)) alternateShade = colorShade;
+ else if (applyDelta) alternateShade = colorShade +
alternateShade;
if (isNaN(alternateOpacity)) alternateOpacity =
colorOpacity;
+ else if (applyDelta) alternateOpacity = colorOpacity +
alternateOpacity;
var alternate:ColorSwatch = new
ColorSwatch(colorBase,alternateShade,alternateOpacity,dark);
assert(alternate.colorShade != colorShade ||
alternate.colorOpacity != colorOpacity, "parameters not configured to create a
variant");
return alternate;
@@ -160,7 +208,7 @@ package org.apache.royale.style.colors
return name in BASE_COLORS;
}
- public static function getColorValue(name:String):Boolean{
+ public static function getColorValue(name:String):uint{
return BASE_COLORS[name];
}
diff --git
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/colors/CSSColor.as
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/colors/ColorUtils.as
similarity index 62%
copy from
frameworks/projects/Style/src/main/royale/org/apache/royale/style/colors/CSSColor.as
copy to
frameworks/projects/Style/src/main/royale/org/apache/royale/style/colors/ColorUtils.as
index 0698f3af04..057393c547 100644
---
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/colors/CSSColor.as
+++
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/colors/ColorUtils.as
@@ -19,41 +19,26 @@
package org.apache.royale.style.colors
{
import org.apache.royale.debugging.assert;
- import org.apache.royale.style.colors.CSSColor;
import org.apache.royale.utils.number.pinValue;
- public class CSSColor
+ public class ColorUtils
{
- private function CSSColor()
+ private function ColorUtils()
{
}
- public static function getColor(values:Array, opacity:Number =
100, space:String = "rgb"):String{
- assert(values && values.length == 3, "invalid color
values");
- var withAlpha:Boolean = opacity < 100;
- var alphaString:String = opacity + "%";
- var channels:String = values.join(" ");
-
- switch (space)
- {
- case "rgb":
- case "hsl":
- case "hwb":
- case "lab":
- case "lch":
- case "oklab":
- case "oklch":
- return withAlpha ? space + "(" +
channels + " / " + alphaString + ")" : space + "(" + channels + ")";
- default:
- assert(false, "Unsupported color space:
" + space);
- break;
- }
- return "";
- }
-
+
/**
- * Returns an RGB array on a white -> base -> black ramp.
- * 0 is white, 50 is the input color, 100 is black.
+ * Returns an RGB array representing a perceptually-balanced
variation of the input color.
+ * Uses OKLCH color space to maintain consistent hue and
saturation across different lightness levels.
+ *
+ * @param color The base color as a uint (0xRRGGBB).
+ * @param grayValue A value from 0 to 100.
+ * Values < 50 transition toward a high-lightness
aesthetic target (~97% lightness).
+ * Value of 50 returns the input color (base).
+ * Values > 50 transition toward a low-lightness
aesthetic target (~12% lightness).
+ * @param darkMode If true, inverts the shading scale to
optimize the color for dark theme contexts.
+ * @return An Array of [R, G, B] values (0-255).
*/
public static function getVariation(color:uint,
grayValue:Number, darkMode:Boolean = false):Array
{
@@ -95,7 +80,7 @@ package org.apache.royale.style.colors
/**
* Convenience helper for callers that have separate channel
values.
*/
- public static function getVariationRGB(r:Number, g:Number,
b:Number, grayValue:Number):Array
+ public static function getVariationRGB(r:Number, g:Number,
b:Number, grayValue:Number, darkMode:Boolean = false):Array
{
var rr:uint = uint(pinValue(r, 0, 255));
var gg:uint = uint(pinValue(g, 0, 255));
@@ -272,6 +257,59 @@ package org.apache.royale.style.colors
900: 0.45
}
+ public static function getOklchRamp(base:Array):Object{
+ var ramp:Object = {};
+ for (var shade:String in shading_factors)
+ {
+ var m:Number = shading_factors[shade];
+
+ // Lightness scaling
+ var L:Number = base[0] * m;
+
+ // Chroma scaling (slightly reduced for darker
shades)
+ var C:Number = base[1] * (m < 1 ? m : 1);
+
+ // Hue stays constant
+ var H:Number = base[2];
+
+ ramp[shade] = [L,C,H];
+ }
+ return ramp;
+ }
+
+ public static function oklchDistance(a:Array, b:Array):Number
+ {
+ // Hue difference with wrap-around
+ var dh:Number = Math.abs(a[2] - b[2]);
+ if (dh > 180) dh = 360 - dh;
+
+ var dL:Number = a[0] - b[0];
+ var dC:Number = a[1] - b[1];
+
+ return Math.sqrt(dL*dL + dC*dC + dh*dh);
+ }
+
+ public static function flattenRGBAOverBackground(fg_rgb:Array,
alpha:Number, bg_rgb:Array = null):Array
+ {
+ assert(alpha>=0 && alpha<=1,'alpha out of range');
+ // Foreground
+ var rF:uint = fg_rgb[0] & 0xff;
+ var gF:uint = fg_rgb[1] & 0xff;
+ var bF:uint = fg_rgb[2] & 0xff;
+
+ // Background
+ var rB:uint = bg_rgb ? bg_rgb[0] & 0xff : 0xFF;
+ var gB:uint = bg_rgb ? bg_rgb[1] & 0xff : 0xFF;
+ var bB:uint = bg_rgb ? bg_rgb[2] & 0xff : 0xFF;
+
+ // Composite
+ var r:uint = rF * alpha + rB * (1 - alpha);
+ var g:uint = gF * alpha + gB * (1 - alpha);
+ var b:uint = bF * alpha + bB * (1 - alpha);
+
+ return [r,g,b]
+ }
+
private static var inverted_factors:Object;
private static const SHADE_KEYS:Array = [];
@@ -289,7 +327,7 @@ package org.apache.royale.style.colors
trace('inverted', inverted_factors);
}
const factors:Object = darkMode ? inverted_factors :
shading_factors;
- const shadeKeys:Array = darkMode ?
CSSColor.INVERTED_SHADE_KEYS : CSSColor.SHADE_KEYS;
+ const shadeKeys:Array = darkMode ?
ColorUtils.INVERTED_SHADE_KEYS : ColorUtils.SHADE_KEYS;
if (!shadeKeys.length) {
//populate it first time
COMPILE::JS{
@@ -400,8 +438,8 @@ package org.apache.royale.style.colors
var r1:uint = (rgb >> 16) & 0xFF;
var g1:uint = (rgb >> 8) & 0xFF;
var b1:uint = rgb & 0xFF;
- var oklch:Array = rgbToOKLCH([r1,g1,b1]);
- var rgb2:Array = oklchToRGB(oklch);
+ var oklch:Array = rgb_ToOKLCH([r1,g1,b1]);
+ var rgb2:Array = oklch_ToRGB(oklch);
var r2:uint = rgb2[0];
var g2:uint = rgb2[1];
@@ -420,5 +458,154 @@ package org.apache.royale.style.colors
);
}
}*/
+
+ /**
+ * Compute WCAG relative luminance from sRGB (0–255)
+ */
+ private static function relativeLuminance(rgb:Array):Number {
+ function chan(v:Number):Number {
+ v /= 255.0;
+ return (v <= 0.04045) ? (v / 12.92) :
Math.pow((v + 0.055) / 1.055, 2.4);
+ }
+ var r:Number = chan(rgb[0]);
+ var g:Number = chan(rgb[1]);
+ var b:Number = chan(rgb[2]);
+ return 0.2126 * r + 0.7152 * g + 0.0722 * b;
+ }
+
+ /**
+ * WCAG contrast ratio between two RGB colors
+ */
+ public static function contrast(a:Array, b:Array):Number {
+ var L1:Number = relativeLuminance(a);
+ var L2:Number = relativeLuminance(b);
+ var lighter:Number = Math.max(L1, L2);
+ var darker:Number = Math.min(L1, L2);
+ return (lighter + 0.05) / (darker + 0.05);
+ }
+
+ /**
+ * Generate a WCAG‑compliant contrast color in OKLCH by:
+ * 1. Binary‑searching lightness (L) to find the minimum value
that meets contrast.
+ * 2. Binary‑searching chroma (C) to find the maximum valid
chroma at that L.
+ *
+ * The resulting color preserves the hue of the input color and
retains as much
+ * chroma as possible, producing a contrast color that remains
visually related
+ * to the original color rather than collapsing to grayscale.
+ */
+ public static function generateContrastLCH(bgLch:Array,
wantLight:Boolean):Array {
+ var L:Number = bgLch[0];
+ var C:Number = bgLch[1];
+ var h:Number = bgLch[2];
+
+ var bgRgb:Array = oklch_ToRGB(bgLch);
+
+ // -----------------------------
+ // 1. BINARY SEARCH FOR LIGHTNESS
+ // -----------------------------
+ var low:Number;
+ var high:Number;
+
+ if (wantLight) {
+ low = L;
+ high = 1.0;
+ } else {
+ low = 0.0;
+ high = L;
+ }
+
+ var mid:Number;
+ var safeC:Number;
+ var test:Array;
+ var rgb:Array;
+
+ // 20 iterations = sub‑pixel precision
+ for (var i:int = 0; i < 20; i++) {
+ mid = (low + high) * 0.5;
+
+ // Stability chroma curve (prevents invalid
OKLCH at extremes)
+ safeC = C * (1 - Math.abs(mid - 0.5) * 2);
+ safeC = pinValue(safeC, 0, C);
+
+ test = [mid, safeC, h];
+ rgb = oklch_ToRGB(test);
+
+ var cr:Number = contrast(rgb, bgRgb);
+
+ if (cr >= 4.5) {
+ if (wantLight) high = mid;
+ else low = mid;
+ } else {
+ if (wantLight) low = mid;
+ else high = mid;
+ }
+ }
+
+ var L_final:Number = mid;
+
+ // -----------------------------
+ // 2. BINARY SEARCH FOR CHROMA
+ // -----------------------------
+ var cLow:Number = 0.0;
+ var cHigh:Number = C;
+ var cMid:Number;
+ var bestC:Number = 0.0;
+
+ for (i = 0; i < 20; i++) {
+ cMid = (cLow + cHigh) * 0.5;
+
+ // Candidate with this chroma
+ test = [L_final, cMid, h];
+ rgb = oklch_ToRGB(test);
+
+ // Check if round‑trip OKLCH is valid
+ var rt:Array = rgb_ToOKLCH(rgb);
+ var valid:Boolean = Math.abs(rt[0] - L_final) <
0.02; // lightness must survive round‑trip
+
+ // Check contrast
+ var cr2:Number = contrast(rgb, bgRgb);
+
+ if (valid && cr2 >= 4.5) {
+ bestC = cMid; // keep this chroma
+ cLow = cMid; // try for more
+ } else {
+ cHigh = cMid; // too much chroma →
reduce
+ }
+ }
+
+ // Final brand‑safe contrast color
+ return [L_final, bestC, h];
+ }
+
+ /**
+ * Given an RGB background, return a strong‑contrast RGB
foreground.
+ */
+ public static function chooseContrastRGB(bgRgb:Array):Array {
+
+ // Predefined white/black
+ const WHITE:Array = [255, 255, 255];
+ const BLACK:Array = [0, 0, 0];
+
+ var cWhite:Number = contrast(bgRgb, WHITE);
+ var cBlack:Number = contrast(bgRgb, BLACK);
+
+ // Fast path: if either passes WCAG AA, choose the
stronger
+ var whitePass:Boolean = (cWhite >= 4.5);
+ var blackPass:Boolean = (cBlack >= 4.5);
+
+ if (whitePass || blackPass) {
+ return (cWhite > cBlack) ? WHITE : BLACK;
+ }
+
+ // Slow path: generate a corrected OKLCH foreground
+ var bgLch:Array = rgb_ToOKLCH(bgRgb);
+ var L:Number = bgLch[0];
+
+ // If background is light, generate dark text; if dark,
generate light text
+ var wantLight:Boolean = (L < 0.6);
+
+ var correctedLch:Array = generateContrastLCH(bgLch,
wantLight);
+ return oklch_ToRGB(correctedLch);
+ }
}
}
\ No newline at end of file
diff --git
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/colors/ThemeColorSet.as
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/colors/ThemeColorSet.as
index 76480f9496..1a7740e8d3 100644
---
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/colors/ThemeColorSet.as
+++
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/colors/ThemeColorSet.as
@@ -20,7 +20,6 @@ package org.apache.royale.style.colors
{
import org.apache.royale.style.util.CSSLookup;
import org.apache.royale.utils.CSSUtils;
-
import org.apache.royale.debugging.assert;
public class ThemeColorSet
@@ -56,6 +55,22 @@ package org.apache.royale.style.colors
COMPILE::JS
private const storage:Map = new Map();
+
+ private const lchLookups:Object = {init:false};
+ private function getLCHLookups():Object{
+ if (lchLookups.init === false) {
+ delete lchLookups.init;
+ var key:String;
+ for each(key in _fieldNames) {
+ var baseColor:String =
getThemeBaseColor(key);
+ if (baseColor) {
+ var col:uint
=ColorSwatch.getColorValue(baseColor);
+ lchLookups[baseColor] =
ColorUtils.rgb_ToOKLCH([(col>>16)&0xff,(col>>8)&0xff,col&0xff])
+ }
+ }
+ }
+ return lchLookups;
+ }
/**
* Subclasses must specify colorBase before calling this
constructor.
@@ -146,54 +161,65 @@ package org.apache.royale.style.colors
}
public function
getContrastSwatch(original:ColorSwatch):ColorSwatch{
- var swatch:String = original.colorBase;
- var shade:Number = original.colorShade;
- var opacity:Number = original.colorOpacity;
- var dark:Boolean = original.dark;
- var nameVariant:String = swatch+'-contrast';
- if (!CSSLookup.has(nameVariant)) {
-
registerContrastVariant(nameVariant,swatch,shade,dark,false);
+ var result:ColorSwatch =
findContrastVariant(original.colorBase,original.colorShade,original.dark,false,
true);
+ if (original.colorOpacity != 100) {
+ result =
result.getVariant(NaN,original.colorOpacity);
}
- return new ColorSwatch(nameVariant,500,opacity,dark);
+ return result
}
public function
getWeakContrastSwatch(original:ColorSwatch):ColorSwatch{
- var swatch:String = original.colorBase;
- var shade:Number = original.colorShade;
- var opacity:Number = original.colorOpacity;
- var dark:Boolean = original.dark;
- var nameVariant:String = swatch+'-contrast-weak';
- if (!CSSLookup.has(nameVariant)) {
-
registerContrastVariant(nameVariant,swatch,shade,dark,true);
+ var result:ColorSwatch =
findContrastVariant(original.colorBase,original.colorShade,original.dark,true,
true);
+ if (original.colorOpacity != 100) {
+ result =
result.getVariant(NaN,original.colorOpacity);
}
- return new ColorSwatch(nameVariant,500,opacity,dark);
+ return result;
}
- private static function
registerContrastVariant(nameVariant:String, swatch:String,
shade:Number,dark:Boolean, weak:Boolean):void{
+ private var contrastLookupSpecifiers:Object = {};
+
+ /**
+ * Finds a contrast variant ColorSwatch based on the pararmeters
passed in
+ * @param swatch the name of a color swatch (can be outside this set)
+ * @param shade the shade 50 - 900
+ * @param dark tbd
+ * @param weak if true then a weak contrast is returned, otherwise a
strong contrast
+ * @param limitRange if true then limit lookups to this color set only
+ * @return
+ */
+ public function findContrastVariant(swatch:String,
shade:Number,dark:Boolean, weak:Boolean, limitRange:Boolean=false):ColorSwatch{
+ const lookupKey:String =
swatch+'$$'+shade+'$$'+dark+'$$'+weak+'$$';
+
+ var existing:String =
contrastLookupSpecifiers[lookupKey];
+ if (existing) {
+
+ return ColorSwatch.fromSpecifier(existing);
+ }
var base:Object = ColorSwatch.getColorValue(swatch) ||
CSSLookup.getProperty(swatch);
var baseColor:uint = CSSUtils.toColor(base);
- // Convert from 50,100,200... to 5,10,20... for easier
math.
shade = Math.round(shade/10);
- var colorVals:Array =
CSSColor.getVariation(baseColor,shade,dark);
- var oklch:Array = CSSColor.rgb_ToOKLCH(colorVals);
- var L:Number = oklch[0];
- var H:Number = oklch[2];
- var fg:Array;
+ var colorVals:Array =
ColorUtils.getVariation(baseColor,shade,dark);
+ var bgLch:Array = ColorUtils.rgb_ToOKLCH(colorVals);
+ var L:Number = bgLch[0];
+
+ // var wantLight:Boolean =
(ColorUtils.contrast([255,255,255], colorVals) < ColorUtils.contrast([0,0,0],
colorVals));
+ var wantLight:Boolean = (L < .62);
+ // Strong or weak contrast?
+ var targetLch:Array =
ColorUtils.generateContrastLCH(bgLch, wantLight);
if (weak) {
- if (L < 0.55)
- fg = [0.80, 0.01, H]; // weak light
- else
- fg = [0.35, 0.02, H]; // weak dark
- } else {
- if (L < 0.55)
- fg = [0.97, 0.02, H]; // light contrast
- else
- fg = [0.18, 0.03, H]; // dark contrast
+ // Weak contrast = reduce chroma + move L
slightly toward bg
+ targetLch[1] *= 0.4; // reduce chroma
+ targetLch[0] = (targetLch[0] + L) * 0.5; //
blend toward background
}
- colorVals = CSSColor.oklch_ToRGB(fg);
-
CSSLookup.register(nameVariant,'rgb('+colorVals.join(',')+')');
+ var fg:Array = targetLch;
+ colorVals = ColorUtils.oklch_ToRGB(fg);
+ var lookups:Object = limitRange ? getLCHLookups() :
null;
+ var ret:ColorSwatch =
ColorSwatch.estimateFromRGB(colorVals,lookups);
+ contrastLookupSpecifiers[lookupKey] = ret.toString()
+
+ return ret;
}
public function fromJSON(obj:Object):void{
diff --git
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/elements/Textarea.as
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/elements/Textarea.as
index 339e8c7e1e..88c63240f2 100644
---
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/elements/Textarea.as
+++
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/elements/Textarea.as
@@ -215,6 +215,88 @@ package org.apache.royale.style.elements
textarea.value = value;
}
}
+
+ public function get readonly():Boolean
+ {
+ COMPILE::JS
+ {
+ return textarea.readOnly;
+ }
+ COMPILE::SWF
+ {
+ return false
+ }
+ }
+
+ public function set readonly(value:Boolean):void
+ {
+ COMPILE::JS
+ {
+ textarea.readOnly = value;
+ }
+ }
+
+ public function get placeholder():String
+ {
+ COMPILE::JS
+ {
+ return textarea.placeholder;
+ }
+ COMPILE::SWF
+ {
+ return null
+ }
+ }
+
+ public function set placeholder(value:String):void
+ {
+ COMPILE::JS
+ {
+ //set the content in the textArea
+ textarea.placeholder = value;
+ }
+ }
+
+ private var _required:Boolean;
+
+ public function get required():Boolean
+ {
+ return _required;
+ }
+
+ public function set required(value:Boolean):void
+ {
+ if(value != !!_required){
+ toggleAttribute('required',value);
+ }
+ _required = value;
+ }
+
+ private var _invalid:Boolean;
+ /**
+ * Indicates whether the current state of the component is
invalid.
+ * This can be used to apply error styles to the component.
+ *
+ * The Checkbox skin should specify invalid styles if desired.
+ *
+ * @languageversion 3.0
+ * @productversion Royale 1.0.0
+ */
+ public function get invalid():Boolean
+ {
+ return _invalid;
+ }
+
+ public function set invalid(value:Boolean):void
+ {
+ COMPILE::JS
+ {
+ if(value != !!_invalid){
+ toggleAttribute("data-invalid", value);
+ }
+ }
+ _invalid = value;
+ }
override protected function getTag():String
{
diff --git
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/skins/CheckBoxSkin.as
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/skins/CheckBoxSkin.as
index a918878211..514c1be7dd 100644
---
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/skins/CheckBoxSkin.as
+++
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/skins/CheckBoxSkin.as
@@ -281,8 +281,9 @@ package org.apache.royale.style.skins
var colorSet:ThemeColorSet =
ThemeManager.instance.activeTheme.themeColorSet;
var enabledColor:ColorSwatch =
colorSet.getContrastSwatch(colorSet.getSwatch(ThemeColorSet.PRIMARY,500));
//weak contrast against disabled fill:
- var disabledFillColor:ColorSwatch =
colorSet.getSwatch(ThemeColorSet.BASE, 200, 50);
- var disabledColor:ColorSwatch =
colorSet.getWeakContrastSwatch(disabledFillColor);
+ // var disabledFillColor:ColorSwatch =
colorSet.getSwatch(ThemeColorSet.BASE, 200, 50);
+ // var disabledColor:ColorSwatch =
colorSet.getWeakContrastSwatch(disabledFillColor);
+ var disabledColor:ColorSwatch =
colorSet.getSwatch(ThemeColorSet.BASE, 300,50);
_checkIcon = new Div();
var size:Number = 16 * getMultiplier();
@@ -348,8 +349,10 @@ package org.apache.royale.style.skins
if(!_indeterminateIcon){
var colorSet:ThemeColorSet =
ThemeManager.instance.activeTheme.themeColorSet;
var enabledColor:ColorSwatch =
colorSet.getContrastSwatch(colorSet.getSwatch(ThemeColorSet.PRIMARY,500));
- var disabledFillColor:ColorSwatch =
colorSet.getSwatch(ThemeColorSet.BASE, 200, 50);
- var disabledColor:ColorSwatch =
colorSet.getWeakContrastSwatch(disabledFillColor);
+ // var disabledFillColor:ColorSwatch =
colorSet.getSwatch(ThemeColorSet.BASE, 200, 50);
+ // var disabledColor:ColorSwatch =
colorSet.getWeakContrastSwatch(disabledFillColor);
+
+ var disabledColor:ColorSwatch =
colorSet.getSwatch(ThemeColorSet.BASE, 300,50);
_indeterminateIcon = new Div();
var size:Number = 16 * getMultiplier();
diff --git
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/layout/InsetBlock.as
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/skins/IToastSkin.as
similarity index 61%
copy from
frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/layout/InsetBlock.as
copy to
frameworks/projects/Style/src/main/royale/org/apache/royale/style/skins/IToastSkin.as
index 2c5260018b..a640d3d67d 100644
---
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/layout/InsetBlock.as
+++
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/skins/IToastSkin.as
@@ -16,16 +16,24 @@
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////
-package org.apache.royale.style.stylebeads.layout
+package org.apache.royale.style.skins
{
- import org.apache.royale.style.stylebeads.LeafStyleBase;
- import org.apache.royale.debugging.assert;
-
- public class InsetBlock extends InsetBase
+ import org.apache.royale.style.IStyleSkin;
+ import org.apache.royale.style.IStyleUIBase;
+ import org.apache.royale.style.StyleUIBase;
+
+ public interface IToastSkin extends IStyleSkin
{
- public function InsetBlock()
- {
- super("inset-y", "inset-block");
- }
+ //function updateStyles():void;
+ //function get labelStyles():Array;
+
+ function get toastContentStyles():Array;
+ function get textLayoutStyles():Array;
+ function get buttonsLayoutStyles():Array;
+ function get toastBodyStyles():Array;
+
+ function getIcon(flavor:String):IStyleUIBase;
+ function getActionButton(action:String):IStyleUIBase;
+ function getCloseButton():IStyleUIBase;
}
}
\ No newline at end of file
diff --git
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/skins/ToastSkin.as
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/skins/ToastSkin.as
new file mode 100644
index 0000000000..3bcf209a66
--- /dev/null
+++
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/skins/ToastSkin.as
@@ -0,0 +1,381 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package org.apache.royale.style.skins
+{
+ import org.apache.royale.style.StyleSkin;
+ import org.apache.royale.style.Icon;
+ import org.apache.royale.style.IStyleUIBase;
+ import org.apache.royale.core.IStrand;
+ import org.apache.royale.style.Toast;
+ import org.apache.royale.style.colors.ColorSwatch;
+ import org.apache.royale.style.colors.ThemeColorSet;
+ import org.apache.royale.style.elements.Button;
+ import org.apache.royale.style.stylebeads.StyleBeadBase;
+ import org.apache.royale.style.stylebeads.anim.Animation;
+ import org.apache.royale.style.stylebeads.anim.CustomAnimation;
+ import org.apache.royale.style.util.AnimationManager;
+ import org.apache.royale.style.stylebeads.anim.Transition;
+ import org.apache.royale.style.stylebeads.flexgrid.Flex;
+ import org.apache.royale.style.stylebeads.flexgrid.JustifyContent;
+ import org.apache.royale.style.stylebeads.layout.Bottom;
+ import org.apache.royale.style.stylebeads.layout.Display;
+ import org.apache.royale.style.stylebeads.flexgrid.AlignItems;
+ import org.apache.royale.style.stylebeads.interact.UserSelect;
+ import org.apache.royale.style.stylebeads.layout.Position;
+ import org.apache.royale.style.stylebeads.layout.ZIndex;
+ import org.apache.royale.style.stylebeads.sizing.HeightStyle;
+ import org.apache.royale.style.stylebeads.sizing.WidthStyle;
+ import org.apache.royale.style.stylebeads.border.BorderRadius;
+ import org.apache.royale.style.stylebeads.states.HoverState;
+ import org.apache.royale.style.stylebeads.states.attribute.DataState;
+ import org.apache.royale.style.stylebeads.typography.FontSmoothing;
+ import org.apache.royale.style.support.Icons;
+ import org.apache.royale.style.util.ThemeManager;
+ import org.apache.royale.style.stylebeads.background.BackgroundColor;
+ import org.apache.royale.style.stylebeads.typography.FontSize;
+ import org.apache.royale.style.stylebeads.typography.TextColor;
+ import org.apache.royale.style.stylebeads.typography.FontWeight;
+ import org.apache.royale.style.stylebeads.border.Border;
+ import org.apache.royale.style.stylebeads.spacing.Padding;
+
+
+
+ public class ToastSkin extends StyleSkin implements IToastSkin
+ {
+
+ //distance from bottom that toast should pop-up to.
+ public static const arrivalOffset:uint = 30;
+
+ private static const inAnimationName:String = 'toast-fadein';
+ private static const outAnimationName:String = 'toast-fadeout';
+ public static function getAnimation(out:Boolean):StyleBeadBase{
+ var result:StyleBeadBase;
+ var durationMillisecs:uint = 500;
+ var name:String = out ? outAnimationName :
inAnimationName;
+ if (AnimationManager.has(name)) {
+ //trace('optimized animation route',name)
+ return new Animation(name + " " +
durationMillisecs + "ms");
+ }
+ //trace('creating animation route',name)
+ //otherwise create CustomAnimation, which registers it:
+ if (out) {
+ result = new CustomAnimation(name,[
+ 'from {bottom: '+arrivalOffset+'px;
opacity: 1; visibility: visible;}',
+ 'to {bottom: 0px; opacity: 0;
visibility: hidden;}'
+ ],durationMillisecs);
+ } else {
+ //in
+ result = new CustomAnimation(name,[
+ 'from {bottom: 0; opacity: 0;
visibility: visible; }',
+ 'to {bottom: '+arrivalOffset+'px;
opacity: 1; visibility: visible; }'
+ ],durationMillisecs);
+ }
+ return result;
+ }
+
+ public function ToastSkin()
+ {
+ super();
+ }
+
+ /**
+ * @royaleignorecoercion org.apache.royale.style.Toast
+ */
+ private function get host():Toast
+ {
+ return _strand as Toast;
+ }
+ override public function set strand(value:IStrand):void
+ {
+ super.strand = value;
+ applyStyles();
+ }
+
+ private function
getBackgroundShade(colorSet:ThemeColorSet,colorState:String):ColorSwatch{
+ var shade:uint = 500;
+ return colorSet.getSwatch(colorState,shade);
+ }
+
+ private function getHostFlavorColor():String{
+ var hostFlavor:String = host.flavor;
+ //normalize any 'specific' variations:
+ switch(hostFlavor) {
+ case 'negative':
+ hostFlavor = 'error';
+ break;
+ case 'positive':
+ hostFlavor = 'success';
+ break;
+ default:
+ }
+ return hostFlavor || ThemeColorSet.NEUTRAL;
+ }
+
+ private function createToastStyles():void
+ {
+ var multiplier:Number = getMultiplier();
+ var colorState:String = getHostFlavorColor();
+ var colorSet:ThemeColorSet =
ThemeManager.instance.activeTheme.themeColorSet ;
+ var backgroundColor:ColorSwatch =
getBackgroundShade(colorSet,colorState);
+ var padding:Padding = new
Padding(computeSize(multiplier * 4, host.unit), host.unit);
+ padding.right = padding.left = computeSize(8 *
multiplier,padding.unit);
+ var toastStyles:Array = [
+ new Display('inline-flex'),
+ /*new FlexDirection('row'),*/ //this is the
default anyway
+ new AlignItems('stretch'), // or new
AlignItems('center')
+ new BorderRadius(computeSize(4 * multiplier,
host.unit)),
+ padding,
+ new FontSmoothing('antialiased'),
+ new BackgroundColor(backgroundColor)
+ ];
+ var textStyles:Array = [
+ new FontSize(/*computeSize(14 * multiplier,
host.unit)*/host.size || 'base'),
+ new FontWeight(700),
+ new
TextColor(colorSet.getContrastSwatch(backgroundColor))
+ ];
+ _toastStyles = toastStyles.concat(textStyles);
+ }
+
+ private var _toastStyles:Array;
+ public function get toastContentStyles():Array
+ {
+ if(!_toastStyles)
+ createToastStyles();
+ return _toastStyles;
+ }
+
+ private function createBodyStyles():void
+ {
+ var multiplier:Number = getMultiplier();
+ var padding:Padding = new Padding(null, host.unit);
+ padding.right = computeSize(8 *
multiplier,padding.unit);
+ var styles:Array = [
+ padding,
+ new Display('inline-flex'),
+ new AlignItems('center')
+ ];
+ _bodyStyles = styles;
+ }
+
+ private var _bodyStyles:Array;
+ public function get toastBodyStyles():Array
+ {
+ if(!_bodyStyles)
+ createBodyStyles();
+ return _bodyStyles;
+ }
+
+ private function createTextLayoutStyles():void{
+ var multiplier:Number = getMultiplier();
+ var padding:Padding = new
Padding(computeSize(multiplier * 2, host.unit), host.unit);
+ //padding.right = padding.left = computeSize(8 *
multiplier,host.unit);
+ padding.inline = computeSize(8 * multiplier,host.unit);
+ _textLayoutStyles = [
+ new Display('inline-block'),
+ padding
+ ];
+ }
+
+ private var _textLayoutStyles:Array;
+ public function get textLayoutStyles():Array{
+ if(!_textLayoutStyles)
+ createTextLayoutStyles();
+ return _textLayoutStyles;
+ }
+
+ private function applyStyles():void
+ {
+ var inAnimation:StyleBeadBase = getAnimation(false);
+ var outAnimation:StyleBeadBase = getAnimation(true);
+ var toastContainerStyles:Array = [
+ new UserSelect('none'),
+ new Position('fixed'),
+ new Bottom(arrivalOffset+'px'),
+ new WidthStyle('100%'),
+ new Display('flex'),
+ new AlignItems('center'),
+ new JustifyContent('center'),
+ new ZIndex(100),
+ new DataState('showing', [
+ inAnimation
+ ]),
+ new DataState('hiding', [
+ outAnimation
+ ])
+ ];
+ _styles = toastContainerStyles;
+ host.setStyles(_styles, true);
+ COMPILE::JS{
+ host.element.addEventListener('animationend',
onAnimationEnded);
+ }
+ }
+
+ private function onAnimationEnded(e:Object):void{
+ switch(e.animationName) {
+ case inAnimationName:
+ host.afterShow();
+ break;
+ case outAnimationName:
+ host.afterHide();
+ break;
+ }
+ }
+
+ private function getMultiplier():Number
+ {
+ switch(host.size)
+ {
+ case "xs":
+ return 0.6;
+ case "sm":
+ return 0.8;
+ case "md":
+ return 1;
+ case "lg":
+ return 1.2;
+ case "xl":
+ return 1.4;
+ default:
+ return 1;
+ }
+ }
+
+ private function createButtonsLayoutStyles():void
+ {
+ var padding:Padding = new Padding(null,host.unit);
+ var multiplier:Number = getMultiplier();
+ padding.left = computeSize(5 * multiplier,host.unit);
+ var colorState:String = getHostFlavorColor();
+ var colorSet:ThemeColorSet =
ThemeManager.instance.getTheme(host.theme).themeColorSet;
+ //we need a contrast with the background color
+ var borderLineColor:ColorSwatch =
colorSet.getContrastSwatch(getBackgroundShade(colorSet,colorState)).getVariant(NaN,80);
+ var border:Border = new
Border(borderLineColor.toString(),'none',computeSize(multiplier,host.unit),null,host.unit);
+ border.leftStyle = 'solid';
+ _buttonsLayoutStyles = [
+ new Display('inline-flex'),
+ padding,
+ border,
+ new AlignItems('center'),
+ new JustifyContent('center')
+ ];
+ }
+
+ private var _buttonsLayoutStyles:Array;
+ public function get buttonsLayoutStyles():Array
+ {
+ if(!_buttonsLayoutStyles)
+ createButtonsLayoutStyles();
+ return _buttonsLayoutStyles;
+ }
+
+ private function getButtonHoverColor():BackgroundColor{
+ var colorState:String = getHostFlavorColor();
+ var colorSet:ThemeColorSet =
ThemeManager.instance.activeTheme.themeColorSet ;
+ var backgroundColor:ColorSwatch =
getBackgroundShade(colorSet,colorState);
+ return new
BackgroundColor(colorSet.getContrastSwatch(backgroundColor).getVariant(NaN,20));
+ }
+
+ private function createCloseButton():void{
+ var multiplier:Number = getMultiplier();
+ var closeButton:Button = new Button();
+ var dimension:String = computeSize(20 * multiplier,
host.unit)
+ closeButton.setStyles([
+ new WidthStyle(dimension),
+ new HeightStyle(dimension),
+ new Display('flex'),
+ new AlignItems('center'),
+ new JustifyContent('center'),
+ new BackgroundColor('transparent'),
+ new TextColor('inherit'),
+ new BorderRadius('full'),
+ new Transition(),
+ new HoverState([
+ getButtonHoverColor()
+ ])
+ ])
+ var icon:Icon = Icons.cross_Small();
+
+ icon.setStyles([
+ new Flex(1)
+ ])
+ closeButton.addElement(icon);
+ _closeButton = closeButton;
+ }
+
+ private var _closeButton:Button;
+ public function getCloseButton():IStyleUIBase{
+ if (!_closeButton)
+ createCloseButton();
+ return _closeButton;
+ }
+
+ public function getActionButton(action:String):IStyleUIBase{
+ var button:Button = new Button();
+ COMPILE::JS{
+ button.element.textContent = action;
+ }
+ var multiplier:Number = getMultiplier();
+ var padding:Padding = new
Padding(computeSize(multiplier * 2, host.unit), host.unit);
+ padding.inline = computeSize(8 * multiplier,host.unit);
+ button.setStyles([
+ new BackgroundColor('transparent'),
+ padding,
+ new BorderRadius('full'),
+ new TextColor('inherit'), //button natively has
its own text styles so we need to force inherit here to share our text styling
+ new FontSize('inherit'),
+ new FontWeight('inherit'),
+ new Transition(),
+ new HoverState([
+ getButtonHoverColor()
+ ])
+ ]);
+ return button;
+ }
+
+ public function getIcon(flavor:String):IStyleUIBase {
+ var icon:Icon;
+ switch(flavor) {
+ case "error":
+ case "warning":
+ case "negative":
+ icon = Icons.alert_medium();
+ break;
+ case "positive":
+ case "success":
+ icon = Icons.success_medium();
+ break;
+ case "info":
+ icon = Icons.info_medium();
+ break;
+ default:
+ icon = null
+ }
+
+ if (icon) {
+ var multiplier:Number = getMultiplier();
+ var dimension:String = computeSize(20 *
multiplier, host.unit);
+ icon.setStyles([
+ new WidthStyle(dimension),
+ new HeightStyle(dimension)
+ ])
+ }
+ return icon;
+ }
+ }
+}
\ No newline at end of file
diff --git
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/anim/Animation.as
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/anim/Animation.as
index fff2a1d14d..39bae98425 100644
---
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/anim/Animation.as
+++
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/anim/Animation.as
@@ -48,21 +48,21 @@ package org.apache.royale.style.stylebeads.anim
}
*/
- override public function set value(value:*):void
+ override public function set value(v:*):void
{
assert(
- isVar(value) ||
["spin","ping","pulse","bounce","none"].indexOf(value) != -1,
- "animation only accepts 'spin', 'ping',
'pulse', 'bounce', or a CSS variable referencing a valid animation"
+ isVar(v) || v == "none" || (v is String &&
v.length > 0),
+ "animation only accepts a valid animation name,
'none', or a CSS variable referencing an animation"
);
- calculatedRuleValue = calculatedSelector = _value =
value;
- if(isVar(value))
+ calculatedRuleValue = calculatedSelector = _value = v;
+ if(isVar(v))
{
- calculatedRuleValue = fromVar(value);
+ calculatedRuleValue = fromVar(v);
}
else
{
var theme:StyleTheme =
ThemeManager.instance.activeTheme;
- switch(value)
+ switch(v)
{
case "spin":
calculatedRuleValue =
theme.animateSpin;
@@ -80,6 +80,6 @@ package org.apache.royale.style.stylebeads.anim
break;
}
}
- }
+ }
}
}
\ No newline at end of file
diff --git
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/layout/InsetBlockEnd.as
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/anim/AnimationDuration.as
similarity index 59%
copy from
frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/layout/InsetBlockEnd.as
copy to
frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/anim/AnimationDuration.as
index 4b2d978cb8..2945d35a69 100644
---
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/layout/InsetBlockEnd.as
+++
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/anim/AnimationDuration.as
@@ -16,17 +16,28 @@
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////
-package org.apache.royale.style.stylebeads.layout
+package org.apache.royale.style.stylebeads.anim
{
import org.apache.royale.style.stylebeads.LeafStyleBase;
import org.apache.royale.debugging.assert;
+ import org.apache.royale.style.util.ThemeManager;
- public class InsetBlockEnd extends InsetBase
+ public class AnimationDuration extends LeafStyleBase
{
- public function InsetBlockEnd()
+ public function AnimationDuration(value:* = null)
{
- super("inset-be", "inset-block-end");
+ super("duration", "animation-duration", value);
}
+ override public function set value(value:*):void
+ {
+ _value = value;
+ assert(value == "default" || isVar(value) ||
(isInt(value) && value >= 0), "animation-duration only accepts valid CSS
variables or non-negative integers representing milliseconds");
+ calculatedSelector = value;
+ if(value == "default")
+ calculatedRuleValue =
ThemeManager.instance.activeTheme.defaultTransitionDuration;
+ else
+ calculatedRuleValue = isInt(value) ? value +
"ms" : fromVar(value);
+ }
}
-}
\ No newline at end of file
+}
diff --git
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/layout/InsetBlockStart.as
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/anim/AnimationIterationCount.as
similarity index 62%
copy from
frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/layout/InsetBlockStart.as
copy to
frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/anim/AnimationIterationCount.as
index 9428d3c829..79df3749b8 100644
---
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/layout/InsetBlockStart.as
+++
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/anim/AnimationIterationCount.as
@@ -16,17 +16,31 @@
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////
-package org.apache.royale.style.stylebeads.layout
+package org.apache.royale.style.stylebeads.anim
{
import org.apache.royale.style.stylebeads.LeafStyleBase;
import org.apache.royale.debugging.assert;
- public class InsetBlockStart extends InsetBase
+ public class AnimationIterationCount extends LeafStyleBase
{
- public function InsetBlockStart()
+ public function AnimationIterationCount(value:* = null)
{
- super("inset-bs", "inset-block-start");
+ super("iteration", "animation-iteration-count", value);
}
+ override public function get value():*
+ {
+ return _value;
+ }
+
+ override public function set value(value:*):void
+ {
+ assert(isVar(value) || value == "infinite" ||
(isInt(value) && value >= 0), "animation-iteration-count only accepts
'infinite', a non-negative integer, or a CSS variable");
+ calculatedRuleValue = calculatedSelector = _value =
value;
+ if(isVar(value))
+ {
+ calculatedRuleValue = fromVar(value);
+ }
+ }
}
-}
\ No newline at end of file
+}
diff --git
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/anim/Animation.as
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/anim/AnimationTimingFunction.as
similarity index 50%
copy from
frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/anim/Animation.as
copy to
frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/anim/AnimationTimingFunction.as
index fff2a1d14d..e209841e20 100644
---
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/anim/Animation.as
+++
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/anim/AnimationTimingFunction.as
@@ -19,67 +19,47 @@
package org.apache.royale.style.stylebeads.anim
{
import org.apache.royale.style.stylebeads.LeafStyleBase;
- import org.apache.royale.debugging.assert;
import org.apache.royale.style.util.StyleTheme;
import org.apache.royale.style.util.ThemeManager;
+ import org.apache.royale.style.util.CSSLookup;
+ import org.apache.royale.debugging.assert;
- public class Animation extends LeafStyleBase
+ public class AnimationTimingFunction extends LeafStyleBase
{
- public function Animation(value:* = null)
+ public function AnimationTimingFunction(value:* = null)
{
- super("animate", "animation", value);
+ super("ease", "animation-timing-function", value);
}
-
-// need to figure out how to register keyframes, etc.
-
-//animate-bounce
-//animation: var(--animate-bounce); /* bounce 1s infinite */
-
-/**
-@keyframes bounce {
- 0%, 100% {
- transform: translateY(-25%);
- animation-timing-function: cubic-bezier(0.8, 0, 1, 1);
- }
- 50% {
- transform: none;
- animation-timing-function: cubic-bezier(0, 0, 0.2, 1);
- }
-}
- */
-
override public function set value(value:*):void
{
- assert(
- isVar(value) ||
["spin","ping","pulse","bounce","none"].indexOf(value) != -1,
- "animation only accepts 'spin', 'ping',
'pulse', 'bounce', or a CSS variable referencing a valid animation"
- );
- calculatedRuleValue = calculatedSelector = _value =
value;
- if(isVar(value))
- {
- calculatedRuleValue = fromVar(value);
- }
- else
+ _value = value;
+ var ruleValue:String = value;
+ var selectorValue:String = value;
+ var theme:StyleTheme =
ThemeManager.instance.activeTheme;
+ switch(value)
{
- var theme:StyleTheme =
ThemeManager.instance.activeTheme;
- switch(value)
- {
- case "spin":
- calculatedRuleValue =
theme.animateSpin;
- break;
- case "ping":
- calculatedRuleValue =
theme.animatePing;
- break;
- case "pulse":
- calculatedRuleValue =
theme.animatePulse;
- break;
- case "bounce":
- calculatedRuleValue =
theme.animateBounce;
- break;
- case "none":
- break;
- }
+ case "default":
+ ruleValue =
theme.defaultTransitionTimingFunction;
+ break;
+ case "in":
+ ruleValue = theme.easeIn;
+ break;
+ case "out":
+ ruleValue = theme.easeOut;
+ break;
+ case "in-out":
+ ruleValue = theme.easeInOut;
+ break;
+ case "linear":
+ case "initial":
+ break;
+ default:
+ ruleValue =
CSSLookup.getProperty(value);
+ break;
}
- }
+ assert(ruleValue, "animation-timing-function only
accepts 'linear', 'in', 'out', 'in-out', 'initial', or a valid CSS timing
function value");
+ calculatedSelector = selectorValue;
+ calculatedRuleValue = ruleValue;
+ }
}
-}
\ No newline at end of file
+}
diff --git
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/anim/CustomAnimation.as
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/anim/CustomAnimation.as
new file mode 100644
index 0000000000..5ab312324c
--- /dev/null
+++
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/anim/CustomAnimation.as
@@ -0,0 +1,105 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package org.apache.royale.style.stylebeads.anim
+{
+ import org.apache.royale.style.stylebeads.CompositeStyle;
+
+ public class CustomAnimation extends CompositeStyle
+ {
+ public function CustomAnimation(name:String =
null,keyframes:Array = null,duration:Object = 'default',timingFunction:String =
'default',iterationCount:String = null)
+ {
+ super();
+ _nameStyle = new Keyframes(name,keyframes);
+ _timingStyle = new
AnimationTimingFunction(timingFunction);
+ _durationStyle = new AnimationDuration(duration);
+ styles = [
+ _nameStyle,
+ _timingStyle,
+ _durationStyle
+ ];
+ if (iterationCount)
+ {
+ this.iterationCount = iterationCount;
+ }
+ }
+
+ private var _nameStyle:Keyframes;
+ private var _timingStyle:AnimationTimingFunction;
+ private var _durationStyle:AnimationDuration;
+ private var _iterationCountStyle:AnimationIterationCount;
+
+ public function get name():String
+ {
+ return _nameStyle.value;
+ }
+
+ public function set name(value:String):void
+ {
+ _nameStyle.value = value;
+ }
+
+ public function get keyframes():Array
+ {
+ return _nameStyle.keyframes;
+ }
+
+ public function set keyframes(value:Array):void
+ {
+ _nameStyle.keyframes = value;
+ }
+
+ public function get timingFunction():String
+ {
+ return _timingStyle.value;
+ }
+
+ public function set timingFunction(value:String):void
+ {
+ _timingStyle.value = value;
+ }
+
+ public function get duration():*
+ {
+ return _durationStyle.value;
+ }
+
+ public function set duration(value:*):void
+ {
+ _durationStyle.value = value;
+ }
+
+ public function get iterationCount():String
+ {
+ return _iterationCountStyle ?
_iterationCountStyle.value : null;
+ }
+
+ public function set iterationCount(value:String):void
+ {
+ if (!_iterationCountStyle)
+ {
+ _iterationCountStyle = new
AnimationIterationCount(value);
+ addStyleBead(_iterationCountStyle);
+ }
+ else
+ {
+ _iterationCountStyle.value = value;
+ }
+ }
+ }
+}
diff --git
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/layout/InsetBlockEnd.as
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/anim/Keyframes.as
similarity index 54%
copy from
frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/layout/InsetBlockEnd.as
copy to
frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/anim/Keyframes.as
index 4b2d978cb8..2792189ea5 100644
---
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/layout/InsetBlockEnd.as
+++
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/anim/Keyframes.as
@@ -16,17 +16,49 @@
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////
-package org.apache.royale.style.stylebeads.layout
+package org.apache.royale.style.stylebeads.anim
{
import org.apache.royale.style.stylebeads.LeafStyleBase;
- import org.apache.royale.debugging.assert;
+ import org.apache.royale.style.util.AnimationManager;
- public class InsetBlockEnd extends InsetBase
+ public class Keyframes extends LeafStyleBase
{
- public function InsetBlockEnd()
+ public function Keyframes(name:String = null, value:Array =
null)
{
- super("inset-be", "inset-block-end");
+ _keyframes = value;
+ super("keyframes", "animation-name", name);
}
+ private var _keyframes:Array;
+
+ public function get keyframes():Array
+ {
+ return _keyframes;
+ }
+
+ public function set keyframes(value:Array):void
+ {
+ _keyframes = value;
+ if (_value && _keyframes)
+ {
+ AnimationManager.registerKeyframes(_value,
_keyframes);
+ }
+ }
+
+ override public function get value():*
+ {
+ return _value;
+ }
+
+ override public function set value(value:*):void
+ {
+ _value = value;
+ calculatedSelector = _value;
+ calculatedRuleValue = _value;
+ if (_value && _keyframes)
+ {
+ AnimationManager.registerKeyframes(_value,
_keyframes);
+ }
+ }
}
-}
\ No newline at end of file
+}
diff --git
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/layout/Bottom.as
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/layout/Bottom.as
index ae272f81fb..5d32f7d57b 100644
---
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/layout/Bottom.as
+++
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/layout/Bottom.as
@@ -20,9 +20,9 @@ package org.apache.royale.style.stylebeads.layout
{
public class Bottom extends InsetBase
{
- public function Bottom()
+ public function Bottom(value:* = null)
{
- super("bottom", "bottom");
+ super("bottom", "bottom", value);
}
}
}
\ No newline at end of file
diff --git
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/layout/Inset.as
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/layout/Inset.as
index 77b52a3305..effbe92940 100644
---
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/layout/Inset.as
+++
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/layout/Inset.as
@@ -23,9 +23,9 @@ package org.apache.royale.style.stylebeads.layout
public class Inset extends InsetBase
{
- public function Inset()
+ public function Inset(value:* = null)
{
- super("inset", "inset");
+ super("inset", "inset", value);
}
}
}
\ No newline at end of file
diff --git
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/layout/InsetBase.as
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/layout/InsetBase.as
index 9c688b008b..dcaede4639 100644
---
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/layout/InsetBase.as
+++
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/layout/InsetBase.as
@@ -30,10 +30,12 @@ package org.apache.royale.style.stylebeads.layout
private var savedPrefix:String;
override public function set value(value:*):void
{
+ _value = value;
var isNum:Boolean = parseFloat(value) == value;
var isInt:Boolean = int(value) == value;
var parseNum:Number = parseFloat(value);
var isNegative:Boolean = parseNum < 0;
+
if(isNegative)
{
if(!savedPrefix)
@@ -55,12 +57,9 @@ package org.apache.royale.style.stylebeads.layout
{
calculatedSelector = sanitizeSelector(value);
calculatedRuleValue = value;
+ if(value == "none")
+ calculatedSelector = "hidden";
}
- //
assert(["inline","block","inline-block","flow-root","flex","inline-flex","grid","inline-grid","contents","table","inline-table","table-caption","table-cell","table-column","table-column-group","table-footer-group","table-header-group","table-row-group","table-row","list-item","none"].indexOf(value)
>= 0, "Invalid value for display: " + value);
- _value = value;
- calculatedRuleValue = calculatedSelector = value;
- if(value == "none")
- calculatedSelector = "hidden";
}
}
}
\ No newline at end of file
diff --git
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/layout/InsetBlock.as
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/layout/InsetBlock.as
index 2c5260018b..f8314e8137 100644
---
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/layout/InsetBlock.as
+++
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/layout/InsetBlock.as
@@ -23,9 +23,9 @@ package org.apache.royale.style.stylebeads.layout
public class InsetBlock extends InsetBase
{
- public function InsetBlock()
+ public function InsetBlock(value:* = null)
{
- super("inset-y", "inset-block");
+ super("inset-y", "inset-block", value);
}
}
}
\ No newline at end of file
diff --git
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/layout/InsetBlockEnd.as
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/layout/InsetBlockEnd.as
index 4b2d978cb8..6a60eb83da 100644
---
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/layout/InsetBlockEnd.as
+++
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/layout/InsetBlockEnd.as
@@ -23,9 +23,9 @@ package org.apache.royale.style.stylebeads.layout
public class InsetBlockEnd extends InsetBase
{
- public function InsetBlockEnd()
+ public function InsetBlockEnd(value:* = null)
{
- super("inset-be", "inset-block-end");
+ super("inset-block-end", "inset-block-end", value);
}
}
diff --git
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/layout/InsetBlockStart.as
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/layout/InsetBlockStart.as
index 9428d3c829..0c22d15ac8 100644
---
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/layout/InsetBlockStart.as
+++
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/layout/InsetBlockStart.as
@@ -23,9 +23,9 @@ package org.apache.royale.style.stylebeads.layout
public class InsetBlockStart extends InsetBase
{
- public function InsetBlockStart()
+ public function InsetBlockStart(value:* = null)
{
- super("inset-bs", "inset-block-start");
+ super("inset-block-start", "inset-block-start", value);
}
}
diff --git
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/layout/InsetInlineEnd.as
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/layout/InsetInlineEnd.as
index daf90c196d..ebd372dcde 100644
---
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/layout/InsetInlineEnd.as
+++
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/layout/InsetInlineEnd.as
@@ -20,9 +20,9 @@ package org.apache.royale.style.stylebeads.layout
{
public class InsetInlineEnd extends InsetBase
{
- public function InsetInlineEnd()
+ public function InsetInlineEnd(value:* = null)
{
- super("inset-e", "inset-inline-end");
+ super("inset-inline-end", "inset-inline-end", value);
}
}
}
\ No newline at end of file
diff --git
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/layout/InsetInlineStart.as
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/layout/InsetInlineStart.as
index 9445e67fd4..03205315b6 100644
---
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/layout/InsetInlineStart.as
+++
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/layout/InsetInlineStart.as
@@ -23,9 +23,9 @@ package org.apache.royale.style.stylebeads.layout
public class InsetInlineStart extends InsetBase
{
- public function InsetInlineStart()
+ public function InsetInlineStart(value:* = null)
{
- super("inset-s", "inset-inline-start");
+ super("inset-inline-start", "inset-inline-start",
value);
}
}
}
\ No newline at end of file
diff --git
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/layout/Left.as
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/layout/Left.as
index 1943d10522..0ed0885b7d 100644
---
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/layout/Left.as
+++
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/layout/Left.as
@@ -20,9 +20,9 @@ package org.apache.royale.style.stylebeads.layout
{
public class Left extends InsetBase
{
- public function Left()
+ public function Left(value:* = null)
{
- super("left", "left");
+ super("left", "left", value);
}
}
}
\ No newline at end of file
diff --git
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/layout/Right.as
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/layout/Right.as
index b023a5c522..187711cbef 100644
---
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/layout/Right.as
+++
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/layout/Right.as
@@ -22,9 +22,9 @@ package org.apache.royale.style.stylebeads.layout
public class Right extends InsetBase
{
- public function Right()
+ public function Right(value:* = null)
{
- super("right", "right");
+ super("right", "right", value);
}
}
}
\ No newline at end of file
diff --git
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/layout/Top.as
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/layout/Top.as
index db803e5df7..fd3f2de67a 100644
---
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/layout/Top.as
+++
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/layout/Top.as
@@ -22,9 +22,9 @@ package org.apache.royale.style.stylebeads.layout
public class Top extends InsetBase
{
- public function Top()
+ public function Top(value:* = null)
{
- super("top", "top");
+ super("top", "top", value);
}
}
}
\ No newline at end of file
diff --git
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/layout/InsetBlockStart.as
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/states/attribute/NotDataState.as
similarity index 59%
copy from
frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/layout/InsetBlockStart.as
copy to
frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/states/attribute/NotDataState.as
index 9428d3c829..a7ed5fdde4 100644
---
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/layout/InsetBlockStart.as
+++
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/stylebeads/states/attribute/NotDataState.as
@@ -16,17 +16,35 @@
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////
-package org.apache.royale.style.stylebeads.layout
+package org.apache.royale.style.stylebeads.states.attribute
{
- import org.apache.royale.style.stylebeads.LeafStyleBase;
- import org.apache.royale.debugging.assert;
+ import org.apache.royale.style.stylebeads.states.NotState;
- public class InsetBlockStart extends InsetBase
+ /**
+ * NotDataState is a decorator that adds a :not([data-attribute])
pseudo-class to the rule.
+ */
+ public class NotDataState extends NotState
{
- public function InsetBlockStart()
+ public function NotDataState(type:String = null, styles:Array =
null)
{
- super("inset-bs", "inset-block-start");
+ super(null, styles);
+ if(type)
+ {
+ dataType = type;
+ }
}
+ private var _dataType:String;
+ public function get dataType():String
+ {
+ return _dataType;
+ }
+
+ public function set dataType(value:String):void
+ {
+ _dataType = value;
+ ruleDecorator = "[data-" + value + "]";
+ selectorDecorator = "not-data-" + value + ":";
+ }
}
-}
\ No newline at end of file
+}
diff --git
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/support/Icons.as
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/support/Icons.as
new file mode 100644
index 0000000000..ea9100260b
--- /dev/null
+++
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/support/Icons.as
@@ -0,0 +1,92 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+package org.apache.royale.style.support
+{
+ import org.apache.royale.style.Icon;
+
+
+ /**
+ * The Icons class supports commonly used icons
+ *
+ * This file includes derived work based on Adobe Spectrum Icons,
+ * licensed under the Apache License, Version 2.0.
+ *
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10.2
+ * @playerversion AIR 2.6
+ * @productversion Royale 1.0
+ *
+ * @royalesuppressexport
+ */
+ public class Icons
+ {
+ /**
+ * constructor.
+ *
+ * @private
+ */
+ private function Icons()
+ {
+ super();
+ }
+
+ /**
+ * @royalesuppressexport
+ */
+ public static function cross_Small():Icon{
+ if (!Icon.isRegistered('support_icons_cross_small')) {
+ Icon.registerIcon('support_icons_cross_small',
<svg viewBox="0 0 20 20" fill="currentColor" stroke="none"><path d="M13.317
12.433L10.884 10l2.433-2.433a.625.625 0 1 0-.884-.884L10 9.116 7.567
6.683a.625.625 0 1 0-.884.884L9.116 10 6.683 12.433a.625.625 0 1 0 .884.884L10
10.884l2.433 2.433a.625.625 0 0 0 .884-.884z" stroke-linecap="round"
stroke-linejoin="round"/></svg>);
+ }
+ return new Icon('support_icons_cross_small');
+ }
+
+ /**
+ * @royalesuppressexport
+ */
+ public static function info_medium():Icon{
+ if (!Icon.isRegistered('support_icons_info_medium')) {
+ Icon.registerIcon('support_icons_info_medium',
<svg viewBox="0 0 20 20" fill="currentColor" stroke="none"><path d="M11 3a8 8 0
1 0 8 8 8 8 0 0 0-8-8zm-.15 2.15a1.359 1.359 0 0 1 1.431
1.283q.004.064.001.129A1.332 1.332 0 0 1 10.85 7.994a1.353 1.353 0 0
1-1.432-1.433 1.359 1.359 0 0 1 1.304-1.412q.064-.002.128.001zM13 15.5a.5.5 0 0
1-.5.5h-3a.5.5 0 0 1-.5-.5v-1a.5.5 0 0 1 .5-.5H10V11h-.5a.5.5 0 0
1-.5-.5v-1a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 .5.5V14h.5a.5.5 0 0 1 .5.5z"
stroke-linecap="rou [...]
+ }
+ return new Icon('support_icons_info_medium');
+ }
+
+ /**
+ * @royalesuppressexport
+ */
+ public static function alert_medium():Icon{
+ if (!Icon.isRegistered('support_icons_alert_medium')) {
+ Icon.registerIcon('support_icons_alert_medium',
<svg viewBox="0 0 20 20" fill="currentColor" stroke="none"><path d="M10.564
3.289L2.2 18.256A.5.5 0 0 0 2.636 19h16.728a.5.5 0 0 0 .436-.744L11.436
3.289a.5.5 0 0 0-.872 0zM12 16.75a.25.25 0 0 1-.25.25h-1.5a.25.25 0 0
1-.25-.25v-1.5a.25.25 0 0 1 .25-.25h1.5a.25.25 0 0 1 .25.25zm0-3a.25.25 0 0
1-.25.25h-1.5a.25.25 0 0 1-.25-.25v-6a.25.25 0 0 1 .25-.25h1.5a.25.25 0 0 1
.25.25z" stroke-linecap="round" stroke-linejoin="round"/></svg>);
+ }
+ return new Icon('support_icons_alert_medium');
+ }
+
+ /**
+ * @royalesuppressexport
+ */
+ public static function success_medium():Icon{
+ if (!Icon.isRegistered('support_icons_success_medium'))
{
+
Icon.registerIcon('support_icons_success_medium', <svg viewBox="0 0 20 20"
fill="currentColor" stroke="none"><path d="M11 3A8 8 0 1 0 19 11A8 8 0 0 0 11
3M16.333 7.54L10.009 15.67A.6.6 0 0 1 9.572 15.9H9.535A.6.6 0 0 1 9.11
15.724L5.217 11.824A.6.6 0 0 1 5.217 10.975L5.88 10.312A.6.6 0 0 1 6.728
10.312L9.4 12.991L14.656 6.237A.6.6 0 0 1 15.499 6.137L16.227 6.703A.6.6 0 0 1
16.333 7.54Z" stroke-linecap="round" stroke-linejoin="round"/></svg>);
+ }
+ return new Icon('support_icons_success_medium');
+ }
+
+
+ }
+}