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 42a9822980 Added Menu
42a9822980 is described below

commit 42a9822980bd353dea49c4b319bbf7214affb3d3
Author: Yishay Weiss <[email protected]>
AuthorDate: Sun Apr 19 09:34:43 2026 +0300

    Added Menu
---
 examples/royale/TourDeStyle/README.md              |   2 +
 .../src/main/royale/MenuPlayGround.mxml            |  72 +++++++++++
 .../TourDeStyle/src/main/royale/TourDeStyle.mxml   |  19 +++
 .../projects/Style/src/main/resources/defaults.css |  16 +++
 .../Style/src/main/resources/style-manifest.xml    |   9 ++
 .../main/royale/org/apache/royale/style/Menu.as    |  58 +++++++++
 .../royale/org/apache/royale/style/MenuDetails.as  | 142 +++++++++++++++++++++
 .../royale/org/apache/royale/style/MenuItem.as     |  46 +++++++
 .../royale/org/apache/royale/style/MenuTitle.as    |  46 +++++++
 .../apache/royale/style/skins/IMenuDetailsSkin.as  |  29 +++++
 .../apache/royale/style/skins/MenuDetailsSkin.as   | 110 ++++++++++++++++
 .../org/apache/royale/style/skins/MenuItemSkin.as  |  69 ++++++++++
 .../org/apache/royale/style/skins/MenuSkin.as      |  90 +++++++++++++
 .../org/apache/royale/style/skins/MenuTitleSkin.as |  66 ++++++++++
 14 files changed, 774 insertions(+)

diff --git a/examples/royale/TourDeStyle/README.md 
b/examples/royale/TourDeStyle/README.md
index 5e7f7f6b71..fd6ce0111a 100644
--- a/examples/royale/TourDeStyle/README.md
+++ b/examples/royale/TourDeStyle/README.md
@@ -56,6 +56,7 @@ individually:
     ant -Dexample=TogglePlayGround
     ant -Dexample=DropdownPlayGround
     ant -Dexample=NavbarPlayGround
+    ant -Dexample=MenuPlayGround
 
 ### Debug-Only Build (faster)
 
@@ -84,3 +85,4 @@ After building, open `bin/js-debug/index.html` in a browser.
 | TogglePlayGround       | Toggle switches, checked and disabled states      |
 | DropdownPlayGround     | Dropdowns with programmatic and disabled states   |
 | NavbarPlayGround       | Navbar with start/center/end slot layout           |
