You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by hn...@apache.org on 2026/04/15 11:48:20 UTC

(myfaces-tobago) branch main updated (37c1f20962 -> 9bae705544)

This is an automated email from the ASF dual-hosted git repository.

hnoeth pushed a change to branch main
in repository https://gitbox.apache.org/repos/asf/myfaces-tobago.git


    from 37c1f20962 build(deps-dev): bump org.seleniumhq.selenium:selenium-java (#7232)
     new 4ef87c3a88 refactor(demo): navigation
     new 9bae705544 build(theme): rebuild

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../src/main/scss/demo-navigation.scss             |  70 ++++++
 .../tobago-example-demo/src/main/scss/demo.scss    |  51 +---
 .../tobago-example-demo/src/main/ts/demo-all.ts    |   1 +
 .../src/main/ts/demo-navigation.ts                 |  74 ++++++
 .../src/main/webapp/css/demo.css                   |  76 +++---
 .../src/main/webapp/css/demo.css.map               |   2 +-
 .../src/main/webapp/css/demo.min.css               |   2 +-
 .../src/main/webapp/css/demo.min.css.map           |   2 +-
 .../src/main/webapp/js/demo-all.js                 |   1 +
 .../src/main/webapp/js/demo-all.js.map             |   2 +-
 .../src/main/webapp/js/demo-navigation.js          |  65 +++++
 .../src/main/webapp/js/demo-navigation.js.map      |   1 +
 .../tobago-example-demo/src/main/webapp/js/demo.js |  65 +++++
 .../src/main/webapp/js/demo.js.map                 |   2 +-
 .../tobago-example-demo/src/main/webapp/main.xhtml |  72 +++---
 .../tobago-example-demo/src/main/webapp/menu.xhtml | 272 +++++++++++----------
 .../tobago-theme-standard/src/main/js/tobago.js    |   4 +-
 .../src/main/js/tobago.js.map                      |   2 +-
 18 files changed, 507 insertions(+), 257 deletions(-)
 create mode 100644 tobago-example/tobago-example-demo/src/main/scss/demo-navigation.scss
 create mode 100644 tobago-example/tobago-example-demo/src/main/ts/demo-navigation.ts
 create mode 100644 tobago-example/tobago-example-demo/src/main/webapp/js/demo-navigation.js
 create mode 100644 tobago-example/tobago-example-demo/src/main/webapp/js/demo-navigation.js.map


(myfaces-tobago) 01/02: refactor(demo): navigation

Posted by hn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

hnoeth pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/myfaces-tobago.git

commit 4ef87c3a8802acfed3167151382bd1b8042324c6
Author: Henning Noeth <hn...@apache.org>
AuthorDate: Tue Apr 14 14:36:51 2026 +0200

    refactor(demo): navigation
---
 .../src/main/scss/demo-navigation.scss             |  70 ++++++
 .../tobago-example-demo/src/main/scss/demo.scss    |  51 +---
 .../tobago-example-demo/src/main/ts/demo-all.ts    |   1 +
 .../src/main/ts/demo-navigation.ts                 |  74 ++++++
 .../tobago-example-demo/src/main/webapp/main.xhtml |  72 +++---
 .../tobago-example-demo/src/main/webapp/menu.xhtml | 272 +++++++++++----------
 6 files changed, 319 insertions(+), 221 deletions(-)

diff --git a/tobago-example/tobago-example-demo/src/main/scss/demo-navigation.scss b/tobago-example/tobago-example-demo/src/main/scss/demo-navigation.scss
new file mode 100644
index 0000000000..a28d64c0cc
--- /dev/null
+++ b/tobago-example/tobago-example-demo/src/main/scss/demo-navigation.scss
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+
+.navigation {
+  tobago-tree-node[data-tobago-level='0'] {
+    font-weight: bold;
+    margin-top: 1rem;
+    white-space: nowrap;
+
+    &[index='1'] {
+      margin-top: 0;
+    }
+  }
+
+  tobago-tree-node {
+    &[data-tobago-level='1'],
+    &[data-tobago-level='2'],
+    &[data-tobago-level='3'],
+    &[data-tobago-level='4'],
+    &[data-tobago-level='5'] {
+      a {
+        padding: 0.25rem;
+        color: var(--bs-secondary);
+        border-radius: var(--bs-border-radius);
+
+        &:hover {
+          background-color: rgba(var(--bs-secondary-rgb), 0.1);
+        }
+
+        &.active {
+          color: var(--bs-primary);
+          background-color: rgba(var(--bs-primary-rgb), 0.1);
+        }
+      }
+    }
+  }
+
+  tobago-tree-node {
+    &[data-tobago-level='2'],
+    &[data-tobago-level='3'],
+    &[data-tobago-level='4'],
+    &[data-tobago-level='5'] {
+      a {
+        font-size: small;
+      }
+    }
+  }
+}
+
+.navigation-expanded {
+  display: block;
+  position: sticky;
+  top: calc(56px + 1rem); //height of header is 56px
+  height: calc(100vh - 56px - 40px - 2rem); //height of footer is 40px
+  overflow-y: auto;
+}
diff --git a/tobago-example/tobago-example-demo/src/main/scss/demo.scss b/tobago-example/tobago-example-demo/src/main/scss/demo.scss
index a7daaecaa8..3de3781d6b 100644
--- a/tobago-example/tobago-example-demo/src/main/scss/demo.scss
+++ b/tobago-example/tobago-example-demo/src/main/scss/demo.scss
@@ -15,62 +15,13 @@
  * limitations under the License.
  */
 
+@import "demo-navigation";
 @import "demo-sidebar";
 
 html {
   scroll-padding-top: 72px;
 }
 
-#page\:navigation\:nav, #page\:navigation-small\:nav-small {
-  tobago-tree-node[data-tobago-level='0'] {
-    font-weight: bold;
-    margin-top: 1rem;
-    white-space: nowrap;
-
-    &[index='1'] {
-      margin-top: 0;
-    }
-  }
-
-  tobago-tree-node {
-    &[data-tobago-level='1'],
-    &[data-tobago-level='2'],
-    &[data-tobago-level='3'],
-    &[data-tobago-level='4'],
-    &[data-tobago-level='5'] {
-      a {
-        padding: 0.25rem;
-        color: var(--bs-secondary);
-        border-radius: var(--bs-border-radius);
-
-        &:hover {
-          background-color: rgba(var(--bs-secondary-rgb), 0.1);
-        }
-
-        &.active {
-          color: var(--bs-primary);
-          background-color: rgba(var(--bs-primary-rgb), 0.1);
-        }
-      }
-    }
-  }
-
-  tobago-tree-node {
-    &[data-tobago-level='2'],
-    &[data-tobago-level='3'],
-    &[data-tobago-level='4'],
-    &[data-tobago-level='5'] {
-      a {
-        font-size: small;
-      }
-    }
-  }
-}
-
-.hide-navigation {
-  display: none;
-}
-
 .navigation-box {
   --bs-card-border-radius: 0;
   border: none;
diff --git a/tobago-example/tobago-example-demo/src/main/ts/demo-all.ts b/tobago-example/tobago-example-demo/src/main/ts/demo-all.ts
index 049755b3a3..90c2ddddf9 100644
--- a/tobago-example/tobago-example-demo/src/main/ts/demo-all.ts
+++ b/tobago-example/tobago-example-demo/src/main/ts/demo-all.ts
@@ -21,5 +21,6 @@ import "./demo-date";
 import "./demo-highlight";
 import "./demo-inspect";
 import "./demo-login";
+import "./demo-navigation";
 import "./demo-sidebar";
 import "./demo-test";
diff --git a/tobago-example/tobago-example-demo/src/main/ts/demo-navigation.ts b/tobago-example/tobago-example-demo/src/main/ts/demo-navigation.ts
new file mode 100644
index 0000000000..c300769600
--- /dev/null
+++ b/tobago-example/tobago-example-demo/src/main/ts/demo-navigation.ts
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ */
+
+export class Navigation extends HTMLElement {
+  private headerResizeObserver: ResizeObserver;
+  private footerResizeObserver: ResizeObserver;
+
+  connectedCallback(): void {
+    if (this.fixedHeader) {
+      this.headerResizeObserver = new ResizeObserver(() => this.updatePositionAndSize());
+      this.headerResizeObserver.observe(this.fixedHeader);
+    }
+    if (this.fixedFooter) {
+      this.footerResizeObserver = new ResizeObserver(() => this.updatePositionAndSize());
+      this.footerResizeObserver.observe(this.fixedFooter);
+    }
+    this.updatePositionAndSize();
+    this.activeLink?.scrollIntoView({block: "center"});
+  }
+
+  disconnectedCallback(): void {
+    this.headerResizeObserver?.disconnect();
+    this.footerResizeObserver?.disconnect();
+  }
+
+  private updatePositionAndSize(): void {
+    const headerHeight = this.fixedHeader.offsetHeight;
+    const footerHeight = this.fixedFooter.offsetHeight;
+
+    this.navigationExpanded.style.top = "calc(" + headerHeight + " + 1rem)";
+    this.navigationExpanded.style.height = "calc(100vh - " + headerHeight + " - " + footerHeight + " - 2rem)";
+  }
+
+  get navigationExpanded(): HTMLElement {
+    const rootNode = this.getRootNode() as ShadowRoot | Document;
+    return rootNode.querySelector<HTMLElement>("tobago-panel.navigation-expanded");
+  }
+
+  get fixedHeader(): HTMLElement {
+    const rootNode = this.getRootNode() as ShadowRoot | Document;
+    return rootNode.querySelector<HTMLElement>("tobago-header.sticky-top");
+  }
+
+  get fixedFooter(): HTMLElement | null {
+    const rootNode = this.getRootNode() as ShadowRoot | Document;
+    return rootNode.querySelector<HTMLElement>("tobago-footer.fixed-bottom");
+  }
+
+  get activeLink(): HTMLElement {
+    return this.querySelector(".tobago-link.active");
+  }
+}
+
+if (typeof window !== "undefined") {
+  window.addEventListener("DOMContentLoaded", function (): void {
+    if (!window.customElements.get("demo-navigation")) {
+      window.customElements.define("demo-navigation", Navigation);
+    }
+  });
+}
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/main.xhtml b/tobago-example/tobago-example-demo/src/main/webapp/main.xhtml
index 68b8c2e8d0..c07d6ecfc1 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/main.xhtml
+++ b/tobago-example/tobago-example-demo/src/main/webapp/main.xhtml
@@ -19,14 +19,13 @@
 
 <!-- main template for this demo application, you may also use plain.xhtml for test purpose -->
 
-<ui:composition
-        xmlns:f="jakarta.faces.core"
-        xmlns:tc="http://myfaces.apache.org/tobago/component"
-        xmlns:ui="jakarta.faces.facelets"
-        xmlns="http://www.w3.org/1999/xhtml">
+<ui:composition xmlns="http://www.w3.org/1999/xhtml"
+                xmlns:f="jakarta.faces.core"
+                xmlns:tc="http://myfaces.apache.org/tobago/component"
+                xmlns:ui="jakarta.faces.facelets">
   <f:view locale="#{localeController.locale}">
 
-<!-- XXX doesn't work, why? it does work, when uidefine with metatag is at the specific page -->
+    <!-- XXX doesn't work, why? it does work, when uidefine with metatag is at the specific page -->
     <!--
     <f:metadata>
       <f:importConstants type="org.apache.myfaces.tobago.renderkit.css.Icons" var="bi"/>
@@ -52,40 +51,37 @@
 
       <ui:include src="/menu.xhtml"/>
 
-      <tc:box label="Menu" id="small-view-menu" collapsed="true" collapsedMode="hidden">
-          <f:facet name="bar">
-            <tc:buttons>
-              <tc:button id="show-menu" icon="bi-arrow-bar-down" omit="true">
-                <tc:operation name="show" for="small-view-menu"/>
-              </tc:button>
-              <tc:button id="hide-menu" icon="bi-arrow-bar-up" omit="true">
-                <tc:operation name="hide" for="small-view-menu"/>
-              </tc:button>
-            </tc:buttons>
-          </f:facet>
-          <tc:style customClass="scrollableBox d-block d-lg-none navigation-box"/>
-          <tc:style overflowY="scroll" height="20rem" selector=".scrollableBox .card-body"/>
-          <tc:panel id="clientPanel" collapsedMode="hidden">
-            <ui:include src="/navigation.xhtml">
-              <ui:param name="navigationName" value="navigation-small"/>
-              <ui:param name="navigationId" value="nav-small"/>
-              <ui:param name="linkId" value="cmd-small"/>
-            </ui:include>
-          </tc:panel>
-      </tc:box>
+      <tc:offcanvas id="menuOffcanvas" collapsedMode="hidden">
+        <f:facet name="label">Navigation</f:facet>
+        <f:facet name="bar">
+          <tc:link icon="bi-x-lg" omit="true">
+            <tc:operation name="hide" for="menuOffcanvas"/>
+          </tc:link>
+        </f:facet>
+        <tc:panel>
+          <tc:style customClass="navigation"/>
+          <ui:include src="/navigation.xhtml">
+            <ui:param name="navigationName" value="navigation-small"/>
+            <ui:param name="navigationId" value="nav-small"/>
+            <ui:param name="linkId" value="cmd-small"/>
+          </ui:include>
+        </tc:panel>
+      </tc:offcanvas>
 
       <tc:panel>
         <tc:style customClass="#{navigationState.viewSource ? '' : 'container-lg'}"/>
 
-        <tc:segmentLayout  large="2seg 8seg 2seg">
+        <tc:flexLayout columns="215px 1fr 200px">
           <f:event type="preRenderView" listener="#{navigationState.sync}"/>
           <tc:panel>
-            <tc:style customClass="d-lg-block hide-navigation"/>
-            <ui:include src="/navigation.xhtml">
-              <ui:param name="navigationName" value="navigation"/>
-              <ui:param name="navigationId" value="nav"/>
-              <ui:param name="linkId" value="cmd"/>
-            </ui:include>
+            <tc:style customClass="d-none d-lg-block navigation navigation-expanded" flexShrink="0"/>
+            <demo-navigation>
+              <ui:include src="/navigation.xhtml">
+                <ui:param name="navigationName" value="navigation"/>
+                <ui:param name="navigationId" value="nav"/>
+                <ui:param name="linkId" value="cmd"/>
+              </ui:include>
+            </demo-navigation>
           </tc:panel>
 
           <tc:splitLayout columns="1fr">
@@ -108,16 +104,16 @@
             </tc:panel>
           </tc:splitLayout>
           <tc:panel>
-            <tc:style customClass="d-lg-block" display="none"/>
+            <tc:style customClass="d-lg-block" display="none" flexShrink="0"/>
             <demo-sidebar id="sidebar" tabindex="-1"/>
           </tc:panel>
-        </tc:segmentLayout>
+        </tc:flexLayout>
       </tc:panel>
 
       <tc:popup id="info" collapsedMode="hidden">
         <tc:box label="Client Information">
           <f:facet name="bar">
-<!--            <tc:button image="#{fa.CLOSE.name}">-->
+            <!--            <tc:button image="#{fa.CLOSE.name}">-->
             <tc:button icon="bi-x-lg">
               <tc:operation name="hide" for="info"/>
             </tc:button>
@@ -131,7 +127,7 @@
 
       <tc:footer fixed="true">
         © 2005-2026 Apache Software Foundation, Licensed under the <a
-              href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.
+          href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.
       </tc:footer>
 
     </tc:page>
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/menu.xhtml b/tobago-example/tobago-example-demo/src/main/webapp/menu.xhtml
index 34f77c7603..4d9de6950e 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/menu.xhtml
+++ b/tobago-example/tobago-example-demo/src/main/webapp/menu.xhtml
@@ -18,148 +18,154 @@
 -->
 
 <tc:header fixed="true"
-           xmlns:tc="http://myfaces.apache.org/tobago/component"
-           xmlns:f="jakarta.faces.core">
+           xmlns:f="jakarta.faces.core"
+           xmlns:tc="http://myfaces.apache.org/tobago/component">
 
   <!-- tbd: how to solve this? -->
 
-<!--
-  <tc:flexLayout columns="auto 1fr" alignItems="center">
-
-    <tc:image value="image/feather-leaf.png"/>
--->
-
-    <tc:bar id="bar" markup="togglerLeft, light, large">
-      <tc:style customClass="bg-light box-shadow"/>
-      <f:facet name="brand">
-        <!-- label="Tobago Demo" contains a NO-BREAK SPACE character -->
-        <tc:image value="#{request.contextPath}/image/feather.svg">
-          <tc:style width="1.25rem" height="1.875rem" marginRight="0.5rem"/>
-        </tc:image>
-        <tc:link label="Tobago Demo" id="brand" link="#{request.contextPath}/"/>
-      </f:facet>
-
-      <tc:form id="header">
-        <tc:links id="commands">
-          <tc:link id="config" label="Configuration" omit="true">
-            <tc:link label="Theme" omit="true">
-              <tc:selectOneRadio value="#{themeController.theme}">
-                <tc:event action="#{themeController.submit}"/>
-                <tc:selectItems value="#{themeController.themeItems}"/>
-              </tc:selectOneRadio>
-            </tc:link>
-            <tc:link label="Locale" omit="true">
-              <tc:selectOneRadio value="#{localeController.locale}">
-                <tc:event action="#{localeController.submit}"/>
-                <tc:selectItems value="#{localeController.localeItems}"/>
-              </tc:selectOneRadio>
-            </tc:link>
-            <tc:link outcome="/login.xhtml" label="Login" rendered="#{request.userPrincipal == null}"/>
-            <tc:link action="#{loginController.logout}" label="Logout '#{request.userPrincipal.name}'" rendered="#{request.userPrincipal != null}"/>
-            <tc:link action="#{loginController.resetSession}" label="Reset Session"/>
+  <!--
+    <tc:flexLayout columns="auto 1fr" alignItems="center">
+
+      <tc:image value="image/feather-leaf.png"/>
+  -->
+
+  <tc:bar id="bar" markup="togglerRight light large">
+    <tc:style customClass="bg-light box-shadow"/>
+    <f:facet name="brand">
+      <tc:button icon="bi bi-menu-app" omit="true">
+        <tc:style customClass="d-lg-none" marginRight="1em"/>
+        <tc:operation for="menuOffcanvas" name="show"/>
+      </tc:button>
+
+      <!-- label="Tobago Demo" contains a NO-BREAK SPACE character -->
+      <tc:image value="#{request.contextPath}/image/feather.svg">
+        <tc:style width="1.25rem" height="1.875rem" marginRight="0.5rem"/>
+      </tc:image>
+      <tc:link label="Tobago Demo" id="brand" link="#{request.contextPath}/"/>
+    </f:facet>
+
+    <tc:form id="header">
+      <tc:links id="commands">
+        <tc:link id="config" label="Configuration" omit="true">
+          <tc:link label="Theme" omit="true">
+            <tc:selectOneRadio value="#{themeController.theme}">
+              <tc:event action="#{themeController.submit}"/>
+              <tc:selectItems value="#{themeController.themeItems}"/>
+            </tc:selectOneRadio>
           </tc:link>
-
-          <tc:link label="Test" omit="true">
-            <tc:link id="runtest" label="Run test" outcome="/test.xhtml"
-                     immediate="true" disabled="#{!testController.hasTest()}">
-              <f:param name="base" value="#{testController.base}"/>
-            </tc:link>
-            <tc:link label="Run all tests" outcome="/testAll.xhtml" target="_blank"
-                     immediate="true" rendered="#{facesContext.isProjectStage('Development')}"/>
-            <tc:link label="Access all pages" outcome="/testAccessAllPages.xhtml" target="_blank"
-                     immediate="true" rendered="#{facesContext.isProjectStage('Development')}"/>
-            <tc:link label="Goto test section" action="#{navigationState.gotoTestSection}"
-                     immediate="true" rendered="#{!navigationState.showTestSection}"/>
-            <tc:link label="Deactivate test section" action="#{navigationState.deactivateTestSection}"
-                     immediate="true" rendered="#{navigationState.showTestSection}"/>
+          <tc:link label="Locale" omit="true">
+            <tc:selectOneRadio value="#{localeController.locale}">
+              <tc:event action="#{localeController.submit}"/>
+              <tc:selectItems value="#{localeController.localeItems}"/>
+            </tc:selectOneRadio>
           </tc:link>
-
-          <tc:link label="Menu" omit="true">
-
-<!--            <demo-alert value="Demo Message">-->
-              <!-- XXX demo-alert not working -->
-              <tc:link label="Menu Item" omit="true" id="menu_item"/>
-<!--            </demo-alert>-->
-            <tc:separator/>
-            <tc:link label="Sub Menu" omit="true">
-              <tc:link label="Sub 1" omit="true"/>
-              <tc:link label="Sub 2" omit="true"/>
-              <tc:link label="Sub 3" omit="true"/>
-              <tc:link action="doit" label="Sub 4" omit="true">
-                <tc:link label="Sub 4 1" omit="true"/>
-                <tc:link label="Sub 4 2" omit="true"/>
-                <tc:link label="Sub 4 3" omit="true"/>
-              </tc:link>
-              <tc:link label="Sub 5" omit="true">
-                <tc:link label="Sub 5 1" omit="true"/>
-                <tc:link label="Sub 5 2" omit="true"/>
-              </tc:link>
-            </tc:link>
+          <tc:link outcome="/login.xhtml" label="Login" rendered="#{request.userPrincipal == null}"/>
+          <tc:link action="#{loginController.logout}" label="Logout '#{request.userPrincipal.name}'"
+                   rendered="#{request.userPrincipal != null}"/>
+          <tc:link action="#{loginController.resetSession}" label="Reset Session"/>
+        </tc:link>
+
+        <tc:link label="Test" omit="true">
+          <tc:link id="runtest" label="Run test" outcome="/test.xhtml"
+                   immediate="true" disabled="#{!testController.hasTest()}">
+            <f:param name="base" value="#{testController.base}"/>
           </tc:link>
-
-          <tc:link label="Info" omit="true">
-            <tc:link label="Tobago Demo - #{serverInfo.version}" omit="true" disabled="true"/>
-            <!-- XXX demo-alert not working -->
-            <!--
-            <d emo-alert value="Demo Message">
-            <tc:link label="About" omit="true">
-              <tc:dataAttribute name="alert-text" value="Tobago Demo - #{serverInfo.version}"/>
+          <tc:link label="Run all tests" outcome="/testAll.xhtml" target="_blank"
+                   immediate="true" rendered="#{facesContext.isProjectStage('Development')}"/>
+          <tc:link label="Access all pages" outcome="/testAccessAllPages.xhtml" target="_blank"
+                   immediate="true" rendered="#{facesContext.isProjectStage('Development')}"/>
+          <tc:link label="Goto test section" action="#{navigationState.gotoTestSection}"
+                   immediate="true" rendered="#{!navigationState.showTestSection}"/>
+          <tc:link label="Deactivate test section" action="#{navigationState.deactivateTestSection}"
+                   immediate="true" rendered="#{navigationState.showTestSection}"/>
+        </tc:link>
+
+        <tc:link label="Menu" omit="true">
+
+          <!--            <demo-alert value="Demo Message">-->
+          <!-- XXX demo-alert not working -->
+          <tc:link label="Menu Item" omit="true" id="menu_item"/>
+          <!--            </demo-alert>-->
+          <tc:separator/>
+          <tc:link label="Sub Menu" omit="true">
+            <tc:link label="Sub 1" omit="true"/>
+            <tc:link label="Sub 2" omit="true"/>
+            <tc:link label="Sub 3" omit="true"/>
+            <tc:link action="doit" label="Sub 4" omit="true">
+              <tc:link label="Sub 4 1" omit="true"/>
+              <tc:link label="Sub 4 2" omit="true"/>
+              <tc:link label="Sub 4 3" omit="true"/>
             </tc:link>
-            </d emo-alert>
--->
-            <tc:link omit="true" label="Client Info" id="headerInfo">
-              <tc:operation name="show" for=":::info"/>
+            <tc:link label="Sub 5" omit="true">
+              <tc:link label="Sub 5 1" omit="true"/>
+              <tc:link label="Sub 5 2" omit="true"/>
             </tc:link>
-            <tc:link outcome="/content/000-intro/93-server-info/Server_Info.xhtml" immediate="true" label="Server Info"
-                     disabled="#{! serverInfo.enabled}"/>
-            <tc:link outcome="/content/000-intro/96-logging-info/Logging_Info.xhtml" immediate="true" label="Logging Info"
-                     disabled="#{! serverInfo.enabled}"/>
-            <tc:separator/>
-            <tc:link link="https://myfaces.apache.org/#/tobago" label="Tobago Project" icon="bi-box-arrow-up-right"/>
-            <tc:link link="https://tobago-demo.apache.org/" label="Demo Overview" icon="bi-box-arrow-up-right"/>
           </tc:link>
-
-        </tc:links>
-
-      </tc:form>
-
-      <f:facet name="after">
-        <tc:flexLayout columns="auto auto">
-          <tc:form id="searchForm">
-            <tc:flexLayout columns="200px auto">
-              <tc:in placeholder="Search" required="true" value="#{navigationState.searchString}" labelLayout="none"
-              label="Search" id="search">
-                <f:facet name="after">
-                  <tc:button label="go" action="#{navigationState.search}" defaultCommand="true"/>
-                </f:facet>
-              </tc:in>
-            </tc:flexLayout>
-          </tc:form>
-          <tc:form id="navbtns">
-            <tc:flexLayout columns="auto auto">
-              <tc:buttons>
-                <tc:button immediate="true" id="previous"
-                           icon="bi-chevron-left"
-                           action="#{navigationState.gotoPrevious}"
-                           disabled="#{navigationState.first}"
-                           tip="Previous"/>
-                <tc:button immediate="true" id="next"
-                           icon="bi-chevron-right"
-                           action="#{navigationState.gotoNext}"
-                           disabled="#{navigationState.last}"
-                           tip="Next"/>
-              </tc:buttons>
-              <tc:button action="#{navigationState.toggleViewSource}"
-                         icon="bi-code-slash"
-                         immediate="true" tip="View Source"/>
-            </tc:flexLayout>
-          </tc:form>
-        </tc:flexLayout>
-      </f:facet>
-    </tc:bar>
-
-<!--
-  </tc:flexLayout>
+        </tc:link>
+
+        <tc:link label="Info" omit="true">
+          <tc:link label="Tobago Demo - #{serverInfo.version}" omit="true" disabled="true"/>
+          <!-- XXX demo-alert not working -->
+          <!--
+          <d emo-alert value="Demo Message">
+          <tc:link label="About" omit="true">
+            <tc:dataAttribute name="alert-text" value="Tobago Demo - #{serverInfo.version}"/>
+          </tc:link>
+          </d emo-alert>
 -->
+          <tc:link omit="true" label="Client Info" id="headerInfo">
+            <tc:operation name="show" for=":::info"/>
+          </tc:link>
+          <tc:link outcome="/content/000-intro/93-server-info/Server_Info.xhtml" immediate="true" label="Server Info"
+                   disabled="#{! serverInfo.enabled}"/>
+          <tc:link outcome="/content/000-intro/96-logging-info/Logging_Info.xhtml" immediate="true" label="Logging Info"
+                   disabled="#{! serverInfo.enabled}"/>
+          <tc:separator/>
+          <tc:link link="https://myfaces.apache.org/#/tobago" label="Tobago Project" icon="bi-box-arrow-up-right"/>
+          <tc:link link="https://tobago-demo.apache.org/" label="Demo Overview" icon="bi-box-arrow-up-right"/>
+        </tc:link>
+
+      </tc:links>
+
+    </tc:form>
+
+    <f:facet name="after">
+      <tc:flexLayout columns="auto auto">
+        <tc:form id="searchForm">
+          <tc:flexLayout columns="200px auto">
+            <tc:in placeholder="Search" required="true" value="#{navigationState.searchString}" labelLayout="none"
+                   label="Search" id="search">
+              <f:facet name="after">
+                <tc:button label="go" action="#{navigationState.search}" defaultCommand="true"/>
+              </f:facet>
+            </tc:in>
+          </tc:flexLayout>
+        </tc:form>
+        <tc:form id="navbtns">
+          <tc:flexLayout columns="auto auto">
+            <tc:buttons>
+              <tc:button immediate="true" id="previous"
+                         icon="bi-chevron-left"
+                         action="#{navigationState.gotoPrevious}"
+                         disabled="#{navigationState.first}"
+                         tip="Previous"/>
+              <tc:button immediate="true" id="next"
+                         icon="bi-chevron-right"
+                         action="#{navigationState.gotoNext}"
+                         disabled="#{navigationState.last}"
+                         tip="Next"/>
+            </tc:buttons>
+            <tc:button action="#{navigationState.toggleViewSource}"
+                       icon="bi-code-slash"
+                       immediate="true" tip="View Source"/>
+          </tc:flexLayout>
+        </tc:form>
+      </tc:flexLayout>
+    </f:facet>
+  </tc:bar>
+
+  <!--
+    </tc:flexLayout>
+  -->
 
 </tc:header>


(myfaces-tobago) 02/02: build(theme): rebuild

Posted by hn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

hnoeth pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/myfaces-tobago.git

commit 9bae7055441dac98920ceb08e81104fd550738eb
Author: Henning Noeth <hn...@apache.org>
AuthorDate: Wed Apr 15 13:41:31 2026 +0200

    build(theme): rebuild
---
 .../src/main/webapp/css/demo.css                   | 76 ++++++++++++++--------
 .../src/main/webapp/css/demo.css.map               |  2 +-
 .../src/main/webapp/css/demo.min.css               |  2 +-
 .../src/main/webapp/css/demo.min.css.map           |  2 +-
 .../src/main/webapp/js/demo-all.js                 |  1 +
 .../src/main/webapp/js/demo-all.js.map             |  2 +-
 .../src/main/webapp/js/demo-navigation.js          | 65 ++++++++++++++++++
 .../src/main/webapp/js/demo-navigation.js.map      |  1 +
 .../tobago-example-demo/src/main/webapp/js/demo.js | 65 ++++++++++++++++++
 .../src/main/webapp/js/demo.js.map                 |  2 +-
 .../tobago-theme-standard/src/main/js/tobago.js    |  4 +-
 .../src/main/js/tobago.js.map                      |  2 +-
 12 files changed, 188 insertions(+), 36 deletions(-)

diff --git a/tobago-example/tobago-example-demo/src/main/webapp/css/demo.css b/tobago-example/tobago-example-demo/src/main/webapp/css/demo.css
index 56c208d327..aacc762771 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/css/demo.css
+++ b/tobago-example/tobago-example-demo/src/main/webapp/css/demo.css
@@ -14,6 +14,54 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+/*
+ * 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.
+ */
+.navigation tobago-tree-node[data-tobago-level="0"] {
+  font-weight: bold;
+  margin-top: 1rem;
+  white-space: nowrap;
+}
+.navigation tobago-tree-node[data-tobago-level="0"][index="1"] {
+  margin-top: 0;
+}
+.navigation tobago-tree-node[data-tobago-level="1"] a, .navigation tobago-tree-node[data-tobago-level="2"] a, .navigation tobago-tree-node[data-tobago-level="3"] a, .navigation tobago-tree-node[data-tobago-level="4"] a, .navigation tobago-tree-node[data-tobago-level="5"] a {
+  padding: 0.25rem;
+  color: var(--bs-secondary);
+  border-radius: var(--bs-border-radius);
+}
+.navigation tobago-tree-node[data-tobago-level="1"] a:hover, .navigation tobago-tree-node[data-tobago-level="2"] a:hover, .navigation tobago-tree-node[data-tobago-level="3"] a:hover, .navigation tobago-tree-node[data-tobago-level="4"] a:hover, .navigation tobago-tree-node[data-tobago-level="5"] a:hover {
+  background-color: rgba(var(--bs-secondary-rgb), 0.1);
+}
+.navigation tobago-tree-node[data-tobago-level="1"] a.active, .navigation tobago-tree-node[data-tobago-level="2"] a.active, .navigation tobago-tree-node[data-tobago-level="3"] a.active, .navigation tobago-tree-node[data-tobago-level="4"] a.active, .navigation tobago-tree-node[data-tobago-level="5"] a.active {
+  color: var(--bs-primary);
+  background-color: rgba(var(--bs-primary-rgb), 0.1);
+}
+.navigation tobago-tree-node[data-tobago-level="2"] a, .navigation tobago-tree-node[data-tobago-level="3"] a, .navigation tobago-tree-node[data-tobago-level="4"] a, .navigation tobago-tree-node[data-tobago-level="5"] a {
+  font-size: small;
+}
+
+.navigation-expanded {
+  display: block;
+  position: sticky;
+  top: calc(56px + 1rem);
+  height: calc(100vh - 56px - 40px - 2rem);
+  overflow-y: auto;
+}
+
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
@@ -101,34 +149,6 @@ html {
   scroll-padding-top: 72px;
 }
 
-#page\:navigation\:nav tobago-tree-node[data-tobago-level="0"], #page\:navigation-small\:nav-small tobago-tree-node[data-tobago-level="0"] {
-  font-weight: bold;
-  margin-top: 1rem;
-  white-space: nowrap;
-}
-#page\:navigation\:nav tobago-tree-node[data-tobago-level="0"][index="1"], #page\:navigation-small\:nav-small tobago-tree-node[data-tobago-level="0"][index="1"] {
-  margin-top: 0;
-}
-#page\:navigation\:nav tobago-tree-node[data-tobago-level="1"] a, #page\:navigation\:nav tobago-tree-node[data-tobago-level="2"] a, #page\:navigation\:nav tobago-tree-node[data-tobago-level="3"] a, #page\:navigation\:nav tobago-tree-node[data-tobago-level="4"] a, #page\:navigation\:nav tobago-tree-node[data-tobago-level="5"] a, #page\:navigation-small\:nav-small tobago-tree-node[data-tobago-level="1"] a, #page\:navigation-small\:nav-small tobago-tree-node[data-tobago-level="2"] a, #page\ [...]
-  padding: 0.25rem;
-  color: var(--bs-secondary);
-  border-radius: var(--bs-border-radius);
-}
-#page\:navigation\:nav tobago-tree-node[data-tobago-level="1"] a:hover, #page\:navigation\:nav tobago-tree-node[data-tobago-level="2"] a:hover, #page\:navigation\:nav tobago-tree-node[data-tobago-level="3"] a:hover, #page\:navigation\:nav tobago-tree-node[data-tobago-level="4"] a:hover, #page\:navigation\:nav tobago-tree-node[data-tobago-level="5"] a:hover, #page\:navigation-small\:nav-small tobago-tree-node[data-tobago-level="1"] a:hover, #page\:navigation-small\:nav-small tobago-tree-n [...]
-  background-color: rgba(var(--bs-secondary-rgb), 0.1);
-}
-#page\:navigation\:nav tobago-tree-node[data-tobago-level="1"] a.active, #page\:navigation\:nav tobago-tree-node[data-tobago-level="2"] a.active, #page\:navigation\:nav tobago-tree-node[data-tobago-level="3"] a.active, #page\:navigation\:nav tobago-tree-node[data-tobago-level="4"] a.active, #page\:navigation\:nav tobago-tree-node[data-tobago-level="5"] a.active, #page\:navigation-small\:nav-small tobago-tree-node[data-tobago-level="1"] a.active, #page\:navigation-small\:nav-small tobago- [...]
-  color: var(--bs-primary);
-  background-color: rgba(var(--bs-primary-rgb), 0.1);
-}
-#page\:navigation\:nav tobago-tree-node[data-tobago-level="2"] a, #page\:navigation\:nav tobago-tree-node[data-tobago-level="3"] a, #page\:navigation\:nav tobago-tree-node[data-tobago-level="4"] a, #page\:navigation\:nav tobago-tree-node[data-tobago-level="5"] a, #page\:navigation-small\:nav-small tobago-tree-node[data-tobago-level="2"] a, #page\:navigation-small\:nav-small tobago-tree-node[data-tobago-level="3"] a, #page\:navigation-small\:nav-small tobago-tree-node[data-tobago-level="4 [...]
-  font-size: small;
-}
-
-.hide-navigation {
-  display: none;
-}
-
 .navigation-box {
   --bs-card-border-radius: 0;
   border: none;
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/css/demo.css.map b/tobago-example/tobago-example-demo/src/main/webapp/css/demo.css.map
index 4eb7b35a9b..cfcff273f3 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/css/demo.css.map
+++ b/tobago-example/tobago-example-demo/src/main/webapp/css/demo.css.map
@@ -1 +1 @@
-{"version":3,"sourceRoot":"","sources":["../../scss/demo.scss","../../scss/demo-sidebar.scss"],"names":[],"mappings":"AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAoBA;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAIA;EACE;;AAGF;EACE,cApBc;;AAyBZ;EACE;;AADF;EACE;;AADF;EACE;;AADF;EACE;;AADF;EACE;;AADF;EACE;;AADF;EACE;;AADF;EACE;;AADF;EACE;;AADF;EACE;;AAUN;EACE;EACA;EACA;EACA;EA [...]
\ No newline at end of file
+{"version":3,"sourceRoot":"","sources":["../../scss/demo.scss","../../scss/demo-navigation.scss","../../scss/demo-sidebar.scss"],"names":[],"mappings":"AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAkBE;EACE;EACA;EACA;;AAEA;EACE;;AAUA;EACE;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;;AAWJ;EACE;;;AAMR;EACE;EACA;EACA;EACA;EACA;;;ACpEF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA [...]
\ No newline at end of file
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/css/demo.min.css b/tobago-example/tobago-example-demo/src/main/webapp/css/demo.min.css
index 196f5534eb..2d42e47586 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/css/demo.min.css
+++ b/tobago-example/tobago-example-demo/src/main/webapp/css/demo.min.css
@@ -1,2 +1,2 @@
-demo-sidebar{position:fixed;overflow-x:hidden;overflow-y:auto;padding-top:1rem;padding-bottom:1rem;right:0}demo-sidebar strong{padding-left:calc(2px + .25rem)}demo-sidebar nav ul{padding-left:0}demo-sidebar nav>a{padding-left:.25rem}demo-sidebar nav li a{padding-left:.75rem}demo-sidebar nav li li a{padding-left:1.5rem}demo-sidebar nav li li li a{padding-left:2.25rem}demo-sidebar nav li li li li a{padding-left:3rem}demo-sidebar nav li li li li li a{padding-left:3.75rem}demo-sidebar nav li [...]
+.navigation tobago-tree-node[data-tobago-level="0"]{font-weight:700;margin-top:1rem;white-space:nowrap}.navigation tobago-tree-node[data-tobago-level="0"][index="1"]{margin-top:0}.navigation tobago-tree-node[data-tobago-level="1"] a,.navigation tobago-tree-node[data-tobago-level="2"] a,.navigation tobago-tree-node[data-tobago-level="3"] a,.navigation tobago-tree-node[data-tobago-level="4"] a,.navigation tobago-tree-node[data-tobago-level="5"] a{padding:.25rem;color:var(--bs-secondary);bo [...]
 /*# sourceMappingURL=demo.min.css.map */
\ No newline at end of file
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/css/demo.min.css.map b/tobago-example/tobago-example-demo/src/main/webapp/css/demo.min.css.map
index 5068aa5cb1..9429e704f3 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/css/demo.min.css.map
+++ b/tobago-example/tobago-example-demo/src/main/webapp/css/demo.min.css.map
@@ -1 +1 @@
-{"version":3,"sources":["src/main/webapp/css/demo.css"],"names":[],"mappings":"AAgCA,aACE,SAAU,MACV,WAAY,OACZ,WAAY,KACZ,YAAa,KACb,eAAgB,KAChB,MAAO,EAET,oBACE,aAAc,mBAEhB,oBACE,aAAc,EAEhB,mBACE,aAAc,OAEhB,sBACE,aAAc,OAEhB,yBACE,aAAc,OAEhB,4BACE,aAAc,QAEhB,+BACE,aAAc,KAEhB,kCACE,aAAc,QAEhB,qCACE,aAAc,OAEhB,wCACE,aAAc,QAEhB,2CACE,aAAc,KAEhB,8CACE,aAAc,QAEhB,iDACE,aAAc,OAEhB,mBACE,UAAW,QACX,MAAO,oBACP,gBAAiB,KACjB,YAAa,IAAI,MAAM,YACvB,QAAS,MACT,WAAY,IACZ,cAAe,IAEjB,yBACE,gBAAiB,UAEnB,0BACE,M [...]
\ No newline at end of file
+{"version":3,"sources":["src/main/webapp/css/demo.css"],"names":[],"mappings":"AAgCA,oDACE,YAAa,IACb,WAAY,KACZ,YAAa,OAEf,+DACE,WAAY,EAEd,sDAAuD,sDAAuD,sDAAuD,sDAAuD,sDAC1N,QAAS,OACT,MAAO,oBACP,cAAe,wBAEjB,4DAA6D,4DAA6D,4DAA6D,4DAA6D,4DAClP,iBAAkB,iCAEpB,6DAA8D,6DAA8D,6DAA8D,6DAA8D,6DACtP,MAAO,kBACP,iBAAkB,+BAEpB,sDAAuD,sDAAuD,sDAAuD,sDACnK,UAAW,MAGb,qBACE,QAAS,MACT,SAAU,OACV,IAAK,kBACL,OAAQ,iCACR,WAAY,KAmBd,aACE,SAAU,MACV,WAAY,OACZ,WAAY,KACZ,YAAa,KACb,eAAgB,KAChB,MAAO,EAET,oBACE,aAAc,mBA [...]
\ No newline at end of file
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/js/demo-all.js b/tobago-example/tobago-example-demo/src/main/webapp/js/demo-all.js
index 6a1f966467..6684c79f8a 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/js/demo-all.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/js/demo-all.js
@@ -20,6 +20,7 @@ import "./demo-date";
 import "./demo-highlight";
 import "./demo-inspect";
 import "./demo-login";
+import "./demo-navigation";
 import "./demo-sidebar";
 import "./demo-test";
 //# sourceMappingURL=demo-all.js.map
\ No newline at end of file
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/js/demo-all.js.map b/tobago-example/tobago-example-demo/src/main/webapp/js/demo-all.js.map
index 3b1922008e..9ddbbb1660 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/js/demo-all.js.map
+++ b/tobago-example/tobago-example-demo/src/main/webapp/js/demo-all.js.map
@@ -1 +1 @@
-{"version":3,"file":"demo-all.js","sourceRoot":"","sources":["../../ts/demo-all.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,cAAc,CAAC;AACtB,OAAO,0BAA0B,CAAC;AAClC,OAAO,aAAa,CAAC;AACrB,OAAO,kBAAkB,CAAC;AAC1B,OAAO,gBAAgB,CAAC;AACxB,OAAO,cAAc,CAAC;AACtB,OAAO,gBAAgB,CAAC;AACxB,OAAO,aAAa,CAAC"}
\ No newline at end of file
+{"version":3,"file":"demo-all.js","sourceRoot":"","sources":["../../ts/demo-all.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,cAAc,CAAC;AACtB,OAAO,0BAA0B,CAAC;AAClC,OAAO,aAAa,CAAC;AACrB,OAAO,kBAAkB,CAAC;AAC1B,OAAO,gBAAgB,CAAC;AACxB,OAAO,cAAc,CAAC;AACtB,OAAO,mBAAmB,CAAC;AAC3B,OAAO,gBAAgB,CAAC;AACxB,OAAO,aAAa,CAAC"}
\ No newline at end of file
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/js/demo-navigation.js b/tobago-example/tobago-example-demo/src/main/webapp/js/demo-navigation.js
new file mode 100644
index 0000000000..39193e0d55
--- /dev/null
+++ b/tobago-example/tobago-example-demo/src/main/webapp/js/demo-navigation.js
@@ -0,0 +1,65 @@
+/*
+ * 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.
+ */
+export class Navigation extends HTMLElement {
+    connectedCallback() {
+        var _a;
+        if (this.fixedHeader) {
+            this.headerResizeObserver = new ResizeObserver(() => this.updatePositionAndSize());
+            this.headerResizeObserver.observe(this.fixedHeader);
+        }
+        if (this.fixedFooter) {
+            this.footerResizeObserver = new ResizeObserver(() => this.updatePositionAndSize());
+            this.footerResizeObserver.observe(this.fixedFooter);
+        }
+        this.updatePositionAndSize();
+        (_a = this.activeLink) === null || _a === void 0 ? void 0 : _a.scrollIntoView({ block: "center" });
+    }
+    disconnectedCallback() {
+        var _a, _b;
+        (_a = this.headerResizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
+        (_b = this.footerResizeObserver) === null || _b === void 0 ? void 0 : _b.disconnect();
+    }
+    updatePositionAndSize() {
+        const headerHeight = this.fixedHeader.offsetHeight;
+        const footerHeight = this.fixedFooter.offsetHeight;
+        this.navigationExpanded.style.top = "calc(" + headerHeight + " + 1rem)";
+        this.navigationExpanded.style.height = "calc(100vh - " + headerHeight + " - " + footerHeight + " - 2rem)";
+    }
+    get navigationExpanded() {
+        const rootNode = this.getRootNode();
+        return rootNode.querySelector("tobago-panel.navigation-expanded");
+    }
+    get fixedHeader() {
+        const rootNode = this.getRootNode();
+        return rootNode.querySelector("tobago-header.sticky-top");
+    }
+    get fixedFooter() {
+        const rootNode = this.getRootNode();
+        return rootNode.querySelector("tobago-footer.fixed-bottom");
+    }
+    get activeLink() {
+        return this.querySelector(".tobago-link.active");
+    }
+}
+if (typeof window !== "undefined") {
+    window.addEventListener("DOMContentLoaded", function () {
+        if (!window.customElements.get("demo-navigation")) {
+            window.customElements.define("demo-navigation", Navigation);
+        }
+    });
+}
+//# sourceMappingURL=demo-navigation.js.map
\ No newline at end of file
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/js/demo-navigation.js.map b/tobago-example/tobago-example-demo/src/main/webapp/js/demo-navigation.js.map
new file mode 100644
index 0000000000..841a98ddd3
--- /dev/null
+++ b/tobago-example/tobago-example-demo/src/main/webapp/js/demo-navigation.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"demo-navigation.js","sourceRoot":"","sources":["../../ts/demo-navigation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,MAAM,OAAO,UAAW,SAAQ,WAAW;IAIzC,iBAAiB;;QACf,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACrB,IAAI,CAAC,oBAAoB,GAAG,IAAI,cAAc,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,qBAAqB,EAAE,CAAC,CAAC;YACnF,IAAI,CAAC,oBAAoB,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACtD,CAAC;QACD,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACrB,IAAI,CAAC,oBAAoB,GAAG,IAAI,cAAc,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC, [...]
\ No newline at end of file
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/js/demo.js b/tobago-example/tobago-example-demo/src/main/webapp/js/demo.js
index 668365780d..b0bab2d7b3 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/js/demo.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/js/demo.js
@@ -331,6 +331,71 @@
         }
     });
 
+    /*
+     * 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.
+     */
+    class Navigation extends HTMLElement {
+        connectedCallback() {
+            var _a;
+            if (this.fixedHeader) {
+                this.headerResizeObserver = new ResizeObserver(() => this.updatePositionAndSize());
+                this.headerResizeObserver.observe(this.fixedHeader);
+            }
+            if (this.fixedFooter) {
+                this.footerResizeObserver = new ResizeObserver(() => this.updatePositionAndSize());
+                this.footerResizeObserver.observe(this.fixedFooter);
+            }
+            this.updatePositionAndSize();
+            (_a = this.activeLink) === null || _a === void 0 ? void 0 : _a.scrollIntoView({ block: "center" });
+        }
+        disconnectedCallback() {
+            var _a, _b;
+            (_a = this.headerResizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
+            (_b = this.footerResizeObserver) === null || _b === void 0 ? void 0 : _b.disconnect();
+        }
+        updatePositionAndSize() {
+            const headerHeight = this.fixedHeader.offsetHeight;
+            const footerHeight = this.fixedFooter.offsetHeight;
+            this.navigationExpanded.style.top = "calc(" + headerHeight + " + 1rem)";
+            this.navigationExpanded.style.height = "calc(100vh - " + headerHeight + " - " + footerHeight + " - 2rem)";
+        }
+        get navigationExpanded() {
+            const rootNode = this.getRootNode();
+            return rootNode.querySelector("tobago-panel.navigation-expanded");
+        }
+        get fixedHeader() {
+            const rootNode = this.getRootNode();
+            return rootNode.querySelector("tobago-header.sticky-top");
+        }
+        get fixedFooter() {
+            const rootNode = this.getRootNode();
+            return rootNode.querySelector("tobago-footer.fixed-bottom");
+        }
+        get activeLink() {
+            return this.querySelector(".tobago-link.active");
+        }
+    }
+    if (typeof window !== "undefined") {
+        window.addEventListener("DOMContentLoaded", function () {
+            if (!window.customElements.get("demo-navigation")) {
+                window.customElements.define("demo-navigation", Navigation);
+            }
+        });
+    }
+
     /*
      * Licensed to the Apache Software Foundation (ASF) under one or more
      * contributor license agreements.  See the NOTICE file distributed with
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/js/demo.js.map b/tobago-example/tobago-example-demo/src/main/webapp/js/demo.js.map
index 4aab1cf79b..19bc7713a7 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/js/demo.js.map
+++ b/tobago-example/tobago-example-demo/src/main/webapp/js/demo.js.map
@@ -1 +1 @@
-{"version":3,"file":"demo.js","sources":["demo-alert.js","demo-copy-to-clipboard.js","demo-date.js","demo-highlight.js","demo-inspect.js","demo-login.js","demo-sidebar.js","demo-test.js"],"sourcesContent":["/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, V [...]
\ No newline at end of file
+{"version":3,"file":"demo.js","sources":["demo-alert.js","demo-copy-to-clipboard.js","demo-date.js","demo-highlight.js","demo-inspect.js","demo-login.js","demo-navigation.js","demo-sidebar.js","demo-test.js"],"sourcesContent":["/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under  [...]
\ No newline at end of file
diff --git a/tobago-theme/tobago-theme-standard/src/main/js/tobago.js b/tobago-theme/tobago-theme-standard/src/main/js/tobago.js
index f88459c4b1..f229a1818f 100644
--- a/tobago-theme/tobago-theme-standard/src/main/js/tobago.js
+++ b/tobago-theme/tobago-theme-standard/src/main/js/tobago.js
@@ -2,7 +2,7 @@
 /*!
     * tabbable 6.4.0
     * @license MIT, https://github.com/focus-trap/tabbable/blob/master/LICENSE
-    */var u=["input:not([inert]):not([inert] *)","select:not([inert]):not([inert] *)","textarea:not([inert]):not([inert] *)","a[href]:not([inert]):not([inert] *)","button:not([inert]):not([inert] *)","[tabindex]:not(slot):not([inert]):not([inert] *)","audio[controls]:not([inert]):not([inert] *)","video[controls]:not([inert]):not([inert] *)",'[contenteditable]:not([contenteditable="false"]):not([inert]):not([inert] *)',"details>summary:first-of-type:not([inert]):not([inert] *)","details:n [...]
+    */var u=["input:not([inert]):not([inert] *)","select:not([inert]):not([inert] *)","textarea:not([inert]):not([inert] *)","a[href]:not([inert]):not([inert] *)","button:not([inert]):not([inert] *)","[tabindex]:not(slot):not([inert]):not([inert] *)","audio[controls]:not([inert]):not([inert] *)","video[controls]:not([inert]):not([inert] *)",'[contenteditable]:not([contenteditable="false"]):not([inert]):not([inert] *)',"details>summary:first-of-type:not([inert]):not([inert] *)","details:n [...]
 /*!
       * Bootstrap v5.3.8 (https://getbootstrap.com/)
       * Copyright 2011-2025 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
@@ -22,5 +22,5 @@ const Tr=globalThis,Lr=e=>e,Cr=Tr.trustedTypes,Ir=Cr?Cr.createPolicy("lit-html",
       ${i>0?" tabindex='"+String(i)+"'":""}
       @click="${this.removeBadge.bind(this)}"
       @focus="${this.focusEvent.bind(this)}"
-      @blur="${this.blurEvent.bind(this)}"><i class='bi-x-lg'></i></button>`}removeBadge(e){const t=e.target.closest(".btn-group").dataset.tobagoValue,s=this.hiddenSelect.querySelector(`[value="${t}"]`);s.selected=!1;const i=this.badges.querySelector(`[data-tobago-value="${t}"]`),n=this.getPreviousEnabledBadge(i),o=this.getNextEnabledBadge(i);n?n.querySelector("button.btn.badge").focus():o?o.querySelector("button.btn.badge").focus():(this.filterInput.disabled=!1,this.filterInput.focus()) [...]
+      @blur="${this.blurEvent.bind(this)}"><i class='bi-x-lg'></i></button>`}removeBadge(e){const t=e.target.closest(".btn-group").dataset.tobagoValue,s=this.hiddenSelect.querySelector(`[value="${t}"]`);s.selected=!1;const i=this.badges.querySelector(`[data-tobago-value="${t}"]`),n=this.getPreviousEnabledBadge(i),o=this.getNextEnabledBadge(i);n?n.querySelector("button.btn.badge").focus():o?o.querySelector("button.btn.badge").focus():(this.filterInput.disabled=!1,this.filterInput.focus()) [...]
 //# sourceMappingURL=tobago.js.map
diff --git a/tobago-theme/tobago-theme-standard/src/main/js/tobago.js.map b/tobago-theme/tobago-theme-standard/src/main/js/tobago.js.map
index 7b0168ba34..f20505a9d7 100644
--- a/tobago-theme/tobago-theme-standard/src/main/js/tobago.js.map
+++ b/tobago-theme/tobago-theme-standard/src/main/js/tobago.js.map
@@ -1 +1 @@
-{"version":3,"file":"tobago.js","sources":["../ts/tobago-css.ts","../ts/tobago-key.ts","../ts/tobago-client-behaviors.ts","../ts/tobago-dropdown-menu.ts","../ts/ts/util/EventListenerStore.ts","../ts/tobago-bar.ts","../ts/tobago-date.ts","../ts/tobago-dropdown-item-factory.ts","../ts/tobago-dropdown-item.ts","../ts/ts/dropdown/DropdownMenuStatic.ts","../../../../node_modules/tabbable/dist/index.esm.js","../ts/tobago-dropdown.ts","../ts/tobago-overlay-type.ts","../ts/tobago-suggest-filter. [...]
\ No newline at end of file
+{"version":3,"file":"tobago.js","sources":["../ts/tobago-css.ts","../ts/tobago-key.ts","../ts/tobago-client-behaviors.ts","../ts/tobago-dropdown-menu.ts","../ts/ts/util/EventListenerStore.ts","../ts/tobago-bar.ts","../ts/tobago-date.ts","../ts/tobago-dropdown-item-factory.ts","../ts/tobago-dropdown-item.ts","../ts/ts/dropdown/DropdownMenuStatic.ts","../../../../node_modules/tabbable/dist/index.esm.js","../ts/tobago-dropdown.ts","../ts/tobago-overlay-type.ts","../ts/tobago-suggest-filter. [...]
\ No newline at end of file