add disable attribute for tc:buttons and tc:links

* add setter for disable attribute in ButtonsTagDeclaration and LinksTagDeclaration
* create Interface to set and get disabled
* adjust Renderer to write disabled attribute in tag
* adjust isDisabled in AbstractUICommandBase to check if the parent is disabled. If the parent is disabled all all children are disabled. If a child has the disabled attribute set, than the child is not disabled.
* create example in demo

ISSUE: TOBAGO-1997
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/component/SupportsDisabled.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/component/SupportsDisabled.java
new file mode 100644
index 0000000..ab39327
--- /dev/null
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/component/SupportsDisabled.java
@@ -0,0 +1,27 @@
+/*
+ * 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.myfaces.tobago.component;
+
+public interface SupportsDisabled {
+
+  boolean isDisabled();
+
+  void setDisabled(final boolean disabled);
+}
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIButtons.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIButtons.java
index 30396e5..357ff5f 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIButtons.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIButtons.java
@@ -19,12 +19,18 @@
 
 package org.apache.myfaces.tobago.internal.component;
 
+import org.apache.myfaces.tobago.component.SupportsDisabled;
 import org.apache.myfaces.tobago.layout.Orientation;
 
 /**
  * {@link org.apache.myfaces.tobago.internal.taglib.component.ButtonsTagDeclaration}
  */
-public abstract class AbstractUIButtons extends AbstractUIPanelBase {
+public abstract class AbstractUIButtons extends AbstractUIPanelBase implements SupportsDisabled {
+
+  enum PropertyKeys {
+    disabled,
+  }
 
   public abstract Orientation getOrientation();
+
 }
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUICommandBase.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUICommandBase.java
index 1045901..7321b2e 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUICommandBase.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUICommandBase.java
@@ -19,6 +19,7 @@
 
 package org.apache.myfaces.tobago.internal.component;
 
+import org.apache.myfaces.tobago.component.SupportsDisabled;
 import org.apache.myfaces.tobago.config.TobagoConfig;
 import org.apache.myfaces.tobago.event.CollapsibleActionListener;
 import org.apache.myfaces.tobago.internal.config.SecurityAnnotation;
@@ -108,6 +109,13 @@
     final FacesContext facesContext = getFacesContext();
     final TobagoConfig tobagoConfig = TobagoConfig.getInstance(facesContext);
     final Boolean disabled = (Boolean) getStateHelper().eval(AbstractUICommand.PropertyKeys.disabled);
+    if (disabled == null) {
+      SupportsDisabled parent =
+          ComponentUtils.findAncestor(getCurrentComponent(facesContext), SupportsDisabled.class);
+      if (parent != null && parent.isDisabled()) {
+        return true;
+      }
+    }
     return disabled != null && disabled
         || (tobagoConfig.getSecurityAnnotation() == SecurityAnnotation.disable && !isAllowed());
   }
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUILinks.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUILinks.java
index 8de772a..b0c9789 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUILinks.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUILinks.java
@@ -19,12 +19,18 @@
 
 package org.apache.myfaces.tobago.internal.component;
 
+import org.apache.myfaces.tobago.component.SupportsDisabled;
 import org.apache.myfaces.tobago.layout.Orientation;
 
 /**
  * {@link org.apache.myfaces.tobago.internal.taglib.component.LinksTagDeclaration}
  */