+| MenuPlayGround         | Menu with titles, items, and links                 |
diff --git a/examples/royale/TourDeStyle/src/main/royale/MenuPlayGround.mxml 
b/examples/royale/TourDeStyle/src/main/royale/MenuPlayGround.mxml
new file mode 100644
index 0000000000..2f16007aa5
--- /dev/null
+++ b/examples/royale/TourDeStyle/src/main/royale/MenuPlayGround.mxml
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+  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.
+
+-->
+<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009";
+               xmlns:s="library://ns.apache.org/royale/style"
+               xmlns:e="library://ns.apache.org/royale/style-elements">
+
+    <s:initialView>
+    <s:View>
+    <s:FlexContainer vertical="true" gap="24">
+
+        <!-- Basic vertical menu -->
+        <e:Div text="Basic — A simple vertical menu with three items." />
+        <s:Menu>
+            <s:MenuItem><e:Span text="Item 1" /></s:MenuItem>
+            <s:MenuItem><e:Span text="Item 2" /></s:MenuItem>
+            <s:MenuItem><e:Span text="Item 3" /></s:MenuItem>
+        </s:Menu>
+
+        <!-- Menu with title -->
+        <e:Div text="With Title — Section headers group related menu items." />
+        <s:Menu>
+            <s:MenuTitle><e:Span text="General" /></s:MenuTitle>
+            <s:MenuItem><e:Span text="Dashboard" /></s:MenuItem>
+            <s:MenuItem><e:Span text="Settings" /></s:MenuItem>
+            <s:MenuTitle><e:Span text="Account" /></s:MenuTitle>
+            <s:MenuItem><e:Span text="Profile" /></s:MenuItem>
+            <s:MenuItem><e:Span text="Billing" /></s:MenuItem>
+        </s:Menu>
+
+        <!-- Menu with links -->
+        <e:Div text="With Links — Menu items containing clickable links." />
+        <s:Menu>
+            <s:MenuItem><e:A text="Features" href="#" /></s:MenuItem>
+            <s:MenuItem><e:A text="Pricing" href="#" /></s:MenuItem>
+            <s:MenuItem><e:A text="About" href="#" /></s:MenuItem>
+        </s:Menu>
+
+        <!-- Collapsible submenu -->
+        <e:Div text="Collapsible Submenu — Click 'Parent' to toggle the nested 
menu." />
+        <s:Menu>
+            <s:MenuItem><e:Span text="Item 1" /></s:MenuItem>
+            <s:MenuDetails headerText="Parent" open="true">
+                <s:Menu submenu="true">
+                    <s:MenuItem><e:Span text="Submenu 1" /></s:MenuItem>
+                    <s:MenuItem><e:Span text="Submenu 2" /></s:MenuItem>
+                </s:Menu>
+            </s:MenuDetails>
+            <s:MenuItem><e:Span text="Item 3" /></s:MenuItem>
+        </s:Menu>
+
+    </s:FlexContainer>
+    </s:View>
+    </s:initialView>
+
+</s:Application>
diff --git a/examples/royale/TourDeStyle/src/main/royale/TourDeStyle.mxml 
b/examples/royale/TourDeStyle/src/main/royale/TourDeStyle.mxml
index dad72434cb..402baa9929 100644
--- a/examples/royale/TourDeStyle/src/main/royale/TourDeStyle.mxml
+++ b/examples/royale/TourDeStyle/src/main/royale/TourDeStyle.mxml
@@ -32,6 +32,7 @@
                 modalSection.visible = (idx == 4);
                 paginationSection.visible = (idx == 5);
                 navbarSection.visible = (idx == 6);
+                menuSection.visible = (idx == 7);
             }
 
             private function openModal(id:String):void
@@ -57,6 +58,7 @@
                 <s:Tab text="Modal" />
                 <s:Tab text="Pagination" />
                 <s:Tab text="Navbar" />
+                <s:Tab text="Menu" />
             </s:tabs>
         </s:TabBar>
 
@@ -226,6 +228,23 @@
             </s:Navbar>
         </s:FlexContainer>
 
+        <!-- Menu Section -->
+        <s:FlexContainer id="menuSection" visible="false" gap="24" 
vertical="true">
+            <s:Menu>
+                <s:MenuItem><e:Span text="Item 1" /></s:MenuItem>
+                <s:MenuItem><e:Span text="Item 2" /></s:MenuItem>
+                <s:MenuItem><e:Span text="Item 3" /></s:MenuItem>
+            </s:Menu>
+            <s:Menu>
+                <s:MenuTitle><e:Span text="General" /></s:MenuTitle>
+                <s:MenuItem><e:Span text="Dashboard" /></s:MenuItem>
+                <s:MenuItem><e:Span text="Settings" /></s:MenuItem>
+                <s:MenuTitle><e:Span text="Account" /></s:MenuTitle>
+                <s:MenuItem><e:Span text="Profile" /></s:MenuItem>
+                <s:MenuItem><e:Span text="Billing" /></s:MenuItem>
+            </s:Menu>
+        </s:FlexContainer>
+
     </s:FlexContainer>
     </s:View>
     </s:initialView>
