This is an automated email from the ASF dual-hosted git repository.
yishayw 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 ca7254fe79 Added Toggle
ca7254fe79 is described below
commit ca7254fe79fe72498788c54683b111de819d15ee
Author: Yishay Weiss <[email protected]>
AuthorDate: Tue Apr 14 11:24:25 2026 +0300
Added Toggle
---
.../projects/Style/src/main/resources/defaults.css | 4 +
.../Style/src/main/resources/style-manifest.xml | 2 +
.../main/royale/org/apache/royale/style/Toggle.as | 182 +++++++++++++++
.../org/apache/royale/style/skins/IToggleSkin.as | 29 +++
.../org/apache/royale/style/skins/ToggleSkin.as | 243 +++++++++++++++++++++
5 files changed, 460 insertions(+)
diff --git a/frameworks/projects/Style/src/main/resources/defaults.css
b/frameworks/projects/Style/src/main/resources/defaults.css
index 8144ff87b2..f4f028200b 100644
--- a/frameworks/projects/Style/src/main/resources/defaults.css
+++ b/frameworks/projects/Style/src/main/resources/defaults.css
@@ -59,6 +59,10 @@ Dropdown
{
IStyleSkin:
ClassReference("org.apache.royale.style.skins.DropdownSkin");
}
+Toggle
+{
+ IStyleSkin: ClassReference("org.apache.royale.style.skins.ToggleSkin");
+}
DataItemRenderer
{
diff --git a/frameworks/projects/Style/src/main/resources/style-manifest.xml
b/frameworks/projects/Style/src/main/resources/style-manifest.xml
index f96c9ea7ef..0bc6f3cc71 100644
--- a/frameworks/projects/Style/src/main/resources/style-manifest.xml
+++ b/frameworks/projects/Style/src/main/resources/style-manifest.xml
@@ -30,6 +30,7 @@
<component id="CheckBox" class="org.apache.royale.style.CheckBox"/>
<component id="Divider" class="org.apache.royale.style.Divider"/>
<component id="Dropdown" class="org.apache.royale.style.Dropdown"/>
+ <component id="Toggle" class="org.apache.royale.style.Toggle"/>
<component id="FlexContainer" class="org.apache.royale.style.FlexContainer"/>
<component id="GridContainer" class="org.apache.royale.style.GridContainer"/>
<component id="StyleSkin" class="org.apache.royale.style.StyleSkin"/>
@@ -325,5 +326,6 @@
<component id="AccordionSectionSkin"
class="org.apache.royale.style.skins.AccordionSectionSkin"/>
<component id="AccordionContentSkin"
class="org.apache.royale.style.skins.AccordionContentSkin"/>
<component id="ListRendererSkin"
class="org.apache.royale.style.skins.ListRendererSkin"/>
+ <component id="ToggleSkin" class="org.apache.royale.style.skins.ToggleSkin"/>
</componentPackage>
diff --git
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/Toggle.as
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/Toggle.as
new file mode 100644
index 0000000000..ce89a8646a
--- /dev/null
+++
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/Toggle.as
@@ -0,0 +1,182 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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
+{
+ COMPILE::JS{
+ import org.apache.royale.core.WrappedHTMLElement;
+ }
+ import org.apache.royale.events.ValueChangeEvent;
+ import org.apache.royale.core.IHasLabel;
+ import org.apache.royale.style.elements.Div;
+ import org.apache.royale.style.elements.Span;
+ import org.apache.royale.style.skins.IToggleSkin;
+ import org.apache.royale.style.stylebeads.utils.ScreenReader;
+
+ /**
+ * Dispatched when the user toggles the switch.
+ */
+ [Event(name="change", type="org.apache.royale.events.Event")]
+
+ public class Toggle extends StyleUIBase implements IHasLabel
+ {
+
+ public function Toggle()
+ {
+ super();
+ }
+
+ COMPILE::JS
+ private var input:HTMLInputElement;
+
+ private var track:Div;
+
+ private var thumb:Div;
+
+ COMPILE::JS
+ private function elementClicked():void
+ {
+ processCheckedChange(input.checked, false);
+ }
+
+ override protected function getTag():String
+ {
+ return "label";
+ }
+
+ COMPILE::JS
+ override protected function createElement():WrappedHTMLElement
+ {
+ var elem:WrappedHTMLElement = super.createElement();
+ input = newElement("input") as HTMLInputElement;
+ input.type = "checkbox";
+ var srOnly:String = new ScreenReader().getSelector();
+ input.className = ("peer " + srOnly);
+ input.onclick = elementClicked;
+ elem.appendChild(input);
+
+ track = new Div();
+ addElement(track);
+
+ thumb = new Div();
+ track.addElement(thumb);
+
+ return elem;
+ }
+
+ private var _label:String = "";
+
+ public function get label():String
+ {
+ return _label;
+ }
+
+ private var span:Span;
+
+ public function set label(value:String):void
+ {
+ COMPILE::JS
+ {
+ if(_label != value){
+ _label = value;
+ if(!span){
+ span = new Span();
+ addElement(span);
+ if(_stylesLoaded)
+ {
+ applyLabelSkin();
+ }
+ }
+ span.text = value;
+ input.setAttribute("aria-label", value);
+ }
+ }
+ }
+
+ /**
+ * @royaleignorecoercion
org.apache.royale.style.skins.IToggleSkin
+ */
+ override protected function applySkin():void
+ {
+ var toggleSkin:IToggleSkin = skin as IToggleSkin;
+ track.setStyles(toggleSkin.trackStyles, true);
+ thumb.setStyles(toggleSkin.thumbStyles, true);
+ applyLabelSkin();
+ }
+
+ /**
+ * @royaleignorecoercion
org.apache.royale.style.skins.IToggleSkin
+ */
+ private function applyLabelSkin():void
+ {
+ if(!span) return;
+ var toggleSkin:IToggleSkin = skin as IToggleSkin;
+ span.setStyles(toggleSkin.labelStyles, true);
+ }
+
+ private var _disabled:Boolean;
+
+ public function get disabled():Boolean
+ {
+ return _disabled;
+ }
+
+ public function set disabled(value:Boolean):void
+ {
+ COMPILE::JS
+ {
+ if(value != _disabled){
+ input.disabled = value;
+ toggleAttribute("data-disabled", value);
+ }
+ }
+ _disabled = value;
+ }
+
+ private var _checked:Boolean;
+
+
[Bindable(event='valueChange',type='org.apache.royale.events.ValueChangeEvent')]
+ public function get checked():Boolean
+ {
+ return _checked;
+ }
+
+ public function set checked(value:Boolean):void
+ {
+ processCheckedChange(value, true);
+ }
+
+ private function processCheckedChange(value:Boolean,
programmatic:Boolean):void
+ {
+ COMPILE::JS
+ {
+ if(value != _checked){
+ _checked = value;
+ if (programmatic) input.checked = value;
+ toggleAttribute("data-checked", value);
+
dispatchEvent(ValueChangeEvent.createUpdateEvent(this, 'checked', !value,
value));
+ }
+ }
+ }
+
+ override public function getWrapperStyle():String
+ {
+ return 'toggle';
+ }
+ }
+}
diff --git
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/skins/IToggleSkin.as
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/skins/IToggleSkin.as
new file mode 100644
index 0000000000..39722e43d3
--- /dev/null
+++
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/skins/IToggleSkin.as
@@ -0,0 +1,29 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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.IStyleSkin;
+
+ public interface IToggleSkin extends IStyleSkin
+ {
+ function get trackStyles():Array;
+ function get thumbStyles():Array;
+ function get labelStyles():Array;
+ }
+}
diff --git
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/skins/ToggleSkin.as
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/skins/ToggleSkin.as
new file mode 100644
index 0000000000..8ec655e6c5
--- /dev/null
+++
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/skins/ToggleSkin.as
@@ -0,0 +1,243 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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.Toggle;
+ import org.apache.royale.core.IStrand;
+ import org.apache.royale.style.colors.ColorSwatch;
+ import org.apache.royale.style.colors.ThemeColorSet;
+ import org.apache.royale.style.util.ThemeManager;
+ import org.apache.royale.style.stylebeads.layout.Display;
+ import org.apache.royale.style.stylebeads.layout.Position;
+ import org.apache.royale.style.stylebeads.layout.Left;
+ import org.apache.royale.style.stylebeads.layout.Top;
+ import org.apache.royale.style.stylebeads.interact.Cursor;
+ import org.apache.royale.style.stylebeads.interact.UserSelect;
+ 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.border.Outline;
+ import org.apache.royale.style.stylebeads.background.BackgroundColor;
+ import org.apache.royale.style.stylebeads.anim.Transition;
+ import org.apache.royale.style.stylebeads.transform.Transform;
+ import org.apache.royale.style.stylebeads.typography.FontSize;
+ import org.apache.royale.style.stylebeads.typography.TextColor;
+ import org.apache.royale.style.stylebeads.states.PeerPseudo;
+ import org.apache.royale.style.stylebeads.states.GroupPseudo;
+ import org.apache.royale.style.stylebeads.states.CheckedState;
+ import org.apache.royale.style.stylebeads.states.DisabledState;
+ import org.apache.royale.style.stylebeads.states.FocusVisibleState;
+ import org.apache.royale.style.stylebeads.states.attribute.DataState;
+ import org.apache.royale.style.stylebeads.flexgrid.AlignItems;
+ import org.apache.royale.style.stylebeads.flexgrid.ColumnGap;
+
+ public class ToggleSkin extends StyleSkin implements IToggleSkin
+ {
+ public function ToggleSkin()
+ {
+ super();
+ }
+
+ /**
+ * @royaleignorecoercion org.apache.royale.style.Toggle
+ */
+ private function get host():Toggle
+ {
+ return _strand as Toggle;
+ }
+
+ override public function set strand(value:IStrand):void
+ {
+ super.strand = value;
+ applyStyles();
+ }
+
+ private function applyStyles():void
+ {
+ var size:Number = 16 * getMultiplier();
+ var gap:String = computeSize(size * 0.5, host.unit);
+
+ _styles = [
+ new Display("inline-flex"),
+ new AlignItems("center"),
+ new ColumnGap(gap),
+ new UserSelect("none"),
+ new Cursor("pointer"),
+ new DataState("disabled", [
+ new Cursor("default")
+ ])
+ ];
+ host.setStyles(_styles);
+ }
+
+ private function getMultiplier():Number
+ {
+ switch(host.size)
+ {
+ case "sm":
+ return 0.875;
+ case "md":
+ return 1;
+ case "lg":
+ return 1.125;
+ case "xl":
+ return 1.25;
+ default:
+ return 1;
+ }
+ }
+
+ private var _trackStyles:Array;
+
+ public function get trackStyles():Array
+ {
+ if(!_trackStyles)
+ createTrackStyles();
+ return _trackStyles;
+ }
+
+ public function set trackStyles(value:Array):void
+ {
+ _trackStyles = value;
+ }
+
+ private function createTrackStyles():void
+ {
+ var colorSet:ThemeColorSet =
ThemeManager.instance.activeTheme.themeColorSet;
+ var primaryColor:ColorSwatch =
colorSet.getSwatch(ThemeColorSet.PRIMARY, 500);
+ var uncheckedColor:ColorSwatch =
colorSet.getSwatch(ThemeColorSet.NEUTRAL, 300);
+ var disabledColor:ColorSwatch =
colorSet.getSwatch(ThemeColorSet.BASE, 200, 50);
+
+ var size:Number = 16 * getMultiplier();
+ var trackHeight:String = computeSize(size * 1.5,
host.unit);
+ var trackWidth:String = computeSize(size * 2.75,
host.unit);
+
+ var outline:Outline = new Outline();
+ outline.unit = host.unit;
+ outline.width = 0.5;
+ outline.style = "solid";
+ outline.color = primaryColor.getVariant(NaN,
40).colorSpecifier;
+ outline.offset = 0.5;
+
+ _trackStyles = [
+ new Position("relative"),
+ new HeightStyle(trackHeight),
+ new WidthStyle(trackWidth),
+ new BorderRadius("9999px"),
+ new BackgroundColor(uncheckedColor),
+ new Transition(),
+ new PeerPseudo([
+ new FocusVisibleState([outline]),
+ new CheckedState([
+ new
BackgroundColor(primaryColor)
+ ]),
+ new DisabledState([
+ new
BackgroundColor(disabledColor)
+ ])
+ ])
+ ];
+ }
+
+ private var _thumbStyles:Array;
+
+ public function get thumbStyles():Array
+ {
+ if(!_thumbStyles)
+ createThumbStyles();
+ return _thumbStyles;
+ }
+
+ public function set thumbStyles(value:Array):void
+ {
+ _thumbStyles = value;
+ }
+
+ private function createThumbStyles():void
+ {
+ var colorSet:ThemeColorSet =
ThemeManager.instance.activeTheme.themeColorSet;
+ var thumbColor:ColorSwatch =
colorSet.getSwatch(ThemeColorSet.BASE, 0);
+ var disabledThumbColor:ColorSwatch =
colorSet.getSwatch(ThemeColorSet.BASE, 100, 50);
+
+ var size:Number = 16 * getMultiplier();
+ var thumbSize:String = computeSize(size * 1.25,
host.unit);
+ var inset:String = computeSize(size * 0.125, host.unit);
+ var slideDistance:String = computeSize(size * 1.25,
host.unit);
+
+ var left:Left = new Left();
+ left.value = inset;
+
+ var top:Top = new Top();
+ top.value = inset;
+
+ var checkedTransform:Transform = new Transform();
+ checkedTransform.translateX = slideDistance;
+
+ _thumbStyles = [
+ new Position("absolute"),
+ left,
+ top,
+ new HeightStyle(thumbSize),
+ new WidthStyle(thumbSize),
+ new BorderRadius("9999px"),
+ new BackgroundColor(thumbColor),
+ new Transition(),
+ new GroupPseudo([
+ new DataState("checked",
[checkedTransform]),
+ new DataState("disabled", [
+ new
BackgroundColor(disabledThumbColor)
+ ])
+ ], host.getWrapperStyle())
+ ];
+ }
+
+ private var _labelStyles:Array;
+
+ public function get labelStyles():Array
+ {
+ if(!_labelStyles)
+ createLabelStyles();
+ return _labelStyles;
+ }
+
+ public function set labelStyles(value:Array):void
+ {
+ _labelStyles = value;
+ }
+
+ private function createLabelStyles():void
+ {
+ var size:Number = 16 * getMultiplier();
+ var fontSize:String = computeSize(size, host.unit);
+ var colorSet:ThemeColorSet =
ThemeManager.instance.activeTheme.themeColorSet;
+ var enabledColor:ColorSwatch = colorSet.baseContent;
+ var disabledColor:ColorSwatch =
colorSet.baseContentWeak;
+
+ _labelStyles = [
+ new FontSize(fontSize),
+ new TextColor(enabledColor),
+ new PeerPseudo([
+ new DisabledState([
+ new TextColor(disabledColor)
+ ])
+ ])
+ ];
+ }
+ }
+}