-public abstract class AbstractUILinks extends AbstractUIPanelBase {
+public abstract class AbstractUILinks extends AbstractUIPanelBase implements SupportsDisabled {
+
+  enum PropertyKeys {
+    disabled,
+  }
 
   public abstract Orientation getOrientation();
+
 }
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/LinksRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/LinksRenderer.java
index 9baede8..5678943 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/LinksRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/LinksRenderer.java
@@ -27,6 +27,7 @@
 import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
 import org.apache.myfaces.tobago.renderkit.css.CssItem;
 import org.apache.myfaces.tobago.renderkit.css.TobagoClass;
+import org.apache.myfaces.tobago.renderkit.html.HtmlAttributes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
 import org.apache.myfaces.tobago.webapp.TobagoResponseWriter;
 
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/ButtonsTagDeclaration.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/ButtonsTagDeclaration.java
index 313b432..e7d2556 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/ButtonsTagDeclaration.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/ButtonsTagDeclaration.java
@@ -20,7 +20,9 @@
 package org.apache.myfaces.tobago.internal.taglib.component;
 
 import org.apache.myfaces.tobago.apt.annotation.Tag;
+import org.apache.myfaces.tobago.apt.annotation.TagAttribute;
 import org.apache.myfaces.tobago.apt.annotation.UIComponentTag;
+import org.apache.myfaces.tobago.apt.annotation.UIComponentTagAttribute;
 import org.apache.myfaces.tobago.component.RendererTypes;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasIdBindingAndRendered;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasOrientation;
@@ -46,4 +48,10 @@
 public interface ButtonsTagDeclaration
     extends HasIdBindingAndRendered, IsVisual, HasTip, HasOrientation {
 
+  /**
+   * Flag indicating that this element and all children are disabled.
+   */
+  @TagAttribute()
+  @UIComponentTagAttribute(type = "boolean")
+  void setDisabled(String disabled);
 }
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/LinksTagDeclaration.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/LinksTagDeclaration.java
index 75f3673..a16adff 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/LinksTagDeclaration.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/LinksTagDeclaration.java
@@ -20,7 +20,9 @@
 package org.apache.myfaces.tobago.internal.taglib.component;
 
 import org.apache.myfaces.tobago.apt.annotation.Tag;
+import org.apache.myfaces.tobago.apt.annotation.TagAttribute;
 import org.apache.myfaces.tobago.apt.annotation.UIComponentTag;
+import org.apache.myfaces.tobago.apt.annotation.UIComponentTagAttribute;
 import org.apache.myfaces.tobago.component.RendererTypes;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasIdBindingAndRendered;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasOrientation;
@@ -43,4 +45,11 @@
     },
     rendererType = {RendererTypes.LINKS, RendererTypes.LINKS_INSIDE_BAR})
 public interface LinksTagDeclaration extends HasIdBindingAndRendered, IsVisual, HasTip, HasOrientation {
+
+  /**
+   * Flag indicating that this element and all children are disabled.
+   */
+  @TagAttribute()
+  @UIComponentTagAttribute(type = "boolean")
+  void setDisabled(String disabled);
 }
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/040-command/20-buttons/Button_Group.xhtml b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/040-command/20-buttons/Button_Group.xhtml
index 244f0e4..97a9742 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/040-command/20-buttons/Button_Group.xhtml
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/040-command/20-buttons/Button_Group.xhtml
@@ -94,4 +94,19 @@
       <tc:button label="Right"/>
     </tc:buttons>
   </tc:section>
+
+  <tc:section label="Disable">
+    <p>This example shows how to disable all buttons in a button group.
+      It's also possible to set disable to false e.g. for one button.</p>
+    <pre><code class="language-markup">&lt;tc:buttons disabled="true">
+  &lt;c:button label="Left" disabled="false"/>
+  &lt;tc:button label="Center"/>
+  &lt;tc:button label="Right"/>
+&lt;/tc:buttons></code></pre>
+    <tc:buttons disabled="true">
+      <tc:button label="Left" disabled="false"/>
+      <tc:button label="Center"/>
+      <tc:button label="Right"/>
+    </tc:buttons>
+  </tc:section>
 </ui:composition>
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/040-command/25-links/Link_Group.xhtml b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/040-command/25-links/Link_Group.xhtml
index 65bc576..6e0f8bc 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/040-command/25-links/Link_Group.xhtml
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/20-component/040-command/25-links/Link_Group.xhtml
@@ -87,4 +87,19 @@
       <tc:link label="Right"/>
     </tc:links>
   </tc:section>
+
+  <tc:section label="Disable">
+    <p>This example shows how to disable all links in a link group.
+      It's also possible to set disable to false e.g. for one link.</p>
+    <pre><code class="language-markup">&lt;tc:links disabled="true">
+  &lt;c:link label="Left" disabled="false"/>
+  &lt;tc:link label="Center"/>
+  &lt;tc:link label="Right"/>
+&lt;/tc:links></code></pre>
+    <tc:links disabled="true">
+      <tc:link label="Left" disabled="false"/>
+      <tc:link label="Center"/>
+      <tc:link label="Right"/>
+    </tc:links>
+  </tc:section>
 </ui:composition>