diff --git a/frameworks/projects/Style/src/main/resources/defaults.css 
b/frameworks/projects/Style/src/main/resources/defaults.css
index 9960cc19ac..ae64dfe46c 100644
--- a/frameworks/projects/Style/src/main/resources/defaults.css
+++ b/frameworks/projects/Style/src/main/resources/defaults.css
@@ -127,6 +127,22 @@ NavbarEnd
 {
        IStyleSkin: 
ClassReference("org.apache.royale.style.skins.NavbarEndSkin");
 }
+Menu
+{
+       IStyleSkin: ClassReference("org.apache.royale.style.skins.MenuSkin");
+}
+MenuItem
+{
+       IStyleSkin: 
ClassReference("org.apache.royale.style.skins.MenuItemSkin");
+}
+MenuTitle
+{
+       IStyleSkin: 
ClassReference("org.apache.royale.style.skins.MenuTitleSkin");
+}
+MenuDetails
+{
+       IStyleSkin: 
ClassReference("org.apache.royale.style.skins.MenuDetailsSkin");
+}
 
 DataItemRenderer
 {
diff --git a/frameworks/projects/Style/src/main/resources/style-manifest.xml 
b/frameworks/projects/Style/src/main/resources/style-manifest.xml
index 2ab488049d..2b2ce5c72d 100644
--- a/frameworks/projects/Style/src/main/resources/style-manifest.xml
+++ b/frameworks/projects/Style/src/main/resources/style-manifest.xml
@@ -46,6 +46,10 @@
   <component id="NavbarStart" class="org.apache.royale.style.NavbarStart"/>
   <component id="NavbarCenter" class="org.apache.royale.style.NavbarCenter"/>
   <component id="NavbarEnd" class="org.apache.royale.style.NavbarEnd"/>
+  <component id="Menu" class="org.apache.royale.style.Menu"/>
+  <component id="MenuItem" class="org.apache.royale.style.MenuItem"/>
+  <component id="MenuTitle" class="org.apache.royale.style.MenuTitle"/>
+  <component id="MenuDetails" class="org.apache.royale.style.MenuDetails"/>
   <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"/>
@@ -308,5 +312,10 @@
   <component id="NavbarStartSkin" 
class="org.apache.royale.style.skins.NavbarStartSkin"/>
   <component id="NavbarCenterSkin" 
class="org.apache.royale.style.skins.NavbarCenterSkin"/>
   <component id="NavbarEndSkin" 
class="org.apache.royale.style.skins.NavbarEndSkin"/>
+  <component id="MenuSkin" class="org.apache.royale.style.skins.MenuSkin"/>
+  <component id="MenuItemSkin" 
class="org.apache.royale.style.skins.MenuItemSkin"/>
+  <component id="MenuTitleSkin" 
class="org.apache.royale.style.skins.MenuTitleSkin"/>
+  <component id="MenuDetailsSkin" 
class="org.apache.royale.style.skins.MenuDetailsSkin"/>
+  <component id="IMenuDetailsSkin" 
class="org.apache.royale.style.skins.IMenuDetailsSkin"/>
 
 </componentPackage>
diff --git 
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/Menu.as 
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/Menu.as
new file mode 100644
index 0000000000..3364cc6198
--- /dev/null
+++ b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/Menu.as
@@ -0,0 +1,58 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.html.util.addElementToWrapper;
+       }
+
+       public class Menu extends Group
+       {
+               public function Menu()
+               {
+                       super();
+               }
+
+               private var _submenu:Boolean = false;
+
+               public function get submenu():Boolean
+               {
+                       return _submenu;
+               }
+
+               public function set submenu(value:Boolean):void
+               {
+                       _submenu = value;
+               }
+
+               COMPILE::JS
+               override protected function createElement():WrappedHTMLElement
+               {
+                       addElementToWrapper(this, 'ul');
+                       return element;
+               }
+
+               override public function getWrapperStyle():String
+               {
+                       return 'menu';
+               }
+       }
+}
diff --git 
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/MenuDetails.as
 
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/MenuDetails.as
new file mode 100644
index 0000000000..7848f9d5be
--- /dev/null
+++ 
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/MenuDetails.as
@@ -0,0 +1,142 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.html.util.addElementToWrapper;
+       }
+       import org.apache.royale.core.IChild;
+       import org.apache.royale.core.UIBase;
+       import org.apache.royale.events.Event;
+       import org.apache.royale.events.MouseEvent;
+       import org.apache.royale.style.elements.Summary;
+       import org.apache.royale.style.skins.IMenuDetailsSkin;
+       import org.apache.royale.style.IStyleUIBase;
+
+       [Event(name="openChanged", type="org.apache.royale.events.Event")]
+
+       public class MenuDetails extends Group
+       {
+               public function MenuDetails()
+               {
+                       super();
+               }
+
+               public function get headerText():String
+               {
+                       return headerElem.text;
+               }
+
+               public function set headerText(value:String):void
+               {
+                       headerElem.text = value;
+               }
+
+               private var _open:Boolean = false;
+
+               public function get open():Boolean
+               {
+                       return _open;
+               }
+
+               public function set open(value:Boolean):void
+               {
+                       if (value != _open)
+                       {
+                               _open = value;
+                               COMPILE::JS
+                               {
+                                       if (value)
+                                               
detailsElem.setAttribute("open", "");
+                                       else
+                                               
detailsElem.removeAttribute("open");
+                               }
+                               if (headerIcon)
+                               {
+                                       headerIcon.toggleAttribute("data-open", 
value);
+                               }
+                               dispatchEvent(new Event("openChanged"));
+                       }
+               }
+
+               private function toggleSection(ev:MouseEvent):void
+               {
+                       ev.stopPropagation();
+                       ev.preventDefault();
+                       open = !open;
+               }
+
+               protected var headerElem:Summary;
+
+               protected var headerIcon:IStyleUIBase;
+
+               COMPILE::JS
+               protected var detailsElem:HTMLElement;
+
+               /**
+                * @royaleignorecoercion 
org.apache.royale.style.skins.IMenuDetailsSkin
+                */
+               override protected function applySkin():void
+               {
+                       super.applySkin();
+                       if (skin is IMenuDetailsSkin)
+                       {
+                               headerElem.setStyles((skin as 
IMenuDetailsSkin).summaryStyles);
+                               var icon:IStyleUIBase = (skin as 
IMenuDetailsSkin).getIcon();
+                               if (icon)
+                               {
+                                       headerIcon = icon;
+                                       headerElem.addElement(headerIcon);
+                                       if (open)
+                                               
headerIcon.toggleAttribute("data-open", true);
+                               }
+                       }
+               }
+
+               override public function getWrapperStyle():String
+               {
+                       return 'menu-details';
+               }
+
+               COMPILE::JS
+               override protected function createElement():WrappedHTMLElement
+               {
+                       addElementToWrapper(this, 'li');
+
+                       detailsElem = document.createElement('details') as 
HTMLElement;
+                       element.appendChild(detailsElem);
+
+                       headerElem = new Summary();
+                       headerElem.text = '';
+                       headerElem.addEventListener("click", toggleSection);
+                       detailsElem.appendChild(headerElem.element);
+
+                       return element;
+               }
+
+               COMPILE::JS
+               override public function addElement(c:IChild, 
dispatchEvent:Boolean = true):void
+               {
+                       detailsElem.appendChild((c as UIBase).element);
+                       (c as UIBase).addedToParent();
+               }
+       }
+}
diff --git 
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/MenuItem.as 
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/MenuItem.as
new file mode 100644
index 0000000000..fb6bee2403
--- /dev/null
+++ 
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/MenuItem.as
@@ -0,0 +1,46 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.html.util.addElementToWrapper;
+       }
+
+       public class MenuItem extends Group
+       {
+               public function MenuItem()
+               {
+                       super();
+               }
+
+               COMPILE::JS
+               override protected function createElement():WrappedHTMLElement
+               {
+                       addElementToWrapper(this, 'li');
+                       return element;
+               }
+
+               override public function getWrapperStyle():String
+               {
+                       return 'menu-item';
+               }
+       }
+}
diff --git 
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/MenuTitle.as
 
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/MenuTitle.as
new file mode 100644
index 0000000000..29e7a9e4ab
--- /dev/null
+++ 
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/MenuTitle.as
@@ -0,0 +1,46 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.html.util.addElementToWrapper;
+       }
+
+       public class MenuTitle extends Group
+       {
+               public function MenuTitle()
+               {
+                       super();
+               }
+
+               COMPILE::JS
+               override protected function createElement():WrappedHTMLElement
+               {
+                       addElementToWrapper(this, 'li');
+                       return element;
+               }
+
+               override public function getWrapperStyle():String
+               {
+                       return 'menu-title';
+               }
+       }
+}
diff --git 
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/skins/IMenuDetailsSkin.as
 
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/skins/IMenuDetailsSkin.as
new file mode 100644
index 0000000000..6aa15c8b8c
--- /dev/null
+++ 
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/skins/IMenuDetailsSkin.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;
+       import org.apache.royale.style.IStyleUIBase;
+
+       public interface IMenuDetailsSkin extends IStyleSkin
+       {
+               function get summaryStyles():Array;
+               function getIcon():IStyleUIBase;
+       }
+}
diff --git 
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/skins/MenuDetailsSkin.as
 
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/skins/MenuDetailsSkin.as
new file mode 100644
index 0000000000..e83c9fff69
--- /dev/null
+++ 
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/skins/MenuDetailsSkin.as
@@ -0,0 +1,110 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.MenuDetails;
+       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.flexgrid.AlignItems;
+       import org.apache.royale.style.stylebeads.spacing.Padding;
+       import org.apache.royale.style.stylebeads.border.BorderRadius;
+       import org.apache.royale.style.stylebeads.interact.Cursor;
+       import org.apache.royale.style.stylebeads.states.HoverState;
+       import org.apache.royale.style.stylebeads.background.BackgroundColor;
+       import org.apache.royale.style.stylebeads.typography.ListStyleType;
+       import org.apache.royale.style.stylebeads.sizing.HeightStyle;
+       import org.apache.royale.style.stylebeads.sizing.WidthStyle;
+       import org.apache.royale.style.stylebeads.typography.TextColor;
+       import org.apache.royale.style.stylebeads.anim.Transition;
+       import org.apache.royale.style.stylebeads.anim.TransitionDuration;
+       import org.apache.royale.style.stylebeads.states.attribute.DataState;
+       import org.apache.royale.style.stylebeads.transform.Rotate;
+       import org.apache.royale.style.stylebeads.flexgrid.JustifyContent;
+       import org.apache.royale.style.Icon;
+       import org.apache.royale.style.IStyleUIBase;
+
+       public class MenuDetailsSkin extends StyleSkin implements 
IMenuDetailsSkin
+       {
+               public function MenuDetailsSkin()
+               {
+                       super();
+               }
+
+               private var _summaryStyles:Array;
+
+               /**
+                * @royaleignorecoercion org.apache.royale.style.MenuDetails
+                */
+               override public function set strand(value:IStrand):void
+               {
+                       var item:MenuDetails = value as MenuDetails;
+                       var colorSet:ThemeColorSet = 
ThemeManager.instance.activeTheme.themeColorSet;
+                       var hoverBg:ColorSwatch = 
colorSet.getSwatch(ThemeColorSet.BASE, 300);
+
+                       var padding:Padding = new Padding();
+                       padding.block = computeSize(8, item.unit);
+                       padding.inline = computeSize(12, item.unit);
+
+                       _summaryStyles = [
+                               new Display("flex"),
+                               new AlignItems("center"),
+                               new JustifyContent("space-between"),
+                               new ListStyleType("none"),
+                               padding,
+                               new BorderRadius(computeSize(8, item.unit)),
+                               new Cursor("pointer"),
+                               new HoverState([
+                                       new 
BackgroundColor(hoverBg.colorSpecifier)
+                               ])
+                       ];
+
+                       super.strand = value;
+               }
+
+               public function get summaryStyles():Array
+               {
+                       return _summaryStyles;
+               }
+
+               public function getIcon():IStyleUIBase
+               {
+                       var markup:XML = <svg viewBox="0 0 20 20" fill="none" 
stroke="currentColor" stroke-width="2"><path d="M7 5l5 5-5 5" 
stroke-linecap="round" stroke-linejoin="round"/></svg>
+                       var iconName:String = "menu-arrow-icon";
+                       Icon.registerIcon(iconName, markup);
+                       var colorSet:ThemeColorSet = 
ThemeManager.instance.activeTheme.themeColorSet;
+                       var textColor:ColorSwatch = 
colorSet.getSwatch(ThemeColorSet.BASE, 500);
+                       var icon:Icon = new Icon(iconName);
+                       icon.styleBeads = [
+                               new HeightStyle(4),
+                               new WidthStyle(4),
+                               new TextColor(textColor),
+                               new Transition("transform"),
+                               new TransitionDuration(200),
+                               new DataState("open", [
+                                       new Rotate(90)
+                               ])
+                       ];
+                       return icon;
+               }
+       }
+}
diff --git 
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/skins/MenuItemSkin.as
 
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/skins/MenuItemSkin.as
new file mode 100644
index 0000000000..a787114fac
--- /dev/null
+++ 
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/skins/MenuItemSkin.as
@@ -0,0 +1,69 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.MenuItem;
+       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.flexgrid.AlignItems;
+       import org.apache.royale.style.stylebeads.spacing.Padding;
+       import org.apache.royale.style.stylebeads.border.BorderRadius;
+       import org.apache.royale.style.stylebeads.interact.Cursor;
+       import org.apache.royale.style.stylebeads.states.HoverState;
+       import org.apache.royale.style.stylebeads.background.BackgroundColor;
+
+       public class MenuItemSkin extends StyleSkin
+       {
+               public function MenuItemSkin()
+               {
+                       super();
+               }
+
+               /**
+                * @royaleignorecoercion org.apache.royale.style.MenuItem
+                */
+               override public function set strand(value:IStrand):void
+               {
+                       var item:MenuItem = value as MenuItem;
+                       var colorSet:ThemeColorSet = 
ThemeManager.instance.activeTheme.themeColorSet;
+                       var hoverBg:ColorSwatch = 
colorSet.getSwatch(ThemeColorSet.BASE, 300);
+
+                       var padding:Padding = new Padding();
+                       padding.block = computeSize(8, item.unit);
+                       padding.inline = computeSize(12, item.unit);
+
+                       _styles = [
+                               new Display("flex"),
+                               new AlignItems("center"),
+                               padding,
+                               new BorderRadius(computeSize(8, item.unit)),
+                               new Cursor("pointer"),
+                               new HoverState([
+                                       new 
BackgroundColor(hoverBg.colorSpecifier)
+                               ])
+                       ];
+
+                       super.strand = value;
+               }
+       }
+}
diff --git 
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/skins/MenuSkin.as
 
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/skins/MenuSkin.as
new file mode 100644
index 0000000000..1160506809
--- /dev/null
+++ 
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/skins/MenuSkin.as
@@ -0,0 +1,90 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.Menu;
+       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.flexgrid.FlexDirection;
+       import org.apache.royale.style.stylebeads.flexgrid.Gap;
+       import org.apache.royale.style.stylebeads.spacing.Padding;
+       import org.apache.royale.style.stylebeads.spacing.Margin;
+       import org.apache.royale.style.stylebeads.background.BackgroundColor;
+       import org.apache.royale.style.stylebeads.border.Border;
+       import org.apache.royale.style.stylebeads.border.BorderRadius;
+
+       public class MenuSkin extends StyleSkin
+       {
+               public function MenuSkin()
+               {
+                       super();
+               }
+
+               /**
+                * @royaleignorecoercion org.apache.royale.style.Menu
+                */
+               override public function set strand(value:IStrand):void
+               {
+                       var menu:Menu = value as Menu;
+                       var colorSet:ThemeColorSet = 
ThemeManager.instance.activeTheme.themeColorSet;
+
+                       _styles = [
+                               new Display("flex"),
+                               new FlexDirection("column"),
+                               new Gap(computeSize(2, menu.unit))
+                       ];
+
+                       if (menu.submenu)
+                       {
+                               var borderColor:ColorSwatch = 
colorSet.getSwatch(ThemeColorSet.BASE, 300);
+
+                               var border:Border = new Border();
+                               border.leftColor = borderColor.colorSpecifier;
+                               border.style = "solid";
+                               border.width = computeSize(1, menu.unit);
+
+                               var margin:Margin = new Margin();
+                               margin.left = computeSize(16, menu.unit);
+                               margin.top = computeSize(2, menu.unit);
+
+                               _styles.push(border, margin);
+                       }
+                       else
+                       {
+                               var bgColor:ColorSwatch = 
colorSet.getSwatch(ThemeColorSet.BASE, 200);
+
+                               var padding:Padding = new Padding();
+                               padding.block = computeSize(8, menu.unit);
+                               padding.inline = computeSize(8, menu.unit);
+
+                               _styles.push(
+                                       padding,
+                                       new 
BackgroundColor(bgColor.colorSpecifier),
+                                       new BorderRadius(computeSize(12, 
menu.unit))
+                               );
+                       }
+
+                       super.strand = value;
+               }
+       }
+}
diff --git 
a/frameworks/projects/Style/src/main/royale/org/apache/royale/style/skins/MenuTitleSkin.as
 
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/skins/MenuTitleSkin.as
new file mode 100644
index 0000000000..d931af8561
--- /dev/null
+++ 
b/frameworks/projects/Style/src/main/royale/org/apache/royale/style/skins/MenuTitleSkin.as
@@ -0,0 +1,66 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.MenuTitle;
+       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.spacing.Padding;
+       import org.apache.royale.style.stylebeads.typography.FontSize;
+       import org.apache.royale.style.stylebeads.typography.FontWeight;
+       import org.apache.royale.style.stylebeads.typography.TextColor;
+       import org.apache.royale.style.stylebeads.typography.TextTransform;
+       import org.apache.royale.style.stylebeads.typography.LetterSpacing;
+
+       public class MenuTitleSkin extends StyleSkin
+       {
+               public function MenuTitleSkin()
+               {
+                       super();
+               }
+
+               /**
+                * @royaleignorecoercion org.apache.royale.style.MenuTitle
+                */
+               override public function set strand(value:IStrand):void
+               {
+                       var title:MenuTitle = value as MenuTitle;
+                       var colorSet:ThemeColorSet = 
ThemeManager.instance.activeTheme.themeColorSet;
+                       var mutedColor:ColorSwatch = 
colorSet.getSwatch(ThemeColorSet.BASE, 500);
+
+                       var padding:Padding = new Padding();
+                       padding.block = computeSize(4, title.unit);
+                       padding.inline = computeSize(12, title.unit);
+
+                       _styles = [
+                               padding,
+                               new FontSize(computeSize(12, title.unit)),
+                               new FontWeight("bold"),
+                               new TextTransform("uppercase"),
+                               new LetterSpacing(computeSize(1, title.unit)),
+                               new TextColor(mutedColor.colorSpecifier)
+                       ];
+
+                       super.strand = value;
+               }
+       }
+}


Reply via email to