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 2023/01/18 09:53:15 UTC

[myfaces-tobago] branch main updated (b08ed0cd8f -> 1276941437)

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 b08ed0cd8f build(deps): bump dependency-check-maven from 7.4.4 to 8.0.0
     new 1925189014 feat: help/message position
     new 1276941437 build(theme): rebuild after implementing message/help position attribute

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:
 .../myfaces/tobago/component/Attributes.java       |   2 +
 ...catedDimension.java => DecorationPosition.java} |  42 +++--
 ...sabled.java => SupportsDecorationPosition.java} |   6 +-
 .../tobago/internal/component/AbstractUIFile.java  |   3 +-
 .../tobago/internal/component/AbstractUIInput.java |   3 +-
 .../tobago/internal/component/AbstractUIOut.java   |   4 +-
 .../component/AbstractUISelectBoolean.java         |   3 +-
 .../component/AbstractUISelectManyBase.java        |   4 +-
 .../component/AbstractUISelectOneBase.java         |   4 +-
 .../internal/renderkit/renderer/DateRenderer.java  |   2 +-
 ...se.java => DecorationPositionRendererBase.java} | 150 ++++++++++++----
 .../internal/renderkit/renderer/FileRenderer.java  |   2 +-
 .../internal/renderkit/renderer/InRenderer.java    |   2 +-
 .../internal/renderkit/renderer/OutRenderer.java   |   2 +-
 .../internal/renderkit/renderer/RangeRenderer.java |   2 +-
 .../renderer/SelectBooleanRendererBase.java        |   2 +-
 .../renderkit/renderer/SelectManyRendererBase.java |   3 +-
 .../renderkit/renderer/SelectOneRendererBase.java  |   3 +-
 .../internal/renderkit/renderer/StarsRenderer.java |   2 +-
 .../renderkit/renderer/TextareaRenderer.java       |   2 +-
 .../taglib/component/DateTagDeclaration.java       |   3 +-
 .../taglib/component/FileTagDeclaration.java       |   5 +-
 .../taglib/component/InTagDeclaration.java         |   6 +-
 .../taglib/component/OutTagDeclaration.java        |   3 +-
 .../taglib/component/RangeTagDeclaration.java      |   3 +-
 .../SelectBooleanCheckboxTagDeclaration.java       |   5 +-
 .../SelectBooleanToggleTagDeclaration.java         |   5 +-
 .../SelectManyCheckboxTagDeclaration.java          |   3 +-
 .../component/SelectManyListTagDeclaration.java    |   3 +-
 .../component/SelectManyListboxTagDeclaration.java |   5 +-
 .../component/SelectManyShuttleTagDeclaration.java |   5 +-
 .../component/SelectOneChoiceTagDeclaration.java   |   5 +-
 .../component/SelectOneListboxTagDeclaration.java  |   5 +-
 .../component/SelectOneRadioTagDeclaration.java    |   5 +-
 .../taglib/component/StarsTagDeclaration.java      |   5 +-
 .../taglib/component/TextareaTagDeclaration.java   |   3 +-
 ...LabelLayout.java => HasDecorationPosition.java} |  30 ++--
 .../tobago/renderkit/css/BootstrapClass.java       |  24 ++-
 .../myfaces/tobago/renderkit/css/TobagoClass.java  |  38 ++++
 .../tobago/renderkit/html/DataAttributes.java      |   9 +
 .../resources/renderer/date/error-message.html     |   2 +-
 .../src/test/resources/renderer/date/help.html     |   4 +-
 .../test/resources/renderer/in/error-message.html  |   2 +-
 .../src/test/resources/renderer/in/help.html       |   4 +-
 .../selectBooleanCheckboxError.html                |   2 +-
 .../selectBooleanCheckboxFatal.html                |   2 +-
 .../selectBooleanCheckboxInfo.html                 |   2 +-
 .../selectBooleanCheckboxWarning.html              |   2 +-
 .../selectManyCheckboxFatal.html                   |   2 +-
 .../renderer/selectManyShuttle/error-message.html  |   2 +-
 .../resources/renderer/selectManyShuttle/help.html |   4 +-
 .../resources/tobago-config-for-unit-tests.xml     |  35 ++++
 ...ller.java => DecorationPositionController.java} |  34 ++--
 .../100-position/decorationPosition.xhtml          | 117 +++++++++++++
 tobago-theme/src/main/scss/_tobago.scss            | 112 +++++++++---
 .../src/main/css/tobago.css                        | 195 +++++++++++++++++++--
 .../src/main/css/tobago.css.map                    |   2 +-
 .../src/main/css/tobago.min.css                    |   2 +-
 .../src/main/css/tobago.min.css.map                |   2 +-
 .../src/main/css/tobago.css                        | 195 +++++++++++++++++++--
 .../src/main/css/tobago.css.map                    |   2 +-
 .../src/main/css/tobago.min.css                    |   2 +-
 .../src/main/css/tobago.min.css.map                |   2 +-
 .../src/main/css/tobago.css                        | 195 +++++++++++++++++++--
 .../src/main/css/tobago.css.map                    |   2 +-
 .../src/main/css/tobago.min.css                    |   2 +-
 .../src/main/css/tobago.min.css.map                |   2 +-
 .../tobago-theme-speyside/src/main/css/tobago.css  | 194 ++++++++++++++++++--
 .../src/main/css/tobago.css.map                    |   2 +-
 .../src/main/css/tobago.min.css                    |   2 +-
 .../src/main/css/tobago.min.css.map                |   2 +-
 .../tobago-theme-standard/src/main/css/tobago.css  | 195 +++++++++++++++++++--
 .../src/main/css/tobago.css.map                    |   2 +-
 .../src/main/css/tobago.min.css                    |   2 +-
 .../src/main/css/tobago.min.css.map                |   2 +-
 .../src/main/resources/META-INF/tobago-config.xml  |  32 ++++
 .../org/apache/myfaces/tobago/apt/component.stg    |   4 +
 77 files changed, 1533 insertions(+), 246 deletions(-)
 copy tobago-core/src/main/java/org/apache/myfaces/tobago/component/{DeprecatedDimension.java => DecorationPosition.java} (62%)
 copy tobago-core/src/main/java/org/apache/myfaces/tobago/component/{SupportsDisabled.java => SupportsDecorationPosition.java} (86%)
 rename tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/{MessageLayoutRendererBase.java => DecorationPositionRendererBase.java} (62%)
 copy tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/declaration/{HasLabelLayout.java => HasDecorationPosition.java} (53%)
 copy tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/{FormRequiredController.java => DecorationPositionController.java} (57%)
 create mode 100644 tobago-example/tobago-example-demo/src/main/webapp/content/900-test/4900-messageLayout/100-position/decorationPosition.xhtml


[myfaces-tobago] 02/02: build(theme): rebuild after implementing message/help position attribute

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 1276941437d5bedaf4b035da05fdadcfb074035c
Author: Udo Schnurpfeil <lo...@apache.org>
AuthorDate: Thu Jan 12 13:51:44 2023 +0100

    build(theme): rebuild after implementing message/help position attribute
---
 .../src/main/css/tobago.css                        | 195 +++++++++++++++++++--
 .../src/main/css/tobago.css.map                    |   2 +-
 .../src/main/css/tobago.min.css                    |   2 +-
 .../src/main/css/tobago.min.css.map                |   2 +-
 .../src/main/css/tobago.css                        | 195 +++++++++++++++++++--
 .../src/main/css/tobago.css.map                    |   2 +-
 .../src/main/css/tobago.min.css                    |   2 +-
 .../src/main/css/tobago.min.css.map                |   2 +-
 .../src/main/css/tobago.css                        | 195 +++++++++++++++++++--
 .../src/main/css/tobago.css.map                    |   2 +-
 .../src/main/css/tobago.min.css                    |   2 +-
 .../src/main/css/tobago.min.css.map                |   2 +-
 .../tobago-theme-speyside/src/main/css/tobago.css  | 194 ++++++++++++++++++--
 .../src/main/css/tobago.css.map                    |   2 +-
 .../src/main/css/tobago.min.css                    |   2 +-
 .../src/main/css/tobago.min.css.map                |   2 +-
 .../tobago-theme-standard/src/main/css/tobago.css  | 195 +++++++++++++++++++--
 .../src/main/css/tobago.css.map                    |   2 +-
 .../src/main/css/tobago.min.css                    |   2 +-
 .../src/main/css/tobago.min.css.map                |   2 +-
 20 files changed, 919 insertions(+), 85 deletions(-)

diff --git a/tobago-theme/tobago-theme-charlotteville/src/main/css/tobago.css b/tobago-theme/tobago-theme-charlotteville/src/main/css/tobago.css
index 0ccc0ddfb7..c1ff7e86b9 100644
--- a/tobago-theme/tobago-theme-charlotteville/src/main/css/tobago.css
+++ b/tobago-theme/tobago-theme-charlotteville/src/main/css/tobago.css
@@ -11113,7 +11113,6 @@ tobago-flex-layout > tobago-flex-layout {
   margin-bottom: 0;
 }
 
-/* flowLayout ---------------------------------------------------------- */
 tobago-flow-layout {
   display: block;
 }
@@ -11127,7 +11126,6 @@ tobago-focus {
   display: none;
 }
 
-/* footer -------------------------------------------------------------- */
 tobago-footer {
   display: block;
   background-color: #ffffff;
@@ -11163,6 +11161,106 @@ tobago-header.sticky-top {
   margin-right: -0.75rem;
 }
 
+.tobago-help-container {
+  width: 100%;
+}
+.tobago-help-container .help-feedback {
+  display: none;
+  width: 100%;
+  margin-top: 0.25rem;
+  font-size: 0.875em;
+  color: #389c30;
+}
+.tobago-help-container .help-tooltip {
+  position: absolute;
+  top: 100%;
+  z-index: 5;
+  display: none;
+  max-width: 100%;
+  padding: 0.25rem 0.5rem;
+  margin-top: 0.1rem;
+  font-size: 0.875rem;
+  color: #000000;
+  background-color: rgba(56, 156, 48, 0.9);
+  border-radius: 0.375rem;
+}
+.tobago-help-container.is-help ~ .help-feedback,
+.tobago-help-container.is-help ~ .help-tooltip {
+  display: block;
+}
+.tobago-help-container .form-control.is-help {
+  border-color: #389c30;
+  padding-right: calc(1.5em + 0.75rem);
+  background-image: none;
+  background-repeat: no-repeat;
+  background-position: right calc(0.375em + 0.1875rem) center;
+  background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
+}
+.tobago-help-container .form-control.is-help:focus {
+  border-color: #389c30;
+  box-shadow: 0 0 0 0.25rem rgba(56, 156, 48, 0.25);
+}
+.tobago-help-container textarea.form-control.is-help {
+  padding-right: calc(1.5em + 0.75rem);
+  background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem);
+}
+.tobago-help-container .form-select.is-help {
+  border-color: #389c30;
+}
+.tobago-help-container .form-select.is-help:not([multiple]):not([size]), .tobago-help-container .form-select.is-help:not([multiple])[size="1"] {
+  padding-right: 4.125rem;
+  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23323232' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e"), none;
+  background-position: right 0.75rem center, center right 2.25rem;
+  background-size: 16px 12px, calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
+}
+.tobago-help-container .form-select.is-help:focus {
+  border-color: #389c30;
+  box-shadow: 0 0 0 0.25rem rgba(56, 156, 48, 0.25);
+}
+.tobago-help-container .form-control-color.is-help {
+  width: calc(3rem + calc(1.5em + 0.75rem));
+}
+.tobago-help-container .form-check-input.is-help {
+  border-color: #389c30;
+}
+.tobago-help-container .form-check-input.is-help:checked {
+  background-color: #389c30;
+}
+.tobago-help-container .form-check-input.is-help:focus {
+  box-shadow: 0 0 0 0.25rem rgba(56, 156, 48, 0.25);
+}
+.tobago-help-container .form-check-input.is-help ~ .form-check-label {
+  color: #389c30;
+}
+.tobago-help-container .form-check-inline .form-check-input ~ .help-feedback {
+  margin-left: 0.5em;
+}
+.tobago-help-container.tobago-button-left, .tobago-help-container.tobago-button-right {
+  display: flex;
+  align-items: flex-start;
+}
+.tobago-help-container.tobago-button-left.tobago-button-left > tobago-popover, .tobago-help-container.tobago-button-right.tobago-button-left > tobago-popover {
+  margin-right: 0.75rem;
+}
+.tobago-help-container.tobago-button-left.tobago-button-right > tobago-popover, .tobago-help-container.tobago-button-right.tobago-button-right > tobago-popover {
+  margin-left: 0.75rem;
+}
+.tobago-help-container.tobago-button-left tobago-popover > a, .tobago-help-container.tobago-button-right tobago-popover > a {
+  --bs-btn-padding-x: .4rem;
+}
+.tobago-help-container.tobago-tooltip {
+  position: relative;
+}
+.tobago-help-container.tobago-tooltip .help-tooltip {
+  display: block;
+}
+.tobago-help-container.tobago-text-top .help-feedback, .tobago-help-container.tobago-text-bottom .help-feedback {
+  display: block;
+}
+.tobago-help-container.tobago-text-top .help-feedback {
+  margin-bottom: 0.25rem;
+}
+
 /* image ----------------------------------------------------------- */
 tobago-image.disabled {
   filter: grayscale(1) blur(2px) contrast(0.5) brightness(1.2);
@@ -11331,10 +11429,8 @@ button.nav-link { /* bootstrap don't know button.nav-link*/
   padding-right: 0;
 }
 
-/* messages / help text ----------------------------------------------- */
 .tobago-messages-container {
-  display: flex;
-  align-items: flex-start;
+  width: 100%;
 }
 .tobago-messages-container .error-feedback {
   display: none;
@@ -11362,18 +11458,36 @@ button.nav-link { /* bootstrap don't know button.nav-link*/
 }
 .tobago-messages-container .form-control.is-error {
   border-color: #ff00be;
+  padding-right: calc(1.5em + 0.75rem);
+  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23ff00be'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23ff00be' stroke='none'/%3e%3c/svg%3e");
+  background-repeat: no-repeat;
+  background-position: right calc(0.375em + 0.1875rem) center;
+  background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
 }
 .tobago-messages-container .form-control.is-error:focus {
   border-color: #ff00be;
   box-shadow: 0 0 0 0.25rem rgba(255, 0, 190, 0.25);
 }
+.tobago-messages-container textarea.form-control.is-error {
+  padding-right: calc(1.5em + 0.75rem);
+  background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem);
+}
 .tobago-messages-container .form-select.is-error {
   border-color: #ff00be;
 }
+.tobago-messages-container .form-select.is-error:not([multiple]):not([size]), .tobago-messages-container .form-select.is-error:not([multiple])[size="1"] {
+  padding-right: 4.125rem;
+  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23323232' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e"), url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23ff00be'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx [...]
+  background-position: right 0.75rem center, center right 2.25rem;
+  background-size: 16px 12px, calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
+}
 .tobago-messages-container .form-select.is-error:focus {
   border-color: #ff00be;
   box-shadow: 0 0 0 0.25rem rgba(255, 0, 190, 0.25);
 }
+.tobago-messages-container .form-control-color.is-error {
+  width: calc(3rem + calc(1.5em + 0.75rem));
+}
 .tobago-messages-container .form-check-input.is-error {
   border-color: #ff00be;
 }
@@ -11415,18 +11529,36 @@ button.nav-link { /* bootstrap don't know button.nav-link*/
 }
 .tobago-messages-container .form-control.is-warning {
   border-color: #ff00be;
+  padding-right: calc(1.5em + 0.75rem);
+  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23ff00be'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23ff00be' stroke='none'/%3e%3c/svg%3e");
+  background-repeat: no-repeat;
+  background-position: right calc(0.375em + 0.1875rem) center;
+  background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
 }
 .tobago-messages-container .form-control.is-warning:focus {
   border-color: #ff00be;
   box-shadow: 0 0 0 0.25rem rgba(255, 0, 190, 0.25);
 }
+.tobago-messages-container textarea.form-control.is-warning {
+  padding-right: calc(1.5em + 0.75rem);
+  background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem);
+}
 .tobago-messages-container .form-select.is-warning {
   border-color: #ff00be;
 }
+.tobago-messages-container .form-select.is-warning:not([multiple]):not([size]), .tobago-messages-container .form-select.is-warning:not([multiple])[size="1"] {
+  padding-right: 4.125rem;
+  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23323232' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e"), url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23ff00be'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx [...]
+  background-position: right 0.75rem center, center right 2.25rem;
+  background-size: 16px 12px, calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
+}
 .tobago-messages-container .form-select.is-warning:focus {
   border-color: #ff00be;
   box-shadow: 0 0 0 0.25rem rgba(255, 0, 190, 0.25);
 }
+.tobago-messages-container .form-control-color.is-warning {
+  width: calc(3rem + calc(1.5em + 0.75rem));
+}
 .tobago-messages-container .form-check-input.is-warning {
   border-color: #ff00be;
 }
@@ -11468,18 +11600,36 @@ button.nav-link { /* bootstrap don't know button.nav-link*/
 }
 .tobago-messages-container .form-control.is-info {
   border-color: #389c30;
+  padding-right: calc(1.5em + 0.75rem);
+  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23389c30'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23389c30' stroke='none'/%3e%3c/svg%3e");
+  background-repeat: no-repeat;
+  background-position: right calc(0.375em + 0.1875rem) center;
+  background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
 }
 .tobago-messages-container .form-control.is-info:focus {
   border-color: #389c30;
   box-shadow: 0 0 0 0.25rem rgba(56, 156, 48, 0.25);
 }
+.tobago-messages-container textarea.form-control.is-info {
+  padding-right: calc(1.5em + 0.75rem);
+  background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem);
+}
 .tobago-messages-container .form-select.is-info {
   border-color: #389c30;
 }
+.tobago-messages-container .form-select.is-info:not([multiple]):not([size]), .tobago-messages-container .form-select.is-info:not([multiple])[size="1"] {
+  padding-right: 4.125rem;
+  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23323232' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e"), url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23389c30'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx [...]
+  background-position: right 0.75rem center, center right 2.25rem;
+  background-size: 16px 12px, calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
+}
 .tobago-messages-container .form-select.is-info:focus {
   border-color: #389c30;
   box-shadow: 0 0 0 0.25rem rgba(56, 156, 48, 0.25);
 }
+.tobago-messages-container .form-control-color.is-info {
+  width: calc(3rem + calc(1.5em + 0.75rem));
+}
 .tobago-messages-container .form-check-input.is-info {
   border-color: #389c30;
 }
@@ -11495,16 +11645,34 @@ button.nav-link { /* bootstrap don't know button.nav-link*/
 .tobago-messages-container .form-check-inline .form-check-input ~ .info-feedback {
   margin-left: 0.5em;
 }
-.tobago-messages-container .tobago-messages:first-child small label, .tobago-messages-container .tobago-messages:first-child .small label {
-  margin-right: 0; /* for tc:in margin 5px is already set */
-  margin-bottom: 5px;
+.tobago-messages-container.tobago-button-left, .tobago-messages-container.tobago-button-right {
+  display: flex;
+  align-items: flex-start;
+}
+.tobago-messages-container.tobago-button-left.tobago-button-left > tobago-popover, .tobago-messages-container.tobago-button-right.tobago-button-left > tobago-popover {
+  margin-right: 0.75rem;
 }
-.tobago-messages-container tobago-popover {
+.tobago-messages-container.tobago-button-left.tobago-button-right > tobago-popover, .tobago-messages-container.tobago-button-right.tobago-button-right > tobago-popover {
   margin-left: 0.75rem;
 }
-.tobago-messages-container tobago-popover .btn {
-  padding-left: 0.4rem;
-  padding-right: 0.4rem;
+.tobago-messages-container.tobago-button-left tobago-popover > a, .tobago-messages-container.tobago-button-right tobago-popover > a {
+  --bs-btn-padding-x: .4rem;
+}
+.tobago-messages-container.tobago-tooltip {
+  position: relative;
+}
+.tobago-messages-container.tobago-button-left .form-control, .tobago-messages-container.tobago-button-right .form-control {
+  padding-right: 0.75rem;
+  background-image: none;
+}
+.tobago-messages-container.tobago-tooltip .error-tooltip, .tobago-messages-container.tobago-tooltip .warning-tooltip, .tobago-messages-container.tobago-tooltip .info-tooltip {
+  display: block;
+}
+.tobago-messages-container.tobago-text-top .error-feedback, .tobago-messages-container.tobago-text-top .warning-feedback, .tobago-messages-container.tobago-text-top .info-feedback, .tobago-messages-container.tobago-text-bottom .error-feedback, .tobago-messages-container.tobago-text-bottom .warning-feedback, .tobago-messages-container.tobago-text-bottom .info-feedback {
+  display: block;
+}
+.tobago-messages-container.tobago-text-top .error-feedback, .tobago-messages-container.tobago-text-top .warning-feedback, .tobago-messages-container.tobago-text-top .info-feedback {
+  margin-bottom: 0.25rem;
 }
 
 .tobago-popover-box {
@@ -11549,7 +11717,6 @@ tobago-messages .alert.alert-dismissible.alert-warning:before {
 tobago-messages .alert.alert-dismissible.alert-info:before {
   content: "\f646";
 }
-
 .popover .popover-body {
   white-space: pre-line;
 }
@@ -12031,7 +12198,7 @@ tobago-select-many-shuttle .tobago-body .tobago-unselected:disabled option, toba
 tobago-select-many-shuttle .tobago-body .tobago-selected:disabled option, tobago-select-many-shuttle .tobago-body .tobago-selected option:disabled {
   color: rgba(160, 160, 160, 0.5);
 }
-tobago-select-many-shuttle.tobago-label-container > .tobago-body, tobago-select-many-shuttle .tobago-messages-container > .tobago-body {
+tobago-select-many-shuttle.tobago-label-container > .tobago-body, tobago-select-many-shuttle .tobago-help-container > .tobago-body, tobago-select-many-shuttle .tobago-messages-container > .tobago-body {
   flex: 1 0 0px;
 }
 
diff --git a/tobago-theme/tobago-theme-charlotteville/src/main/css/tobago.css.map b/tobago-theme/tobago-theme-charlotteville/src/main/css/tobago.css.map
index 98c7fb3f5e..873cc8d4fa 100644
--- a/tobago-theme/tobago-theme-charlotteville/src/main/css/tobago.css.map
+++ b/tobago-theme/tobago-theme-charlotteville/src/main/css/tobago.css.map
@@ -1 +1 @@
-{"version":3,"sources":["tobago.css","../scss/tobago-theme.scss","../scss/_custom.scss","../../../../node_modules/bootstrap/scss/mixins/_banner.scss","../../../../node_modules/bootstrap/scss/_root.scss","../../../../node_modules/bootstrap/scss/vendor/_rfs.scss","../../../../node_modules/bootstrap/scss/_reboot.scss","../../../../node_modules/bootstrap/scss/_variables.scss","../../../../node_modules/bootstrap/scss/mixins/_border-radius.scss","../../../../node_modules/bootstrap/scss/_type.s [...]
\ No newline at end of file
+{"version":3,"sources":["tobago.css","../scss/tobago-theme.scss","../scss/_custom.scss","../../../../node_modules/bootstrap/scss/mixins/_banner.scss","../../../../node_modules/bootstrap/scss/_root.scss","../../../../node_modules/bootstrap/scss/vendor/_rfs.scss","../../../../node_modules/bootstrap/scss/_reboot.scss","../../../../node_modules/bootstrap/scss/_variables.scss","../../../../node_modules/bootstrap/scss/mixins/_border-radius.scss","../../../../node_modules/bootstrap/scss/_type.s [...]
\ No newline at end of file
diff --git a/tobago-theme/tobago-theme-charlotteville/src/main/css/tobago.min.css b/tobago-theme/tobago-theme-charlotteville/src/main/css/tobago.min.css
index dc46104063..08c03a4ffe 100644
--- a/tobago-theme/tobago-theme-charlotteville/src/main/css/tobago.min.css
+++ b/tobago-theme/tobago-theme-charlotteville/src/main/css/tobago.min.css
@@ -1,2 +1,2 @@
-@charset "UTF-8";:root{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#ff00be;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-black:#000000;--bs-white:#ffffff;--bs-gray:#777777;--bs-gray-dark:#323232;--bs-gray-100:#f8f9fa;--bs-gray-200:#d0d0d0;--bs-gray-300:#dee2e6;--bs-gray-400:#a0a0a0;--bs-gray-500:#adb5bd;--bs-gray-600:#777777;--bs-gray-700:#495057;--bs-gray-800:#323232;--bs-gray-900:#212529;--bs [...]
+@charset "UTF-8";:root{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#ff00be;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-black:#000000;--bs-white:#ffffff;--bs-gray:#777777;--bs-gray-dark:#323232;--bs-gray-100:#f8f9fa;--bs-gray-200:#d0d0d0;--bs-gray-300:#dee2e6;--bs-gray-400:#a0a0a0;--bs-gray-500:#adb5bd;--bs-gray-600:#777777;--bs-gray-700:#495057;--bs-gray-800:#323232;--bs-gray-900:#212529;--bs [...]
 /*# sourceMappingURL=tobago.min.css.map */
\ No newline at end of file
diff --git a/tobago-theme/tobago-theme-charlotteville/src/main/css/tobago.min.css.map b/tobago-theme/tobago-theme-charlotteville/src/main/css/tobago.min.css.map
index 01844811ca..7ff8db6f13 100644
--- a/tobago-theme/tobago-theme-charlotteville/src/main/css/tobago.min.css.map
+++ b/tobago-theme/tobago-theme-charlotteville/src/main/css/tobago.min.css.map
@@ -1 +1 @@
-{"version":3,"sources":["tobago-theme-charlotteville/src/main/css/tobago.css"],"names":[],"mappings":"iBAuCA,MACE,UAAW,QACX,YAAa,QACb,YAAa,QACb,UAAW,QACX,SAAU,QACV,YAAa,QACb,YAAa,QACb,WAAY,QACZ,UAAW,QACX,UAAW,QACX,WAAY,QACZ,WAAY,QACZ,UAAW,QACX,eAAgB,QAChB,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,aAAc,QACd,eAAgB,QAChB,aAAc,QACd,UAAW,QACX,aAAc,QACd,YAAa,QACb,WAAY,QACZ,UAAW,QACX,iBAAkB,EAAE,CAAE,GAAG,CAAE,IAC3B,mBAAoB,GAAG,CAAE,GAAG,CAAE,IAC9 [...]
\ No newline at end of file
+{"version":3,"sources":["tobago-theme-charlotteville/src/main/css/tobago.css"],"names":[],"mappings":"iBAuCA,MACE,UAAW,QACX,YAAa,QACb,YAAa,QACb,UAAW,QACX,SAAU,QACV,YAAa,QACb,YAAa,QACb,WAAY,QACZ,UAAW,QACX,UAAW,QACX,WAAY,QACZ,WAAY,QACZ,UAAW,QACX,eAAgB,QAChB,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,aAAc,QACd,eAAgB,QAChB,aAAc,QACd,UAAW,QACX,aAAc,QACd,YAAa,QACb,WAAY,QACZ,UAAW,QACX,iBAAkB,EAAE,CAAE,GAAG,CAAE,IAC3B,mBAAoB,GAAG,CAAE,GAAG,CAAE,IAC9 [...]
\ No newline at end of file
diff --git a/tobago-theme/tobago-theme-roxborough/src/main/css/tobago.css b/tobago-theme/tobago-theme-roxborough/src/main/css/tobago.css
index 9c3cb898f4..157a98a917 100644
--- a/tobago-theme/tobago-theme-roxborough/src/main/css/tobago.css
+++ b/tobago-theme/tobago-theme-roxborough/src/main/css/tobago.css
@@ -11140,7 +11140,6 @@ tobago-flex-layout > tobago-flex-layout {
   margin-bottom: 0;
 }
 
-/* flowLayout ---------------------------------------------------------- */
 tobago-flow-layout {
   display: block;
 }
@@ -11154,7 +11153,6 @@ tobago-focus {
   display: none;
 }
 
-/* footer -------------------------------------------------------------- */
 tobago-footer {
   display: block;
   background-color: #fff;
@@ -11190,6 +11188,106 @@ tobago-header.sticky-top {
   margin-right: -0.75rem;
 }
 
+.tobago-help-container {
+  width: 100%;
+}
+.tobago-help-container .help-feedback {
+  display: none;
+  width: 100%;
+  margin-top: 0.25rem;
+  font-size: 0.875em;
+  color: #130E8F;
+}
+.tobago-help-container .help-tooltip {
+  position: absolute;
+  top: 100%;
+  z-index: 5;
+  display: none;
+  max-width: 100%;
+  padding: 0.25rem 0.5rem;
+  margin-top: 0.1rem;
+  font-size: 0.875rem;
+  color: #fff;
+  background-color: rgba(19, 14, 143, 0.9);
+  border-radius: 0.375rem;
+}
+.tobago-help-container.is-help ~ .help-feedback,
+.tobago-help-container.is-help ~ .help-tooltip {
+  display: block;
+}
+.tobago-help-container .form-control.is-help {
+  border-color: #130E8F;
+  padding-right: calc(1.5em + 0.75rem);
+  background-image: none;
+  background-repeat: no-repeat;
+  background-position: right calc(0.375em + 0.1875rem) center;
+  background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
+}
+.tobago-help-container .form-control.is-help:focus {
+  border-color: #130E8F;
+  box-shadow: 0 0 0 0.25rem rgba(19, 14, 143, 0.25);
+}
+.tobago-help-container textarea.form-control.is-help {
+  padding-right: calc(1.5em + 0.75rem);
+  background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem);
+}
+.tobago-help-container .form-select.is-help {
+  border-color: #130E8F;
+}
+.tobago-help-container .form-select.is-help:not([multiple]):not([size]), .tobago-help-container .form-select.is-help:not([multiple])[size="1"] {
+  padding-right: 4.125rem;
+  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23323232' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e"), none;
+  background-position: right 0.75rem center, center right 2.25rem;
+  background-size: 16px 12px, calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
+}
+.tobago-help-container .form-select.is-help:focus {
+  border-color: #130E8F;
+  box-shadow: 0 0 0 0.25rem rgba(19, 14, 143, 0.25);
+}
+.tobago-help-container .form-control-color.is-help {
+  width: calc(3rem + calc(1.5em + 0.75rem));
+}
+.tobago-help-container .form-check-input.is-help {
+  border-color: #130E8F;
+}
+.tobago-help-container .form-check-input.is-help:checked {
+  background-color: #130E8F;
+}
+.tobago-help-container .form-check-input.is-help:focus {
+  box-shadow: 0 0 0 0.25rem rgba(19, 14, 143, 0.25);
+}
+.tobago-help-container .form-check-input.is-help ~ .form-check-label {
+  color: #130E8F;
+}
+.tobago-help-container .form-check-inline .form-check-input ~ .help-feedback {
+  margin-left: 0.5em;
+}
+.tobago-help-container.tobago-button-left, .tobago-help-container.tobago-button-right {
+  display: flex;
+  align-items: flex-start;
+}
+.tobago-help-container.tobago-button-left.tobago-button-left > tobago-popover, .tobago-help-container.tobago-button-right.tobago-button-left > tobago-popover {
+  margin-right: 0.75rem;
+}
+.tobago-help-container.tobago-button-left.tobago-button-right > tobago-popover, .tobago-help-container.tobago-button-right.tobago-button-right > tobago-popover {
+  margin-left: 0.75rem;
+}
+.tobago-help-container.tobago-button-left tobago-popover > a, .tobago-help-container.tobago-button-right tobago-popover > a {
+  --bs-btn-padding-x: .4rem;
+}
+.tobago-help-container.tobago-tooltip {
+  position: relative;
+}
+.tobago-help-container.tobago-tooltip .help-tooltip {
+  display: block;
+}
+.tobago-help-container.tobago-text-top .help-feedback, .tobago-help-container.tobago-text-bottom .help-feedback {
+  display: block;
+}
+.tobago-help-container.tobago-text-top .help-feedback {
+  margin-bottom: 0.25rem;
+}
+
 /* image ----------------------------------------------------------- */
 tobago-image.disabled {
   filter: grayscale(1) blur(2px) contrast(0.5) brightness(1.2);
@@ -11358,10 +11456,8 @@ button.nav-link { /* bootstrap don't know button.nav-link*/
   padding-right: 0;
 }
 
-/* messages / help text ----------------------------------------------- */
 .tobago-messages-container {
-  display: flex;
-  align-items: flex-start;
+  width: 100%;
 }
 .tobago-messages-container .error-feedback {
   display: none;
@@ -11389,18 +11485,36 @@ button.nav-link { /* bootstrap don't know button.nav-link*/
 }
 .tobago-messages-container .form-control.is-error {
   border-color: #ffb243;
+  padding-right: calc(1.5em + 0.75rem);
+  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23ffb243'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23ffb243' stroke='none'/%3e%3c/svg%3e");
+  background-repeat: no-repeat;
+  background-position: right calc(0.375em + 0.1875rem) center;
+  background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
 }
 .tobago-messages-container .form-control.is-error:focus {
   border-color: #ffb243;
   box-shadow: 0 0 0 0.25rem rgba(255, 178, 67, 0.25);
 }
+.tobago-messages-container textarea.form-control.is-error {
+  padding-right: calc(1.5em + 0.75rem);
+  background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem);
+}
 .tobago-messages-container .form-select.is-error {
   border-color: #ffb243;
 }
+.tobago-messages-container .form-select.is-error:not([multiple]):not([size]), .tobago-messages-container .form-select.is-error:not([multiple])[size="1"] {
+  padding-right: 4.125rem;
+  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23323232' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e"), url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23ffb243'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx [...]
+  background-position: right 0.75rem center, center right 2.25rem;
+  background-size: 16px 12px, calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
+}
 .tobago-messages-container .form-select.is-error:focus {
   border-color: #ffb243;
   box-shadow: 0 0 0 0.25rem rgba(255, 178, 67, 0.25);
 }
+.tobago-messages-container .form-control-color.is-error {
+  width: calc(3rem + calc(1.5em + 0.75rem));
+}
 .tobago-messages-container .form-check-input.is-error {
   border-color: #ffb243;
 }
@@ -11442,18 +11556,36 @@ button.nav-link { /* bootstrap don't know button.nav-link*/
 }
 .tobago-messages-container .form-control.is-warning {
   border-color: #B26812;
+  padding-right: calc(1.5em + 0.75rem);
+  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23B26812'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23B26812' stroke='none'/%3e%3c/svg%3e");
+  background-repeat: no-repeat;
+  background-position: right calc(0.375em + 0.1875rem) center;
+  background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
 }
 .tobago-messages-container .form-control.is-warning:focus {
   border-color: #B26812;
   box-shadow: 0 0 0 0.25rem rgba(178, 104, 18, 0.25);
 }
+.tobago-messages-container textarea.form-control.is-warning {
+  padding-right: calc(1.5em + 0.75rem);
+  background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem);
+}
 .tobago-messages-container .form-select.is-warning {
   border-color: #B26812;
 }
+.tobago-messages-container .form-select.is-warning:not([multiple]):not([size]), .tobago-messages-container .form-select.is-warning:not([multiple])[size="1"] {
+  padding-right: 4.125rem;
+  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23323232' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e"), url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23B26812'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx [...]
+  background-position: right 0.75rem center, center right 2.25rem;
+  background-size: 16px 12px, calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
+}
 .tobago-messages-container .form-select.is-warning:focus {
   border-color: #B26812;
   box-shadow: 0 0 0 0.25rem rgba(178, 104, 18, 0.25);
 }
+.tobago-messages-container .form-control-color.is-warning {
+  width: calc(3rem + calc(1.5em + 0.75rem));
+}
 .tobago-messages-container .form-check-input.is-warning {
   border-color: #B26812;
 }
@@ -11495,18 +11627,36 @@ button.nav-link { /* bootstrap don't know button.nav-link*/
 }
 .tobago-messages-container .form-control.is-info {
   border-color: #130E8F;
+  padding-right: calc(1.5em + 0.75rem);
+  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23130E8F'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23130E8F' stroke='none'/%3e%3c/svg%3e");
+  background-repeat: no-repeat;
+  background-position: right calc(0.375em + 0.1875rem) center;
+  background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
 }
 .tobago-messages-container .form-control.is-info:focus {
   border-color: #130E8F;
   box-shadow: 0 0 0 0.25rem rgba(19, 14, 143, 0.25);
 }
+.tobago-messages-container textarea.form-control.is-info {
+  padding-right: calc(1.5em + 0.75rem);
+  background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem);
+}
 .tobago-messages-container .form-select.is-info {
   border-color: #130E8F;
 }
+.tobago-messages-container .form-select.is-info:not([multiple]):not([size]), .tobago-messages-container .form-select.is-info:not([multiple])[size="1"] {
+  padding-right: 4.125rem;
+  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23323232' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e"), url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23130E8F'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx [...]
+  background-position: right 0.75rem center, center right 2.25rem;
+  background-size: 16px 12px, calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
+}
 .tobago-messages-container .form-select.is-info:focus {
   border-color: #130E8F;
   box-shadow: 0 0 0 0.25rem rgba(19, 14, 143, 0.25);
 }
+.tobago-messages-container .form-control-color.is-info {
+  width: calc(3rem + calc(1.5em + 0.75rem));
+}
 .tobago-messages-container .form-check-input.is-info {
   border-color: #130E8F;
 }
@@ -11522,16 +11672,34 @@ button.nav-link { /* bootstrap don't know button.nav-link*/
 .tobago-messages-container .form-check-inline .form-check-input ~ .info-feedback {
   margin-left: 0.5em;
 }
-.tobago-messages-container .tobago-messages:first-child small label, .tobago-messages-container .tobago-messages:first-child .small label {
-  margin-right: 0; /* for tc:in margin 5px is already set */
-  margin-bottom: 5px;
+.tobago-messages-container.tobago-button-left, .tobago-messages-container.tobago-button-right {
+  display: flex;
+  align-items: flex-start;
+}
+.tobago-messages-container.tobago-button-left.tobago-button-left > tobago-popover, .tobago-messages-container.tobago-button-right.tobago-button-left > tobago-popover {
+  margin-right: 0.75rem;
 }
-.tobago-messages-container tobago-popover {
+.tobago-messages-container.tobago-button-left.tobago-button-right > tobago-popover, .tobago-messages-container.tobago-button-right.tobago-button-right > tobago-popover {
   margin-left: 0.75rem;
 }
-.tobago-messages-container tobago-popover .btn {
-  padding-left: 0.4rem;
-  padding-right: 0.4rem;
+.tobago-messages-container.tobago-button-left tobago-popover > a, .tobago-messages-container.tobago-button-right tobago-popover > a {
+  --bs-btn-padding-x: .4rem;
+}
+.tobago-messages-container.tobago-tooltip {
+  position: relative;
+}
+.tobago-messages-container.tobago-button-left .form-control, .tobago-messages-container.tobago-button-right .form-control {
+  padding-right: 0.75rem;
+  background-image: none;
+}
+.tobago-messages-container.tobago-tooltip .error-tooltip, .tobago-messages-container.tobago-tooltip .warning-tooltip, .tobago-messages-container.tobago-tooltip .info-tooltip {
+  display: block;
+}
+.tobago-messages-container.tobago-text-top .error-feedback, .tobago-messages-container.tobago-text-top .warning-feedback, .tobago-messages-container.tobago-text-top .info-feedback, .tobago-messages-container.tobago-text-bottom .error-feedback, .tobago-messages-container.tobago-text-bottom .warning-feedback, .tobago-messages-container.tobago-text-bottom .info-feedback {
+  display: block;
+}
+.tobago-messages-container.tobago-text-top .error-feedback, .tobago-messages-container.tobago-text-top .warning-feedback, .tobago-messages-container.tobago-text-top .info-feedback {
+  margin-bottom: 0.25rem;
 }
 
 .tobago-popover-box {
@@ -11576,7 +11744,6 @@ tobago-messages .alert.alert-dismissible.alert-warning:before {
 tobago-messages .alert.alert-dismissible.alert-info:before {
   content: "\f646";
 }
-
 .popover .popover-body {
   white-space: pre-line;
 }
@@ -12058,7 +12225,7 @@ tobago-select-many-shuttle .tobago-body .tobago-unselected:disabled option, toba
 tobago-select-many-shuttle .tobago-body .tobago-selected:disabled option, tobago-select-many-shuttle .tobago-body .tobago-selected option:disabled {
   color: rgba(160, 160, 160, 0.5);
 }
-tobago-select-many-shuttle.tobago-label-container > .tobago-body, tobago-select-many-shuttle .tobago-messages-container > .tobago-body {
+tobago-select-many-shuttle.tobago-label-container > .tobago-body, tobago-select-many-shuttle .tobago-help-container > .tobago-body, tobago-select-many-shuttle .tobago-messages-container > .tobago-body {
   flex: 1 0 0px;
 }
 
diff --git a/tobago-theme/tobago-theme-roxborough/src/main/css/tobago.css.map b/tobago-theme/tobago-theme-roxborough/src/main/css/tobago.css.map
index 50c43956c7..53c4cb9616 100644
--- a/tobago-theme/tobago-theme-roxborough/src/main/css/tobago.css.map
+++ b/tobago-theme/tobago-theme-roxborough/src/main/css/tobago.css.map
@@ -1 +1 @@
-{"version":3,"sources":["tobago.css","../scss/tobago-theme.scss","../scss/_custom.scss","../../../../node_modules/bootstrap/scss/mixins/_banner.scss","../../../../node_modules/bootstrap/scss/_root.scss","../../../../node_modules/bootstrap/scss/vendor/_rfs.scss","../../../../node_modules/bootstrap/scss/_reboot.scss","../../../../node_modules/bootstrap/scss/_variables.scss","../../../../node_modules/bootstrap/scss/mixins/_border-radius.scss","../../../../node_modules/bootstrap/scss/_type.s [...]
\ No newline at end of file
+{"version":3,"sources":["tobago.css","../scss/tobago-theme.scss","../scss/_custom.scss","../../../../node_modules/bootstrap/scss/mixins/_banner.scss","../../../../node_modules/bootstrap/scss/_root.scss","../../../../node_modules/bootstrap/scss/vendor/_rfs.scss","../../../../node_modules/bootstrap/scss/_reboot.scss","../../../../node_modules/bootstrap/scss/_variables.scss","../../../../node_modules/bootstrap/scss/mixins/_border-radius.scss","../../../../node_modules/bootstrap/scss/_type.s [...]
\ No newline at end of file
diff --git a/tobago-theme/tobago-theme-roxborough/src/main/css/tobago.min.css b/tobago-theme/tobago-theme-roxborough/src/main/css/tobago.min.css
index 241ab9dc49..da98d421c0 100644
--- a/tobago-theme/tobago-theme-roxborough/src/main/css/tobago.min.css
+++ b/tobago-theme/tobago-theme-roxborough/src/main/css/tobago.min.css
@@ -1,2 +1,2 @@
-@charset "UTF-8";@font-face{font-family:Amaranth;font-style:normal;font-weight:400;src:url("../fonts/Amaranth-Regular.otf") format("opentype")}@font-face{font-family:Amaranth;font-style:normal;font-weight:700;src:url("../fonts/Amaranth-Bold.otf") format("opentype")}@font-face{font-family:Amaranth;font-style:italic;src:url("../fonts/Amaranth-Italic.otf") format("opentype")}@font-face{font-family:Amaranth;font-style:italic;font-weight:700;src:url("../fonts/Amaranth-BoldItalic.otf") format( [...]
+@charset "UTF-8";@font-face{font-family:Amaranth;font-style:normal;font-weight:400;src:url("../fonts/Amaranth-Regular.otf") format("opentype")}@font-face{font-family:Amaranth;font-style:normal;font-weight:700;src:url("../fonts/Amaranth-Bold.otf") format("opentype")}@font-face{font-family:Amaranth;font-style:italic;src:url("../fonts/Amaranth-Italic.otf") format("opentype")}@font-face{font-family:Amaranth;font-style:italic;font-weight:700;src:url("../fonts/Amaranth-BoldItalic.otf") format( [...]
 /*# sourceMappingURL=tobago.min.css.map */
\ No newline at end of file
diff --git a/tobago-theme/tobago-theme-roxborough/src/main/css/tobago.min.css.map b/tobago-theme/tobago-theme-roxborough/src/main/css/tobago.min.css.map
index fa41575591..18fbb5acc1 100644
--- a/tobago-theme/tobago-theme-roxborough/src/main/css/tobago.min.css.map
+++ b/tobago-theme/tobago-theme-roxborough/src/main/css/tobago.min.css.map
@@ -1 +1 @@
-{"version":3,"sources":["tobago-theme-roxborough/src/main/css/tobago.css"],"names":[],"mappings":"iBAiCA,WACE,YAAa,SACb,WAAY,OACZ,YAAa,IACb,IAAK,qCAAqC,mBAE5C,WACE,YAAa,SACb,WAAY,OACZ,YAAa,IACb,IAAK,kCAAkC,mBAEzC,WACE,YAAa,SACb,WAAY,OACZ,IAAK,oCAAoC,mBAE3C,WACE,YAAa,SACb,WAAY,OACZ,YAAa,IACb,IAAK,wCAAwC,mBAE/C,mBACE,YAAa,QAAQ,CAAE,KAAK,CAAE,MAShC,MACE,UAAW,QACX,YAAa,QACb,YAAa,QACb,UAAW,QACX,SAAU,QACV,YAAa,QACb,YAAa,QACb,WAAY,QACZ,UAAW,QACX,UAAW,QACX,WAAY,QACZ,WAAY,KACZ,UAAW,QACX,eAAgB,QAC [...]
\ No newline at end of file
+{"version":3,"sources":["tobago-theme-roxborough/src/main/css/tobago.css"],"names":[],"mappings":"iBAiCA,WACE,YAAa,SACb,WAAY,OACZ,YAAa,IACb,IAAK,qCAAqC,mBAE5C,WACE,YAAa,SACb,WAAY,OACZ,YAAa,IACb,IAAK,kCAAkC,mBAEzC,WACE,YAAa,SACb,WAAY,OACZ,IAAK,oCAAoC,mBAE3C,WACE,YAAa,SACb,WAAY,OACZ,YAAa,IACb,IAAK,wCAAwC,mBAE/C,mBACE,YAAa,QAAQ,CAAE,KAAK,CAAE,MAShC,MACE,UAAW,QACX,YAAa,QACb,YAAa,QACb,UAAW,QACX,SAAU,QACV,YAAa,QACb,YAAa,QACb,WAAY,QACZ,UAAW,QACX,UAAW,QACX,WAAY,QACZ,WAAY,KACZ,UAAW,QACX,eAAgB,QAC [...]
\ No newline at end of file
diff --git a/tobago-theme/tobago-theme-scarborough/src/main/css/tobago.css b/tobago-theme/tobago-theme-scarborough/src/main/css/tobago.css
index 58fa0a9b64..21a89b5c0d 100644
--- a/tobago-theme/tobago-theme-scarborough/src/main/css/tobago.css
+++ b/tobago-theme/tobago-theme-scarborough/src/main/css/tobago.css
@@ -11114,7 +11114,6 @@ tobago-flex-layout > tobago-flex-layout {
   margin-bottom: 0;
 }
 
-/* flowLayout ---------------------------------------------------------- */
 tobago-flow-layout {
   display: block;
 }
@@ -11128,7 +11127,6 @@ tobago-focus {
   display: none;
 }
 
-/* footer -------------------------------------------------------------- */
 tobago-footer {
   display: block;
   background-color: #fff;
@@ -11164,6 +11162,106 @@ tobago-header.sticky-top {
   margin-right: -0.75rem;
 }
 
+.tobago-help-container {
+  width: 100%;
+}
+.tobago-help-container .help-feedback {
+  display: none;
+  width: 100%;
+  margin-top: 0.25rem;
+  font-size: 0.875em;
+  color: #0dcaf0;
+}
+.tobago-help-container .help-tooltip {
+  position: absolute;
+  top: 100%;
+  z-index: 5;
+  display: none;
+  max-width: 100%;
+  padding: 0.25rem 0.5rem;
+  margin-top: 0.1rem;
+  font-size: 0.875rem;
+  color: #000;
+  background-color: rgba(13, 202, 240, 0.9);
+  border-radius: 0.375rem;
+}
+.tobago-help-container.is-help ~ .help-feedback,
+.tobago-help-container.is-help ~ .help-tooltip {
+  display: block;
+}
+.tobago-help-container .form-control.is-help {
+  border-color: #0dcaf0;
+  padding-right: calc(1.5em + 0.75rem);
+  background-image: none;
+  background-repeat: no-repeat;
+  background-position: right calc(0.375em + 0.1875rem) center;
+  background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
+}
+.tobago-help-container .form-control.is-help:focus {
+  border-color: #0dcaf0;
+  box-shadow: 0 0 0 0.25rem rgba(13, 202, 240, 0.25);
+}
+.tobago-help-container textarea.form-control.is-help {
+  padding-right: calc(1.5em + 0.75rem);
+  background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem);
+}
+.tobago-help-container .form-select.is-help {
+  border-color: #0dcaf0;
+}
+.tobago-help-container .form-select.is-help:not([multiple]):not([size]), .tobago-help-container .form-select.is-help:not([multiple])[size="1"] {
+  padding-right: 4.125rem;
+  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e"), none;
+  background-position: right 0.75rem center, center right 2.25rem;
+  background-size: 16px 12px, calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
+}
+.tobago-help-container .form-select.is-help:focus {
+  border-color: #0dcaf0;
+  box-shadow: 0 0 0 0.25rem rgba(13, 202, 240, 0.25);
+}
+.tobago-help-container .form-control-color.is-help {
+  width: calc(3rem + calc(1.5em + 0.75rem));
+}
+.tobago-help-container .form-check-input.is-help {
+  border-color: #0dcaf0;
+}
+.tobago-help-container .form-check-input.is-help:checked {
+  background-color: #0dcaf0;
+}
+.tobago-help-container .form-check-input.is-help:focus {
+  box-shadow: 0 0 0 0.25rem rgba(13, 202, 240, 0.25);
+}
+.tobago-help-container .form-check-input.is-help ~ .form-check-label {
+  color: #0dcaf0;
+}
+.tobago-help-container .form-check-inline .form-check-input ~ .help-feedback {
+  margin-left: 0.5em;
+}
+.tobago-help-container.tobago-button-left, .tobago-help-container.tobago-button-right {
+  display: flex;
+  align-items: flex-start;
+}
+.tobago-help-container.tobago-button-left.tobago-button-left > tobago-popover, .tobago-help-container.tobago-button-right.tobago-button-left > tobago-popover {
+  margin-right: 0.75rem;
+}
+.tobago-help-container.tobago-button-left.tobago-button-right > tobago-popover, .tobago-help-container.tobago-button-right.tobago-button-right > tobago-popover {
+  margin-left: 0.75rem;
+}
+.tobago-help-container.tobago-button-left tobago-popover > a, .tobago-help-container.tobago-button-right tobago-popover > a {
+  --bs-btn-padding-x: .4rem;
+}
+.tobago-help-container.tobago-tooltip {
+  position: relative;
+}
+.tobago-help-container.tobago-tooltip .help-tooltip {
+  display: block;
+}
+.tobago-help-container.tobago-text-top .help-feedback, .tobago-help-container.tobago-text-bottom .help-feedback {
+  display: block;
+}
+.tobago-help-container.tobago-text-top .help-feedback {
+  margin-bottom: 0.25rem;
+}
+
 /* image ----------------------------------------------------------- */
 tobago-image.disabled {
   filter: grayscale(1) blur(2px) contrast(0.5) brightness(1.2);
@@ -11332,10 +11430,8 @@ button.nav-link { /* bootstrap don't know button.nav-link*/
   padding-right: 0;
 }
 
-/* messages / help text ----------------------------------------------- */
 .tobago-messages-container {
-  display: flex;
-  align-items: flex-start;
+  width: 100%;
 }
 .tobago-messages-container .error-feedback {
   display: none;
@@ -11363,18 +11459,36 @@ button.nav-link { /* bootstrap don't know button.nav-link*/
 }
 .tobago-messages-container .form-control.is-error {
   border-color: #dc3545;
+  padding-right: calc(1.5em + 0.75rem);
+  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");
+  background-repeat: no-repeat;
+  background-position: right calc(0.375em + 0.1875rem) center;
+  background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
 }
 .tobago-messages-container .form-control.is-error:focus {
   border-color: #dc3545;
   box-shadow: 0 0 0 0.25rem rgba(220, 53, 69, 0.25);
 }
+.tobago-messages-container textarea.form-control.is-error {
+  padding-right: calc(1.5em + 0.75rem);
+  background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem);
+}
 .tobago-messages-container .form-select.is-error {
   border-color: #dc3545;
 }
+.tobago-messages-container .form-select.is-error:not([multiple]):not([size]), .tobago-messages-container .form-select.is-error:not([multiple])[size="1"] {
+  padding-right: 4.125rem;
+  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e"), url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx [...]
+  background-position: right 0.75rem center, center right 2.25rem;
+  background-size: 16px 12px, calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
+}
 .tobago-messages-container .form-select.is-error:focus {
   border-color: #dc3545;
   box-shadow: 0 0 0 0.25rem rgba(220, 53, 69, 0.25);
 }
+.tobago-messages-container .form-control-color.is-error {
+  width: calc(3rem + calc(1.5em + 0.75rem));
+}
 .tobago-messages-container .form-check-input.is-error {
   border-color: #dc3545;
 }
@@ -11416,18 +11530,36 @@ button.nav-link { /* bootstrap don't know button.nav-link*/
 }
 .tobago-messages-container .form-control.is-warning {
   border-color: #ffc107;
+  padding-right: calc(1.5em + 0.75rem);
+  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23ffc107'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23ffc107' stroke='none'/%3e%3c/svg%3e");
+  background-repeat: no-repeat;
+  background-position: right calc(0.375em + 0.1875rem) center;
+  background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
 }
 .tobago-messages-container .form-control.is-warning:focus {
   border-color: #ffc107;
   box-shadow: 0 0 0 0.25rem rgba(255, 193, 7, 0.25);
 }
+.tobago-messages-container textarea.form-control.is-warning {
+  padding-right: calc(1.5em + 0.75rem);
+  background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem);
+}
 .tobago-messages-container .form-select.is-warning {
   border-color: #ffc107;
 }
+.tobago-messages-container .form-select.is-warning:not([multiple]):not([size]), .tobago-messages-container .form-select.is-warning:not([multiple])[size="1"] {
+  padding-right: 4.125rem;
+  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e"), url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23ffc107'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx [...]
+  background-position: right 0.75rem center, center right 2.25rem;
+  background-size: 16px 12px, calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
+}
 .tobago-messages-container .form-select.is-warning:focus {
   border-color: #ffc107;
   box-shadow: 0 0 0 0.25rem rgba(255, 193, 7, 0.25);
 }
+.tobago-messages-container .form-control-color.is-warning {
+  width: calc(3rem + calc(1.5em + 0.75rem));
+}
 .tobago-messages-container .form-check-input.is-warning {
   border-color: #ffc107;
 }
@@ -11469,18 +11601,36 @@ button.nav-link { /* bootstrap don't know button.nav-link*/
 }
 .tobago-messages-container .form-control.is-info {
   border-color: #0dcaf0;
+  padding-right: calc(1.5em + 0.75rem);
+  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%230dcaf0'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%230dcaf0' stroke='none'/%3e%3c/svg%3e");
+  background-repeat: no-repeat;
+  background-position: right calc(0.375em + 0.1875rem) center;
+  background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
 }
 .tobago-messages-container .form-control.is-info:focus {
   border-color: #0dcaf0;
   box-shadow: 0 0 0 0.25rem rgba(13, 202, 240, 0.25);
 }
+.tobago-messages-container textarea.form-control.is-info {
+  padding-right: calc(1.5em + 0.75rem);
+  background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem);
+}
 .tobago-messages-container .form-select.is-info {
   border-color: #0dcaf0;
 }
+.tobago-messages-container .form-select.is-info:not([multiple]):not([size]), .tobago-messages-container .form-select.is-info:not([multiple])[size="1"] {
+  padding-right: 4.125rem;
+  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e"), url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%230dcaf0'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx [...]
+  background-position: right 0.75rem center, center right 2.25rem;
+  background-size: 16px 12px, calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
+}
 .tobago-messages-container .form-select.is-info:focus {
   border-color: #0dcaf0;
   box-shadow: 0 0 0 0.25rem rgba(13, 202, 240, 0.25);
 }
+.tobago-messages-container .form-control-color.is-info {
+  width: calc(3rem + calc(1.5em + 0.75rem));
+}
 .tobago-messages-container .form-check-input.is-info {
   border-color: #0dcaf0;
 }
@@ -11496,16 +11646,34 @@ button.nav-link { /* bootstrap don't know button.nav-link*/
 .tobago-messages-container .form-check-inline .form-check-input ~ .info-feedback {
   margin-left: 0.5em;
 }
-.tobago-messages-container .tobago-messages:first-child small label, .tobago-messages-container .tobago-messages:first-child .small label {
-  margin-right: 0; /* for tc:in margin 5px is already set */
-  margin-bottom: 5px;
+.tobago-messages-container.tobago-button-left, .tobago-messages-container.tobago-button-right {
+  display: flex;
+  align-items: flex-start;
+}
+.tobago-messages-container.tobago-button-left.tobago-button-left > tobago-popover, .tobago-messages-container.tobago-button-right.tobago-button-left > tobago-popover {
+  margin-right: 0.75rem;
 }
-.tobago-messages-container tobago-popover {
+.tobago-messages-container.tobago-button-left.tobago-button-right > tobago-popover, .tobago-messages-container.tobago-button-right.tobago-button-right > tobago-popover {
   margin-left: 0.75rem;
 }
-.tobago-messages-container tobago-popover .btn {
-  padding-left: 0.4rem;
-  padding-right: 0.4rem;
+.tobago-messages-container.tobago-button-left tobago-popover > a, .tobago-messages-container.tobago-button-right tobago-popover > a {
+  --bs-btn-padding-x: .4rem;
+}
+.tobago-messages-container.tobago-tooltip {
+  position: relative;
+}
+.tobago-messages-container.tobago-button-left .form-control, .tobago-messages-container.tobago-button-right .form-control {
+  padding-right: 0.75rem;
+  background-image: none;
+}
+.tobago-messages-container.tobago-tooltip .error-tooltip, .tobago-messages-container.tobago-tooltip .warning-tooltip, .tobago-messages-container.tobago-tooltip .info-tooltip {
+  display: block;
+}
+.tobago-messages-container.tobago-text-top .error-feedback, .tobago-messages-container.tobago-text-top .warning-feedback, .tobago-messages-container.tobago-text-top .info-feedback, .tobago-messages-container.tobago-text-bottom .error-feedback, .tobago-messages-container.tobago-text-bottom .warning-feedback, .tobago-messages-container.tobago-text-bottom .info-feedback {
+  display: block;
+}
+.tobago-messages-container.tobago-text-top .error-feedback, .tobago-messages-container.tobago-text-top .warning-feedback, .tobago-messages-container.tobago-text-top .info-feedback {
+  margin-bottom: 0.25rem;
 }
 
 .tobago-popover-box {
@@ -11550,7 +11718,6 @@ tobago-messages .alert.alert-dismissible.alert-warning:before {
 tobago-messages .alert.alert-dismissible.alert-info:before {
   content: "\f646";
 }
-
 .popover .popover-body {
   white-space: pre-line;
 }
@@ -12032,7 +12199,7 @@ tobago-select-many-shuttle .tobago-body .tobago-unselected:disabled option, toba
 tobago-select-many-shuttle .tobago-body .tobago-selected:disabled option, tobago-select-many-shuttle .tobago-body .tobago-selected option:disabled {
   color: rgba(33, 37, 41, 0.5);
 }
-tobago-select-many-shuttle.tobago-label-container > .tobago-body, tobago-select-many-shuttle .tobago-messages-container > .tobago-body {
+tobago-select-many-shuttle.tobago-label-container > .tobago-body, tobago-select-many-shuttle .tobago-help-container > .tobago-body, tobago-select-many-shuttle .tobago-messages-container > .tobago-body {
   flex: 1 0 0px;
 }
 
diff --git a/tobago-theme/tobago-theme-scarborough/src/main/css/tobago.css.map b/tobago-theme/tobago-theme-scarborough/src/main/css/tobago.css.map
index 817baba4f6..9a3089d4e5 100644
--- a/tobago-theme/tobago-theme-scarborough/src/main/css/tobago.css.map
+++ b/tobago-theme/tobago-theme-scarborough/src/main/css/tobago.css.map
@@ -1 +1 @@
-{"version":3,"sources":["tobago.css","../scss/tobago-theme.scss","../../../../node_modules/bootstrap/scss/mixins/_banner.scss","../../../../node_modules/bootstrap/scss/_root.scss","../../../../node_modules/bootstrap/scss/vendor/_rfs.scss","../../../../node_modules/bootstrap/scss/_reboot.scss","../../../../node_modules/bootstrap/scss/_variables.scss","../../../../node_modules/bootstrap/scss/mixins/_border-radius.scss","../../../../node_modules/bootstrap/scss/_type.scss","../../../../node_ [...]
\ No newline at end of file
+{"version":3,"sources":["tobago.css","../scss/tobago-theme.scss","../../../../node_modules/bootstrap/scss/mixins/_banner.scss","../../../../node_modules/bootstrap/scss/_root.scss","../../../../node_modules/bootstrap/scss/vendor/_rfs.scss","../../../../node_modules/bootstrap/scss/_reboot.scss","../../../../node_modules/bootstrap/scss/_variables.scss","../../../../node_modules/bootstrap/scss/mixins/_border-radius.scss","../../../../node_modules/bootstrap/scss/_type.scss","../../../../node_ [...]
\ No newline at end of file
diff --git a/tobago-theme/tobago-theme-scarborough/src/main/css/tobago.min.css b/tobago-theme/tobago-theme-scarborough/src/main/css/tobago.min.css
index 7528aa87c6..ca4fb5c8c2 100644
--- a/tobago-theme/tobago-theme-scarborough/src/main/css/tobago.min.css
+++ b/tobago-theme/tobago-theme-scarborough/src/main/css/tobago.min.css
@@ -1,2 +1,2 @@
-@charset "UTF-8";:root{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#d63384;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-black:#000;--bs-white:#fff;--bs-gray:#6c757d;--bs-gray-dark:#343a40;--bs-gray-100:#f8f9fa;--bs-gray-200:#e9ecef;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#6c757d;--bs-gray-700:#495057;--bs-gray-800:#343a40;--bs-gray-900:#212529;--bs-prima [...]
+@charset "UTF-8";:root{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#d63384;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-black:#000;--bs-white:#fff;--bs-gray:#6c757d;--bs-gray-dark:#343a40;--bs-gray-100:#f8f9fa;--bs-gray-200:#e9ecef;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#6c757d;--bs-gray-700:#495057;--bs-gray-800:#343a40;--bs-gray-900:#212529;--bs-prima [...]
 /*# sourceMappingURL=tobago.min.css.map */
\ No newline at end of file
diff --git a/tobago-theme/tobago-theme-scarborough/src/main/css/tobago.min.css.map b/tobago-theme/tobago-theme-scarborough/src/main/css/tobago.min.css.map
index 7902b5d902..21cdaf3c95 100644
--- a/tobago-theme/tobago-theme-scarborough/src/main/css/tobago.min.css.map
+++ b/tobago-theme/tobago-theme-scarborough/src/main/css/tobago.min.css.map
@@ -1 +1 @@
-{"version":3,"sources":["tobago-theme-scarborough/src/main/css/tobago.css"],"names":[],"mappings":"iBAuBA,MACE,UAAW,QACX,YAAa,QACb,YAAa,QACb,UAAW,QACX,SAAU,QACV,YAAa,QACb,YAAa,QACb,WAAY,QACZ,UAAW,QACX,UAAW,QACX,WAAY,KACZ,WAAY,KACZ,UAAW,QACX,eAAgB,QAChB,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,aAAc,QACd,eAAgB,QAChB,aAAc,QACd,UAAW,QACX,aAAc,QACd,YAAa,QACb,WAAY,QACZ,UAAW,QACX,iBAAkB,EAAE,CAAE,GAAG,CAAE,IAC3B,mBAAoB,GAAG,CAAE,GAAG,CAAE,IAC9B,i [...]
\ No newline at end of file
+{"version":3,"sources":["tobago-theme-scarborough/src/main/css/tobago.css"],"names":[],"mappings":"iBAuBA,MACE,UAAW,QACX,YAAa,QACb,YAAa,QACb,UAAW,QACX,SAAU,QACV,YAAa,QACb,YAAa,QACb,WAAY,QACZ,UAAW,QACX,UAAW,QACX,WAAY,KACZ,WAAY,KACZ,UAAW,QACX,eAAgB,QAChB,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,aAAc,QACd,eAAgB,QAChB,aAAc,QACd,UAAW,QACX,aAAc,QACd,YAAa,QACb,WAAY,QACZ,UAAW,QACX,iBAAkB,EAAE,CAAE,GAAG,CAAE,IAC3B,mBAAoB,GAAG,CAAE,GAAG,CAAE,IAC9B,i [...]
\ No newline at end of file
diff --git a/tobago-theme/tobago-theme-speyside/src/main/css/tobago.css b/tobago-theme/tobago-theme-speyside/src/main/css/tobago.css
index 7b98a8bd51..3c107e118f 100644
--- a/tobago-theme/tobago-theme-speyside/src/main/css/tobago.css
+++ b/tobago-theme/tobago-theme-speyside/src/main/css/tobago.css
@@ -10840,7 +10840,6 @@ tobago-flex-layout > tobago-flex-layout {
   margin-bottom: 0;
 }
 
-/* flowLayout ---------------------------------------------------------- */
 tobago-flow-layout {
   display: block;
 }
@@ -10854,7 +10853,6 @@ tobago-focus {
   display: none;
 }
 
-/* footer -------------------------------------------------------------- */
 tobago-footer {
   display: block;
   background-color: #fff;
@@ -10890,6 +10888,105 @@ tobago-header.sticky-top {
   margin-right: -0.75rem;
 }
 
+.tobago-help-container {
+  width: 100%;
+}
+.tobago-help-container .help-feedback {
+  display: none;
+  width: 100%;
+  margin-top: 0.25rem;
+  font-size: 0.875em;
+  color: #5bc0de;
+}
+.tobago-help-container .help-tooltip {
+  position: absolute;
+  top: 100%;
+  z-index: 5;
+  display: none;
+  max-width: 100%;
+  padding: 0.25rem 0.5rem;
+  margin-top: 0.1rem;
+  font-size: 0.875rem;
+  color: #000;
+  background-color: rgba(91, 192, 222, 0.9);
+}
+.tobago-help-container.is-help ~ .help-feedback,
+.tobago-help-container.is-help ~ .help-tooltip {
+  display: block;
+}
+.tobago-help-container .form-control.is-help {
+  border-color: #5bc0de;
+  padding-right: calc(1.5em + 0.75rem);
+  background-image: none;
+  background-repeat: no-repeat;
+  background-position: right calc(0.375em + 0.1875rem) center;
+  background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
+}
+.tobago-help-container .form-control.is-help:focus {
+  border-color: #5bc0de;
+  box-shadow: 0 0 0 0.25rem rgba(91, 192, 222, 0.25);
+}
+.tobago-help-container textarea.form-control.is-help {
+  padding-right: calc(1.5em + 0.75rem);
+  background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem);
+}
+.tobago-help-container .form-select.is-help {
+  border-color: #5bc0de;
+}
+.tobago-help-container .form-select.is-help:not([multiple]):not([size]), .tobago-help-container .form-select.is-help:not([multiple])[size="1"] {
+  padding-right: 4.125rem;
+  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23323232' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e"), none;
+  background-position: right 0.75rem center, center right 2.25rem;
+  background-size: 16px 12px, calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
+}
+.tobago-help-container .form-select.is-help:focus {
+  border-color: #5bc0de;
+  box-shadow: 0 0 0 0.25rem rgba(91, 192, 222, 0.25);
+}
+.tobago-help-container .form-control-color.is-help {
+  width: calc(3rem + calc(1.5em + 0.75rem));
+}
+.tobago-help-container .form-check-input.is-help {
+  border-color: #5bc0de;
+}
+.tobago-help-container .form-check-input.is-help:checked {
+  background-color: #5bc0de;
+}
+.tobago-help-container .form-check-input.is-help:focus {
+  box-shadow: 0 0 0 0.25rem rgba(91, 192, 222, 0.25);
+}
+.tobago-help-container .form-check-input.is-help ~ .form-check-label {
+  color: #5bc0de;
+}
+.tobago-help-container .form-check-inline .form-check-input ~ .help-feedback {
+  margin-left: 0.5em;
+}
+.tobago-help-container.tobago-button-left, .tobago-help-container.tobago-button-right {
+  display: flex;
+  align-items: flex-start;
+}
+.tobago-help-container.tobago-button-left.tobago-button-left > tobago-popover, .tobago-help-container.tobago-button-right.tobago-button-left > tobago-popover {
+  margin-right: 0.75rem;
+}
+.tobago-help-container.tobago-button-left.tobago-button-right > tobago-popover, .tobago-help-container.tobago-button-right.tobago-button-right > tobago-popover {
+  margin-left: 0.75rem;
+}
+.tobago-help-container.tobago-button-left tobago-popover > a, .tobago-help-container.tobago-button-right tobago-popover > a {
+  --bs-btn-padding-x: .4rem;
+}
+.tobago-help-container.tobago-tooltip {
+  position: relative;
+}
+.tobago-help-container.tobago-tooltip .help-tooltip {
+  display: block;
+}
+.tobago-help-container.tobago-text-top .help-feedback, .tobago-help-container.tobago-text-bottom .help-feedback {
+  display: block;
+}
+.tobago-help-container.tobago-text-top .help-feedback {
+  margin-bottom: 0.25rem;
+}
+
 /* image ----------------------------------------------------------- */
 tobago-image.disabled {
   filter: grayscale(1) blur(2px) contrast(0.5) brightness(1.2);
@@ -11057,10 +11154,8 @@ button.nav-link { /* bootstrap don't know button.nav-link*/
   padding-right: 0;
 }
 
-/* messages / help text ----------------------------------------------- */
 .tobago-messages-container {
-  display: flex;
-  align-items: flex-start;
+  width: 100%;
 }
 .tobago-messages-container .error-feedback {
   display: none;
@@ -11087,18 +11182,36 @@ button.nav-link { /* bootstrap don't know button.nav-link*/
 }
 .tobago-messages-container .form-control.is-error {
   border-color: rgb(211, 0, 64);
+  padding-right: calc(1.5em + 0.75rem);
+  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='rgb%28211, 0, 64%29'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='rgb%28211, 0, 64%29' stroke='none'/%3e%3c/svg%3e");
+  background-repeat: no-repeat;
+  background-position: right calc(0.375em + 0.1875rem) center;
+  background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
 }
 .tobago-messages-container .form-control.is-error:focus {
   border-color: rgb(211, 0, 64);
   box-shadow: 0 0 0 0.25rem rgba(211, 0, 64, 0.25);
 }
+.tobago-messages-container textarea.form-control.is-error {
+  padding-right: calc(1.5em + 0.75rem);
+  background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem);
+}
 .tobago-messages-container .form-select.is-error {
   border-color: rgb(211, 0, 64);
 }
+.tobago-messages-container .form-select.is-error:not([multiple]):not([size]), .tobago-messages-container .form-select.is-error:not([multiple])[size="1"] {
+  padding-right: 4.125rem;
+  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23323232' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e"), url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='rgb%28211, 0, 64%29'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3 [...]
+  background-position: right 0.75rem center, center right 2.25rem;
+  background-size: 16px 12px, calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
+}
 .tobago-messages-container .form-select.is-error:focus {
   border-color: rgb(211, 0, 64);
   box-shadow: 0 0 0 0.25rem rgba(211, 0, 64, 0.25);
 }
+.tobago-messages-container .form-control-color.is-error {
+  width: calc(3rem + calc(1.5em + 0.75rem));
+}
 .tobago-messages-container .form-check-input.is-error {
   border-color: rgb(211, 0, 64);
 }
@@ -11139,18 +11252,36 @@ button.nav-link { /* bootstrap don't know button.nav-link*/
 }
 .tobago-messages-container .form-control.is-warning {
   border-color: #f0ad4e;
+  padding-right: calc(1.5em + 0.75rem);
+  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23f0ad4e'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23f0ad4e' stroke='none'/%3e%3c/svg%3e");
+  background-repeat: no-repeat;
+  background-position: right calc(0.375em + 0.1875rem) center;
+  background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
 }
 .tobago-messages-container .form-control.is-warning:focus {
   border-color: #f0ad4e;
   box-shadow: 0 0 0 0.25rem rgba(240, 173, 78, 0.25);
 }
+.tobago-messages-container textarea.form-control.is-warning {
+  padding-right: calc(1.5em + 0.75rem);
+  background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem);
+}
 .tobago-messages-container .form-select.is-warning {
   border-color: #f0ad4e;
 }
+.tobago-messages-container .form-select.is-warning:not([multiple]):not([size]), .tobago-messages-container .form-select.is-warning:not([multiple])[size="1"] {
+  padding-right: 4.125rem;
+  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23323232' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e"), url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23f0ad4e'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx [...]
+  background-position: right 0.75rem center, center right 2.25rem;
+  background-size: 16px 12px, calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
+}
 .tobago-messages-container .form-select.is-warning:focus {
   border-color: #f0ad4e;
   box-shadow: 0 0 0 0.25rem rgba(240, 173, 78, 0.25);
 }
+.tobago-messages-container .form-control-color.is-warning {
+  width: calc(3rem + calc(1.5em + 0.75rem));
+}
 .tobago-messages-container .form-check-input.is-warning {
   border-color: #f0ad4e;
 }
@@ -11191,18 +11322,36 @@ button.nav-link { /* bootstrap don't know button.nav-link*/
 }
 .tobago-messages-container .form-control.is-info {
   border-color: #5bc0de;
+  padding-right: calc(1.5em + 0.75rem);
+  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%235bc0de'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%235bc0de' stroke='none'/%3e%3c/svg%3e");
+  background-repeat: no-repeat;
+  background-position: right calc(0.375em + 0.1875rem) center;
+  background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
 }
 .tobago-messages-container .form-control.is-info:focus {
   border-color: #5bc0de;
   box-shadow: 0 0 0 0.25rem rgba(91, 192, 222, 0.25);
 }
+.tobago-messages-container textarea.form-control.is-info {
+  padding-right: calc(1.5em + 0.75rem);
+  background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem);
+}
 .tobago-messages-container .form-select.is-info {
   border-color: #5bc0de;
 }
+.tobago-messages-container .form-select.is-info:not([multiple]):not([size]), .tobago-messages-container .form-select.is-info:not([multiple])[size="1"] {
+  padding-right: 4.125rem;
+  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23323232' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e"), url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%235bc0de'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx [...]
+  background-position: right 0.75rem center, center right 2.25rem;
+  background-size: 16px 12px, calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
+}
 .tobago-messages-container .form-select.is-info:focus {
   border-color: #5bc0de;
   box-shadow: 0 0 0 0.25rem rgba(91, 192, 222, 0.25);
 }
+.tobago-messages-container .form-control-color.is-info {
+  width: calc(3rem + calc(1.5em + 0.75rem));
+}
 .tobago-messages-container .form-check-input.is-info {
   border-color: #5bc0de;
 }
@@ -11218,16 +11367,34 @@ button.nav-link { /* bootstrap don't know button.nav-link*/
 .tobago-messages-container .form-check-inline .form-check-input ~ .info-feedback {
   margin-left: 0.5em;
 }
-.tobago-messages-container .tobago-messages:first-child small label, .tobago-messages-container .tobago-messages:first-child .small label {
-  margin-right: 0; /* for tc:in margin 5px is already set */
-  margin-bottom: 5px;
+.tobago-messages-container.tobago-button-left, .tobago-messages-container.tobago-button-right {
+  display: flex;
+  align-items: flex-start;
+}
+.tobago-messages-container.tobago-button-left.tobago-button-left > tobago-popover, .tobago-messages-container.tobago-button-right.tobago-button-left > tobago-popover {
+  margin-right: 0.75rem;
 }
-.tobago-messages-container tobago-popover {
+.tobago-messages-container.tobago-button-left.tobago-button-right > tobago-popover, .tobago-messages-container.tobago-button-right.tobago-button-right > tobago-popover {
   margin-left: 0.75rem;
 }
-.tobago-messages-container tobago-popover .btn {
-  padding-left: 0.4rem;
-  padding-right: 0.4rem;
+.tobago-messages-container.tobago-button-left tobago-popover > a, .tobago-messages-container.tobago-button-right tobago-popover > a {
+  --bs-btn-padding-x: .4rem;
+}
+.tobago-messages-container.tobago-tooltip {
+  position: relative;
+}
+.tobago-messages-container.tobago-button-left .form-control, .tobago-messages-container.tobago-button-right .form-control {
+  padding-right: 0.75rem;
+  background-image: none;
+}
+.tobago-messages-container.tobago-tooltip .error-tooltip, .tobago-messages-container.tobago-tooltip .warning-tooltip, .tobago-messages-container.tobago-tooltip .info-tooltip {
+  display: block;
+}
+.tobago-messages-container.tobago-text-top .error-feedback, .tobago-messages-container.tobago-text-top .warning-feedback, .tobago-messages-container.tobago-text-top .info-feedback, .tobago-messages-container.tobago-text-bottom .error-feedback, .tobago-messages-container.tobago-text-bottom .warning-feedback, .tobago-messages-container.tobago-text-bottom .info-feedback {
+  display: block;
+}
+.tobago-messages-container.tobago-text-top .error-feedback, .tobago-messages-container.tobago-text-top .warning-feedback, .tobago-messages-container.tobago-text-top .info-feedback {
+  margin-bottom: 0.25rem;
 }
 
 .tobago-popover-box {
@@ -11272,7 +11439,6 @@ tobago-messages .alert.alert-dismissible.alert-warning:before {
 tobago-messages .alert.alert-dismissible.alert-info:before {
   content: "\f646";
 }
-
 .popover .popover-body {
   white-space: pre-line;
 }
@@ -11754,7 +11920,7 @@ tobago-select-many-shuttle .tobago-body .tobago-unselected:disabled option, toba
 tobago-select-many-shuttle .tobago-body .tobago-selected:disabled option, tobago-select-many-shuttle .tobago-body .tobago-selected option:disabled {
   color: rgba(33, 37, 41, 0.5);
 }
-tobago-select-many-shuttle.tobago-label-container > .tobago-body, tobago-select-many-shuttle .tobago-messages-container > .tobago-body {
+tobago-select-many-shuttle.tobago-label-container > .tobago-body, tobago-select-many-shuttle .tobago-help-container > .tobago-body, tobago-select-many-shuttle .tobago-messages-container > .tobago-body {
   flex: 1 0 0px;
 }
 
diff --git a/tobago-theme/tobago-theme-speyside/src/main/css/tobago.css.map b/tobago-theme/tobago-theme-speyside/src/main/css/tobago.css.map
index cce65ddcd9..052f5658ce 100644
--- a/tobago-theme/tobago-theme-speyside/src/main/css/tobago.css.map
+++ b/tobago-theme/tobago-theme-speyside/src/main/css/tobago.css.map
@@ -1 +1 @@
-{"version":3,"sources":["tobago.css","../scss/tobago-theme.scss","../scss/_custom.scss","../../../../node_modules/bootstrap/scss/mixins/_banner.scss","../../../../node_modules/bootstrap/scss/_root.scss","../../../../node_modules/bootstrap/scss/vendor/_rfs.scss","../../../../node_modules/bootstrap/scss/_reboot.scss","../../../../node_modules/bootstrap/scss/_variables.scss","../../../../node_modules/bootstrap/scss/_type.scss","../../../../node_modules/bootstrap/scss/mixins/_lists.scss",".. [...]
\ No newline at end of file
+{"version":3,"sources":["tobago.css","../scss/tobago-theme.scss","../scss/_custom.scss","../../../../node_modules/bootstrap/scss/mixins/_banner.scss","../../../../node_modules/bootstrap/scss/_root.scss","../../../../node_modules/bootstrap/scss/vendor/_rfs.scss","../../../../node_modules/bootstrap/scss/_reboot.scss","../../../../node_modules/bootstrap/scss/_variables.scss","../../../../node_modules/bootstrap/scss/_type.scss","../../../../node_modules/bootstrap/scss/mixins/_lists.scss",".. [...]
\ No newline at end of file
diff --git a/tobago-theme/tobago-theme-speyside/src/main/css/tobago.min.css b/tobago-theme/tobago-theme-speyside/src/main/css/tobago.min.css
index 488edbfe5d..5fcae8ce5f 100644
--- a/tobago-theme/tobago-theme-speyside/src/main/css/tobago.min.css
+++ b/tobago-theme/tobago-theme-speyside/src/main/css/tobago.min.css
@@ -1,2 +1,2 @@
-@charset "UTF-8";:root{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:rgb(58, 37, 100);--bs-pink:#d63384;--bs-red:rgb(211, 0, 64);--bs-orange:#d90;--bs-yellow:#ffc107;--bs-green:rgb(29, 163, 50);--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-black:#000;--bs-white:#fff;--bs-gray:rgb(120, 140, 148);--bs-gray-dark:#323232;--bs-gray-100:#f7f7f7;--bs-gray-200:#e3e4e5;--bs-gray-300:#d7d7d7;--bs-gray-400:#ced4da;--bs-gray-500:#acacac;--bs-gray-600:rgb(120, 140, 148);--bs-gray-700:#55595c;--bs-gray [...]
+@charset "UTF-8";:root{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:rgb(58, 37, 100);--bs-pink:#d63384;--bs-red:rgb(211, 0, 64);--bs-orange:#d90;--bs-yellow:#ffc107;--bs-green:rgb(29, 163, 50);--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-black:#000;--bs-white:#fff;--bs-gray:rgb(120, 140, 148);--bs-gray-dark:#323232;--bs-gray-100:#f7f7f7;--bs-gray-200:#e3e4e5;--bs-gray-300:#d7d7d7;--bs-gray-400:#ced4da;--bs-gray-500:#acacac;--bs-gray-600:rgb(120, 140, 148);--bs-gray-700:#55595c;--bs-gray [...]
 /*# sourceMappingURL=tobago.min.css.map */
\ No newline at end of file
diff --git a/tobago-theme/tobago-theme-speyside/src/main/css/tobago.min.css.map b/tobago-theme/tobago-theme-speyside/src/main/css/tobago.min.css.map
index 69df13d034..ab1c438b66 100644
--- a/tobago-theme/tobago-theme-speyside/src/main/css/tobago.min.css.map
+++ b/tobago-theme/tobago-theme-speyside/src/main/css/tobago.min.css.map
@@ -1 +1 @@
-{"version":3,"sources":["tobago-theme-speyside/src/main/css/tobago.css"],"names":[],"mappings":"iBAuCA,MACE,UAAW,QACX,YAAa,QACb,YAAa,iBACb,UAAW,QACX,SAAU,gBACV,YAAa,KACb,YAAa,QACb,WAAY,iBACZ,UAAW,QACX,UAAW,QACX,WAAY,KACZ,WAAY,KACZ,UAAW,mBACX,eAAgB,QAChB,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,mBACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,aAAc,gBACd,eAAgB,QAChB,aAAc,iBACd,UAAW,QACX,aAAc,QACd,YAAa,gBACb,WAAY,QACZ,UAAW,QACX,iBAAkB,EAAE,CAAE,EAAE,CAAE,GAC1B,mBAAoB,GAAG,CAAE,GAAG,CAAE,IA [...]
\ No newline at end of file
+{"version":3,"sources":["tobago-theme-speyside/src/main/css/tobago.css"],"names":[],"mappings":"iBAuCA,MACE,UAAW,QACX,YAAa,QACb,YAAa,iBACb,UAAW,QACX,SAAU,gBACV,YAAa,KACb,YAAa,QACb,WAAY,iBACZ,UAAW,QACX,UAAW,QACX,WAAY,KACZ,WAAY,KACZ,UAAW,mBACX,eAAgB,QAChB,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,mBACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,aAAc,gBACd,eAAgB,QAChB,aAAc,iBACd,UAAW,QACX,aAAc,QACd,YAAa,gBACb,WAAY,QACZ,UAAW,QACX,iBAAkB,EAAE,CAAE,EAAE,CAAE,GAC1B,mBAAoB,GAAG,CAAE,GAAG,CAAE,IA [...]
\ No newline at end of file
diff --git a/tobago-theme/tobago-theme-standard/src/main/css/tobago.css b/tobago-theme/tobago-theme-standard/src/main/css/tobago.css
index 456ba373aa..b3a84390be 100644
--- a/tobago-theme/tobago-theme-standard/src/main/css/tobago.css
+++ b/tobago-theme/tobago-theme-standard/src/main/css/tobago.css
@@ -11097,7 +11097,6 @@ tobago-flex-layout > tobago-flex-layout {
   margin-bottom: 0;
 }
 
-/* flowLayout ---------------------------------------------------------- */
 tobago-flow-layout {
   display: block;
 }
@@ -11111,7 +11110,6 @@ tobago-focus {
   display: none;
 }
 
-/* footer -------------------------------------------------------------- */
 tobago-footer {
   display: block;
   background-color: #fff;
@@ -11147,6 +11145,106 @@ tobago-header.sticky-top {
   margin-right: -0.75rem;
 }
 
+.tobago-help-container {
+  width: 100%;
+}
+.tobago-help-container .help-feedback {
+  display: none;
+  width: 100%;
+  margin-top: 0.25rem;
+  font-size: 0.875em;
+  color: #0dcaf0;
+}
+.tobago-help-container .help-tooltip {
+  position: absolute;
+  top: 100%;
+  z-index: 5;
+  display: none;
+  max-width: 100%;
+  padding: 0.25rem 0.5rem;
+  margin-top: 0.1rem;
+  font-size: 0.875rem;
+  color: #000;
+  background-color: rgba(13, 202, 240, 0.9);
+  border-radius: 0.375rem;
+}
+.tobago-help-container.is-help ~ .help-feedback,
+.tobago-help-container.is-help ~ .help-tooltip {
+  display: block;
+}
+.tobago-help-container .form-control.is-help {
+  border-color: #0dcaf0;
+  padding-right: calc(1.5em + 0.75rem);
+  background-image: none;
+  background-repeat: no-repeat;
+  background-position: right calc(0.375em + 0.1875rem) center;
+  background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
+}
+.tobago-help-container .form-control.is-help:focus {
+  border-color: #0dcaf0;
+  box-shadow: 0 0 0 0.25rem rgba(13, 202, 240, 0.25);
+}
+.tobago-help-container textarea.form-control.is-help {
+  padding-right: calc(1.5em + 0.75rem);
+  background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem);
+}
+.tobago-help-container .form-select.is-help {
+  border-color: #0dcaf0;
+}
+.tobago-help-container .form-select.is-help:not([multiple]):not([size]), .tobago-help-container .form-select.is-help:not([multiple])[size="1"] {
+  padding-right: 4.125rem;
+  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e"), none;
+  background-position: right 0.75rem center, center right 2.25rem;
+  background-size: 16px 12px, calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
+}
+.tobago-help-container .form-select.is-help:focus {
+  border-color: #0dcaf0;
+  box-shadow: 0 0 0 0.25rem rgba(13, 202, 240, 0.25);
+}
+.tobago-help-container .form-control-color.is-help {
+  width: calc(3rem + calc(1.5em + 0.75rem));
+}
+.tobago-help-container .form-check-input.is-help {
+  border-color: #0dcaf0;
+}
+.tobago-help-container .form-check-input.is-help:checked {
+  background-color: #0dcaf0;
+}
+.tobago-help-container .form-check-input.is-help:focus {
+  box-shadow: 0 0 0 0.25rem rgba(13, 202, 240, 0.25);
+}
+.tobago-help-container .form-check-input.is-help ~ .form-check-label {
+  color: #0dcaf0;
+}
+.tobago-help-container .form-check-inline .form-check-input ~ .help-feedback {
+  margin-left: 0.5em;
+}
+.tobago-help-container.tobago-button-left, .tobago-help-container.tobago-button-right {
+  display: flex;
+  align-items: flex-start;
+}
+.tobago-help-container.tobago-button-left.tobago-button-left > tobago-popover, .tobago-help-container.tobago-button-right.tobago-button-left > tobago-popover {
+  margin-right: 0.75rem;
+}
+.tobago-help-container.tobago-button-left.tobago-button-right > tobago-popover, .tobago-help-container.tobago-button-right.tobago-button-right > tobago-popover {
+  margin-left: 0.75rem;
+}
+.tobago-help-container.tobago-button-left tobago-popover > a, .tobago-help-container.tobago-button-right tobago-popover > a {
+  --bs-btn-padding-x: .4rem;
+}
+.tobago-help-container.tobago-tooltip {
+  position: relative;
+}
+.tobago-help-container.tobago-tooltip .help-tooltip {
+  display: block;
+}
+.tobago-help-container.tobago-text-top .help-feedback, .tobago-help-container.tobago-text-bottom .help-feedback {
+  display: block;
+}
+.tobago-help-container.tobago-text-top .help-feedback {
+  margin-bottom: 0.25rem;
+}
+
 /* image ----------------------------------------------------------- */
 tobago-image.disabled {
   filter: grayscale(1) blur(2px) contrast(0.5) brightness(1.2);
@@ -11315,10 +11413,8 @@ button.nav-link { /* bootstrap don't know button.nav-link*/
   padding-right: 0;
 }
 
-/* messages / help text ----------------------------------------------- */
 .tobago-messages-container {
-  display: flex;
-  align-items: flex-start;
+  width: 100%;
 }
 .tobago-messages-container .error-feedback {
   display: none;
@@ -11346,18 +11442,36 @@ button.nav-link { /* bootstrap don't know button.nav-link*/
 }
 .tobago-messages-container .form-control.is-error {
   border-color: #dc3545;
+  padding-right: calc(1.5em + 0.75rem);
+  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");
+  background-repeat: no-repeat;
+  background-position: right calc(0.375em + 0.1875rem) center;
+  background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
 }
 .tobago-messages-container .form-control.is-error:focus {
   border-color: #dc3545;
   box-shadow: 0 0 0 0.25rem rgba(220, 53, 69, 0.25);
 }
+.tobago-messages-container textarea.form-control.is-error {
+  padding-right: calc(1.5em + 0.75rem);
+  background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem);
+}
 .tobago-messages-container .form-select.is-error {
   border-color: #dc3545;
 }
+.tobago-messages-container .form-select.is-error:not([multiple]):not([size]), .tobago-messages-container .form-select.is-error:not([multiple])[size="1"] {
+  padding-right: 4.125rem;
+  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e"), url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx [...]
+  background-position: right 0.75rem center, center right 2.25rem;
+  background-size: 16px 12px, calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
+}
 .tobago-messages-container .form-select.is-error:focus {
   border-color: #dc3545;
   box-shadow: 0 0 0 0.25rem rgba(220, 53, 69, 0.25);
 }
+.tobago-messages-container .form-control-color.is-error {
+  width: calc(3rem + calc(1.5em + 0.75rem));
+}
 .tobago-messages-container .form-check-input.is-error {
   border-color: #dc3545;
 }
@@ -11399,18 +11513,36 @@ button.nav-link { /* bootstrap don't know button.nav-link*/
 }
 .tobago-messages-container .form-control.is-warning {
   border-color: #ffc107;
+  padding-right: calc(1.5em + 0.75rem);
+  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23ffc107'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23ffc107' stroke='none'/%3e%3c/svg%3e");
+  background-repeat: no-repeat;
+  background-position: right calc(0.375em + 0.1875rem) center;
+  background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
 }
 .tobago-messages-container .form-control.is-warning:focus {
   border-color: #ffc107;
   box-shadow: 0 0 0 0.25rem rgba(255, 193, 7, 0.25);
 }
+.tobago-messages-container textarea.form-control.is-warning {
+  padding-right: calc(1.5em + 0.75rem);
+  background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem);
+}
 .tobago-messages-container .form-select.is-warning {
   border-color: #ffc107;
 }
+.tobago-messages-container .form-select.is-warning:not([multiple]):not([size]), .tobago-messages-container .form-select.is-warning:not([multiple])[size="1"] {
+  padding-right: 4.125rem;
+  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e"), url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23ffc107'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx [...]
+  background-position: right 0.75rem center, center right 2.25rem;
+  background-size: 16px 12px, calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
+}
 .tobago-messages-container .form-select.is-warning:focus {
   border-color: #ffc107;
   box-shadow: 0 0 0 0.25rem rgba(255, 193, 7, 0.25);
 }
+.tobago-messages-container .form-control-color.is-warning {
+  width: calc(3rem + calc(1.5em + 0.75rem));
+}
 .tobago-messages-container .form-check-input.is-warning {
   border-color: #ffc107;
 }
@@ -11452,18 +11584,36 @@ button.nav-link { /* bootstrap don't know button.nav-link*/
 }
 .tobago-messages-container .form-control.is-info {
   border-color: #0dcaf0;
+  padding-right: calc(1.5em + 0.75rem);
+  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%230dcaf0'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%230dcaf0' stroke='none'/%3e%3c/svg%3e");
+  background-repeat: no-repeat;
+  background-position: right calc(0.375em + 0.1875rem) center;
+  background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
 }
 .tobago-messages-container .form-control.is-info:focus {
   border-color: #0dcaf0;
   box-shadow: 0 0 0 0.25rem rgba(13, 202, 240, 0.25);
 }
+.tobago-messages-container textarea.form-control.is-info {
+  padding-right: calc(1.5em + 0.75rem);
+  background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem);
+}
 .tobago-messages-container .form-select.is-info {
   border-color: #0dcaf0;
 }
+.tobago-messages-container .form-select.is-info:not([multiple]):not([size]), .tobago-messages-container .form-select.is-info:not([multiple])[size="1"] {
+  padding-right: 4.125rem;
+  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e"), url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%230dcaf0'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx [...]
+  background-position: right 0.75rem center, center right 2.25rem;
+  background-size: 16px 12px, calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
+}
 .tobago-messages-container .form-select.is-info:focus {
   border-color: #0dcaf0;
   box-shadow: 0 0 0 0.25rem rgba(13, 202, 240, 0.25);
 }
+.tobago-messages-container .form-control-color.is-info {
+  width: calc(3rem + calc(1.5em + 0.75rem));
+}
 .tobago-messages-container .form-check-input.is-info {
   border-color: #0dcaf0;
 }
@@ -11479,16 +11629,34 @@ button.nav-link { /* bootstrap don't know button.nav-link*/
 .tobago-messages-container .form-check-inline .form-check-input ~ .info-feedback {
   margin-left: 0.5em;
 }
-.tobago-messages-container .tobago-messages:first-child small label, .tobago-messages-container .tobago-messages:first-child .small label {
-  margin-right: 0; /* for tc:in margin 5px is already set */
-  margin-bottom: 5px;
+.tobago-messages-container.tobago-button-left, .tobago-messages-container.tobago-button-right {
+  display: flex;
+  align-items: flex-start;
+}
+.tobago-messages-container.tobago-button-left.tobago-button-left > tobago-popover, .tobago-messages-container.tobago-button-right.tobago-button-left > tobago-popover {
+  margin-right: 0.75rem;
 }
-.tobago-messages-container tobago-popover {
+.tobago-messages-container.tobago-button-left.tobago-button-right > tobago-popover, .tobago-messages-container.tobago-button-right.tobago-button-right > tobago-popover {
   margin-left: 0.75rem;
 }
-.tobago-messages-container tobago-popover .btn {
-  padding-left: 0.4rem;
-  padding-right: 0.4rem;
+.tobago-messages-container.tobago-button-left tobago-popover > a, .tobago-messages-container.tobago-button-right tobago-popover > a {
+  --bs-btn-padding-x: .4rem;
+}
+.tobago-messages-container.tobago-tooltip {
+  position: relative;
+}
+.tobago-messages-container.tobago-button-left .form-control, .tobago-messages-container.tobago-button-right .form-control {
+  padding-right: 0.75rem;
+  background-image: none;
+}
+.tobago-messages-container.tobago-tooltip .error-tooltip, .tobago-messages-container.tobago-tooltip .warning-tooltip, .tobago-messages-container.tobago-tooltip .info-tooltip {
+  display: block;
+}
+.tobago-messages-container.tobago-text-top .error-feedback, .tobago-messages-container.tobago-text-top .warning-feedback, .tobago-messages-container.tobago-text-top .info-feedback, .tobago-messages-container.tobago-text-bottom .error-feedback, .tobago-messages-container.tobago-text-bottom .warning-feedback, .tobago-messages-container.tobago-text-bottom .info-feedback {
+  display: block;
+}
+.tobago-messages-container.tobago-text-top .error-feedback, .tobago-messages-container.tobago-text-top .warning-feedback, .tobago-messages-container.tobago-text-top .info-feedback {
+  margin-bottom: 0.25rem;
 }
 
 .tobago-popover-box {
@@ -11533,7 +11701,6 @@ tobago-messages .alert.alert-dismissible.alert-warning:before {
 tobago-messages .alert.alert-dismissible.alert-info:before {
   content: "\f646";
 }
-
 .popover .popover-body {
   white-space: pre-line;
 }
@@ -12015,7 +12182,7 @@ tobago-select-many-shuttle .tobago-body .tobago-unselected:disabled option, toba
 tobago-select-many-shuttle .tobago-body .tobago-selected:disabled option, tobago-select-many-shuttle .tobago-body .tobago-selected option:disabled {
   color: rgba(33, 37, 41, 0.5);
 }
-tobago-select-many-shuttle.tobago-label-container > .tobago-body, tobago-select-many-shuttle .tobago-messages-container > .tobago-body {
+tobago-select-many-shuttle.tobago-label-container > .tobago-body, tobago-select-many-shuttle .tobago-help-container > .tobago-body, tobago-select-many-shuttle .tobago-messages-container > .tobago-body {
   flex: 1 0 0px;
 }
 
diff --git a/tobago-theme/tobago-theme-standard/src/main/css/tobago.css.map b/tobago-theme/tobago-theme-standard/src/main/css/tobago.css.map
index d94edbbf9d..1fac7309f4 100644
--- a/tobago-theme/tobago-theme-standard/src/main/css/tobago.css.map
+++ b/tobago-theme/tobago-theme-standard/src/main/css/tobago.css.map
@@ -1 +1 @@
-{"version":3,"sources":["tobago.css","../scss/tobago-theme.scss","../../../../node_modules/bootstrap/scss/mixins/_banner.scss","../../../../node_modules/bootstrap/scss/_root.scss","../../../../node_modules/bootstrap/scss/vendor/_rfs.scss","../../../../node_modules/bootstrap/scss/_reboot.scss","../../../../node_modules/bootstrap/scss/_variables.scss","../../../../node_modules/bootstrap/scss/mixins/_border-radius.scss","../../../../node_modules/bootstrap/scss/_type.scss","../../../../node_ [...]
\ No newline at end of file
+{"version":3,"sources":["tobago.css","../scss/tobago-theme.scss","../../../../node_modules/bootstrap/scss/mixins/_banner.scss","../../../../node_modules/bootstrap/scss/_root.scss","../../../../node_modules/bootstrap/scss/vendor/_rfs.scss","../../../../node_modules/bootstrap/scss/_reboot.scss","../../../../node_modules/bootstrap/scss/_variables.scss","../../../../node_modules/bootstrap/scss/mixins/_border-radius.scss","../../../../node_modules/bootstrap/scss/_type.scss","../../../../node_ [...]
\ No newline at end of file
diff --git a/tobago-theme/tobago-theme-standard/src/main/css/tobago.min.css b/tobago-theme/tobago-theme-standard/src/main/css/tobago.min.css
index c360d7434d..7b526bd768 100644
--- a/tobago-theme/tobago-theme-standard/src/main/css/tobago.min.css
+++ b/tobago-theme/tobago-theme-standard/src/main/css/tobago.min.css
@@ -1,2 +1,2 @@
-@charset "UTF-8";:root{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#d63384;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-black:#000;--bs-white:#fff;--bs-gray:#6c757d;--bs-gray-dark:#343a40;--bs-gray-100:#f8f9fa;--bs-gray-200:#e9ecef;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#6c757d;--bs-gray-700:#495057;--bs-gray-800:#343a40;--bs-gray-900:#212529;--bs-prima [...]
+@charset "UTF-8";:root{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#d63384;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-black:#000;--bs-white:#fff;--bs-gray:#6c757d;--bs-gray-dark:#343a40;--bs-gray-100:#f8f9fa;--bs-gray-200:#e9ecef;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#6c757d;--bs-gray-700:#495057;--bs-gray-800:#343a40;--bs-gray-900:#212529;--bs-prima [...]
 /*# sourceMappingURL=tobago.min.css.map */
\ No newline at end of file
diff --git a/tobago-theme/tobago-theme-standard/src/main/css/tobago.min.css.map b/tobago-theme/tobago-theme-standard/src/main/css/tobago.min.css.map
index 52b2ff982b..68b332c53c 100644
--- a/tobago-theme/tobago-theme-standard/src/main/css/tobago.min.css.map
+++ b/tobago-theme/tobago-theme-standard/src/main/css/tobago.min.css.map
@@ -1 +1 @@
-{"version":3,"sources":["tobago-theme-standard/src/main/css/tobago.css"],"names":[],"mappings":"iBAuBA,MACE,UAAW,QACX,YAAa,QACb,YAAa,QACb,UAAW,QACX,SAAU,QACV,YAAa,QACb,YAAa,QACb,WAAY,QACZ,UAAW,QACX,UAAW,QACX,WAAY,KACZ,WAAY,KACZ,UAAW,QACX,eAAgB,QAChB,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,aAAc,QACd,eAAgB,QAChB,aAAc,QACd,UAAW,QACX,aAAc,QACd,YAAa,QACb,WAAY,QACZ,UAAW,QACX,iBAAkB,EAAE,CAAE,GAAG,CAAE,IAC3B,mBAAoB,GAAG,CAAE,GAAG,CAAE,IAC9B,iBAA [...]
\ No newline at end of file
+{"version":3,"sources":["tobago-theme-standard/src/main/css/tobago.css"],"names":[],"mappings":"iBAuBA,MACE,UAAW,QACX,YAAa,QACb,YAAa,QACb,UAAW,QACX,SAAU,QACV,YAAa,QACb,YAAa,QACb,WAAY,QACZ,UAAW,QACX,UAAW,QACX,WAAY,KACZ,WAAY,KACZ,UAAW,QACX,eAAgB,QAChB,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,cAAe,QACf,aAAc,QACd,eAAgB,QAChB,aAAc,QACd,UAAW,QACX,aAAc,QACd,YAAa,QACb,WAAY,QACZ,UAAW,QACX,iBAAkB,EAAE,CAAE,GAAG,CAAE,IAC3B,mBAAoB,GAAG,CAAE,GAAG,CAAE,IAC9B,iBAA [...]
\ No newline at end of file


[myfaces-tobago] 01/02: feat: help/message position

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 1925189014b8193dba6507e6a41263bd2b46d75c
Author: Henning Noeth <hn...@apache.org>
AuthorDate: Fri Dec 9 10:12:11 2022 +0100

    feat: help/message position
    
    * position for faces messages can be set with 'messagePosition' attribute
    * position for help message can be set with 'helpPosition' attribute
    * faces messages and help messages are always written into a data attribute. This make it easier to implement custom javascript
    * use bootstrap $form-validation-state to create CSS
    * add demo for help/message positions
    * adjust tests
    
    Issue: TOBAGO-2181
---
 .../myfaces/tobago/component/Attributes.java       |   2 +
 .../tobago/component/DecorationPosition.java       |  52 +++++++
 .../component/SupportsDecorationPosition.java      |  27 ++++
 .../tobago/internal/component/AbstractUIFile.java  |   3 +-
 .../tobago/internal/component/AbstractUIInput.java |   3 +-
 .../tobago/internal/component/AbstractUIOut.java   |   4 +-
 .../component/AbstractUISelectBoolean.java         |   3 +-
 .../component/AbstractUISelectManyBase.java        |   4 +-
 .../component/AbstractUISelectOneBase.java         |   4 +-
 .../internal/renderkit/renderer/DateRenderer.java  |   2 +-
 ...se.java => DecorationPositionRendererBase.java} | 150 ++++++++++++++++-----
 .../internal/renderkit/renderer/FileRenderer.java  |   2 +-
 .../internal/renderkit/renderer/InRenderer.java    |   2 +-
 .../internal/renderkit/renderer/OutRenderer.java   |   2 +-
 .../internal/renderkit/renderer/RangeRenderer.java |   2 +-
 .../renderer/SelectBooleanRendererBase.java        |   2 +-
 .../renderkit/renderer/SelectManyRendererBase.java |   3 +-
 .../renderkit/renderer/SelectOneRendererBase.java  |   3 +-
 .../internal/renderkit/renderer/StarsRenderer.java |   2 +-
 .../renderkit/renderer/TextareaRenderer.java       |   2 +-
 .../taglib/component/DateTagDeclaration.java       |   3 +-
 .../taglib/component/FileTagDeclaration.java       |   5 +-
 .../taglib/component/InTagDeclaration.java         |   6 +-
 .../taglib/component/OutTagDeclaration.java        |   3 +-
 .../taglib/component/RangeTagDeclaration.java      |   3 +-
 .../SelectBooleanCheckboxTagDeclaration.java       |   5 +-
 .../SelectBooleanToggleTagDeclaration.java         |   5 +-
 .../SelectManyCheckboxTagDeclaration.java          |   3 +-
 .../component/SelectManyListTagDeclaration.java    |   3 +-
 .../component/SelectManyListboxTagDeclaration.java |   5 +-
 .../component/SelectManyShuttleTagDeclaration.java |   5 +-
 .../component/SelectOneChoiceTagDeclaration.java   |   5 +-
 .../component/SelectOneListboxTagDeclaration.java  |   5 +-
 .../component/SelectOneRadioTagDeclaration.java    |   5 +-
 .../taglib/component/StarsTagDeclaration.java      |   5 +-
 .../taglib/component/TextareaTagDeclaration.java   |   3 +-
 .../taglib/declaration/HasDecorationPosition.java  |  47 +++++++
 .../tobago/renderkit/css/BootstrapClass.java       |  24 +++-
 .../myfaces/tobago/renderkit/css/TobagoClass.java  |  38 ++++++
 .../tobago/renderkit/html/DataAttributes.java      |   9 ++
 .../resources/renderer/date/error-message.html     |   2 +-
 .../src/test/resources/renderer/date/help.html     |   4 +-
 .../test/resources/renderer/in/error-message.html  |   2 +-
 .../src/test/resources/renderer/in/help.html       |   4 +-
 .../selectBooleanCheckboxError.html                |   2 +-
 .../selectBooleanCheckboxFatal.html                |   2 +-
 .../selectBooleanCheckboxInfo.html                 |   2 +-
 .../selectBooleanCheckboxWarning.html              |   2 +-
 .../selectManyCheckboxFatal.html                   |   2 +-
 .../renderer/selectManyShuttle/error-message.html  |   2 +-
 .../resources/renderer/selectManyShuttle/help.html |   4 +-
 .../resources/tobago-config-for-unit-tests.xml     |  35 +++++
 .../example/demo/DecorationPositionController.java |  54 ++++++++
 .../100-position/decorationPosition.xhtml          | 117 ++++++++++++++++
 tobago-theme/src/main/scss/_tobago.scss            | 112 ++++++++++++---
 .../src/main/resources/META-INF/tobago-config.xml  |  32 +++++
 .../org/apache/myfaces/tobago/apt/component.stg    |   4 +
 57 files changed, 728 insertions(+), 115 deletions(-)

diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/component/Attributes.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/component/Attributes.java
index 5b29c108fa..2cb97e7f92 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/component/Attributes.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/component/Attributes.java
@@ -126,6 +126,7 @@ public enum Attributes {
   gridTemplateRows,
   group,
   help,
+  helpPosition,
   height,
   hidden,
   hover,
@@ -216,6 +217,7 @@ public enum Attributes {
   media,
   method,
   messageFormat,
+  messagePosition,
   min,
   minHeight,
   minWidth,
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/component/DecorationPosition.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/component/DecorationPosition.java
new file mode 100644
index 0000000000..2b0323f6ff
--- /dev/null
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/component/DecorationPosition.java
@@ -0,0 +1,52 @@
+/*
+ * 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 enum DecorationPosition {
+  /**
+   * do not render a message to the component
+   */
+  none,
+
+  /**
+   * render a popover button with a message on the left side of the component
+   */
+  buttonLeft,
+
+  /**
+   * render a popover button with a message on the right side of the component
+   */
+  buttonRight,
+
+  /**
+   * render a tooltip under the component
+   */
+  tooltip,
+
+  /**
+   * render text message above the component
+   */
+  textTop,
+
+  /**
+   * render text message under the component
+   */
+  textBottom
+}
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/component/SupportsDecorationPosition.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/component/SupportsDecorationPosition.java
new file mode 100644
index 0000000000..d13c708e62
--- /dev/null
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/component/SupportsDecorationPosition.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 SupportsDecorationPosition {
+
+  DecorationPosition getMessagePosition();
+
+  DecorationPosition getHelpPosition();
+}
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIFile.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIFile.java
index 2005cf2d1f..4828dbde52 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIFile.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIFile.java
@@ -23,6 +23,7 @@ import org.apache.myfaces.tobago.component.SupportFieldId;
 import org.apache.myfaces.tobago.component.SupportsAutoSpacing;
 import org.apache.myfaces.tobago.component.SupportsHelp;
 import org.apache.myfaces.tobago.component.SupportsLabelLayout;
+import org.apache.myfaces.tobago.component.SupportsDecorationPosition;
 import org.apache.myfaces.tobago.component.Visual;
 import org.apache.myfaces.tobago.util.ComponentUtils;
 import org.apache.myfaces.tobago.util.MessageUtils;
@@ -37,7 +38,7 @@ import jakarta.servlet.http.Part;
  * {@link org.apache.myfaces.tobago.internal.taglib.component.FileTagDeclaration}
  */
 public abstract class AbstractUIFile extends UIInput implements SupportsLabelLayout, Visual, ClientBehaviorHolder,
-    SupportFieldId, SupportsHelp, SupportsAutoSpacing {
+    SupportFieldId, SupportsHelp, SupportsAutoSpacing, SupportsDecorationPosition {
 
   private transient boolean nextToRenderIsLabel;
 
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIInput.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIInput.java
index 8c88cd64f7..52424b3a28 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIInput.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIInput.java
@@ -24,6 +24,7 @@ import org.apache.myfaces.tobago.component.SupportsAccessKey;
 import org.apache.myfaces.tobago.component.SupportsAutoSpacing;
 import org.apache.myfaces.tobago.component.SupportsHelp;
 import org.apache.myfaces.tobago.component.SupportsLabelLayout;
+import org.apache.myfaces.tobago.component.SupportsDecorationPosition;
 import org.apache.myfaces.tobago.component.Visual;
 import org.apache.myfaces.tobago.util.ComponentUtils;
 
@@ -35,7 +36,7 @@ import jakarta.faces.context.FacesContext;
  */
 public abstract class AbstractUIInput extends jakarta.faces.component.UIInput
     implements SupportsAccessKey, SupportsAutoSpacing, SupportsLabelLayout, Visual, ClientBehaviorHolder,
-    SupportFieldId, SupportsHelp {
+    SupportFieldId, SupportsHelp, SupportsDecorationPosition {
 
   private transient boolean nextToRenderIsLabel;
 
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIOut.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIOut.java
index ea0b1631e0..36157fab90 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIOut.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIOut.java
@@ -21,6 +21,7 @@ package org.apache.myfaces.tobago.internal.component;
 
 import org.apache.myfaces.tobago.component.SupportsAutoSpacing;
 import org.apache.myfaces.tobago.component.SupportsLabelLayout;
+import org.apache.myfaces.tobago.component.SupportsDecorationPosition;
 import org.apache.myfaces.tobago.component.Visual;
 import org.apache.myfaces.tobago.sanitizer.SanitizeMode;
 
@@ -29,7 +30,8 @@ import jakarta.faces.component.UIOutput;
 /**
  * {@link org.apache.myfaces.tobago.internal.taglib.component.OutTagDeclaration}
  */
-public abstract class AbstractUIOut extends UIOutput implements SupportsLabelLayout, Visual, SupportsAutoSpacing {
+public abstract class AbstractUIOut extends UIOutput implements SupportsLabelLayout, Visual, SupportsAutoSpacing,
+    SupportsDecorationPosition {
 
   private transient boolean nextToRenderIsLabel;
 
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUISelectBoolean.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUISelectBoolean.java
index 32e66da9d6..73cc495c80 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUISelectBoolean.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUISelectBoolean.java
@@ -25,6 +25,7 @@ import org.apache.myfaces.tobago.component.SupportsAccessKey;
 import org.apache.myfaces.tobago.component.SupportsAutoSpacing;
 import org.apache.myfaces.tobago.component.SupportsHelp;
 import org.apache.myfaces.tobago.component.SupportsLabelLayout;
+import org.apache.myfaces.tobago.component.SupportsDecorationPosition;
 import org.apache.myfaces.tobago.component.Visual;
 import org.apache.myfaces.tobago.util.ComponentUtils;
 import org.apache.myfaces.tobago.util.MessageUtils;
@@ -36,7 +37,7 @@ import jakarta.faces.context.FacesContext;
 
 public abstract class AbstractUISelectBoolean extends UISelectBoolean
     implements SupportsAutoSpacing, Visual, ClientBehaviorHolder, SupportFieldId, SupportsAccessKey,
-    SupportsLabelLayout, SupportsHelp {
+    SupportsLabelLayout, SupportsHelp, SupportsDecorationPosition {
 
   private transient boolean nextToRenderIsLabel;
 
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUISelectManyBase.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUISelectManyBase.java
index 42660e362b..dc8ba4f9be 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUISelectManyBase.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUISelectManyBase.java
@@ -22,6 +22,7 @@ package org.apache.myfaces.tobago.internal.component;
 import org.apache.myfaces.tobago.component.SupportsAutoSpacing;
 import org.apache.myfaces.tobago.component.SupportsHelp;
 import org.apache.myfaces.tobago.component.SupportsLabelLayout;
+import org.apache.myfaces.tobago.component.SupportsDecorationPosition;
 import org.apache.myfaces.tobago.component.Visual;
 
 import jakarta.faces.component.UISelectMany;
@@ -34,7 +35,8 @@ import java.util.Collection;
  * Base class for multi select.
  */
 public abstract class AbstractUISelectManyBase extends UISelectMany
-    implements SupportsAutoSpacing, Visual, SupportsLabelLayout, ClientBehaviorHolder, SupportsHelp {
+    implements SupportsAutoSpacing, Visual, SupportsLabelLayout, ClientBehaviorHolder, SupportsHelp,
+    SupportsDecorationPosition {
 
   private transient boolean nextToRenderIsLabel;
 
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUISelectOneBase.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUISelectOneBase.java
index 13f75d95d0..f7f32d8dde 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUISelectOneBase.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUISelectOneBase.java
@@ -22,6 +22,7 @@ package org.apache.myfaces.tobago.internal.component;
 import org.apache.myfaces.tobago.component.SupportsAutoSpacing;
 import org.apache.myfaces.tobago.component.SupportsHelp;
 import org.apache.myfaces.tobago.component.SupportsLabelLayout;
+import org.apache.myfaces.tobago.component.SupportsDecorationPosition;
 import org.apache.myfaces.tobago.component.Visual;
 import org.apache.myfaces.tobago.util.MessageUtils;
 
@@ -33,7 +34,8 @@ import jakarta.faces.context.FacesContext;
  * Base class for select one.
  */
 public abstract class AbstractUISelectOneBase extends jakarta.faces.component.UISelectOne
-    implements SupportsAutoSpacing, Visual, SupportsLabelLayout, ClientBehaviorHolder, SupportsHelp {
+    implements SupportsAutoSpacing, Visual, SupportsLabelLayout, ClientBehaviorHolder, SupportsHelp,
+    SupportsDecorationPosition {
 
   public static final String MESSAGE_VALUE_REQUIRED = "org.apache.myfaces.tobago.UISelectOne.REQUIRED";
 
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/DateRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/DateRenderer.java
index 98877666d3..85a0f30c97 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/DateRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/DateRenderer.java
@@ -52,7 +52,7 @@ import java.time.ZonedDateTime;
 import java.time.format.DateTimeFormatter;
 import java.util.Date;
 
-public class DateRenderer<T extends AbstractUIDate> extends MessageLayoutRendererBase<T> {
+public class DateRenderer<T extends AbstractUIDate> extends DecorationPositionRendererBase<T> {
 
   private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/MessageLayoutRendererBase.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/DecorationPositionRendererBase.java
similarity index 62%
rename from tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/MessageLayoutRendererBase.java
rename to tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/DecorationPositionRendererBase.java
index 74108e9f76..7f1a9f9dbe 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/MessageLayoutRendererBase.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/DecorationPositionRendererBase.java
@@ -19,8 +19,10 @@
 
 package org.apache.myfaces.tobago.internal.renderkit.renderer;
 
+import org.apache.myfaces.tobago.component.DecorationPosition;
 import org.apache.myfaces.tobago.component.Facets;
 import org.apache.myfaces.tobago.component.SupportsAutoSpacing;
+import org.apache.myfaces.tobago.component.SupportsDecorationPosition;
 import org.apache.myfaces.tobago.component.SupportsHelp;
 import org.apache.myfaces.tobago.component.SupportsLabelLayout;
 import org.apache.myfaces.tobago.internal.component.AbstractUIButton;
@@ -48,7 +50,7 @@ import jakarta.faces.context.FacesContext;
 import java.io.IOException;
 import java.util.List;
 
-public abstract class MessageLayoutRendererBase<T extends UIComponent & SupportsLabelLayout & SupportsAutoSpacing>
+public abstract class DecorationPositionRendererBase<T extends UIComponent & SupportsLabelLayout & SupportsAutoSpacing>
     extends LabelLayoutRendererBase<T> {
 
   @Override
@@ -71,54 +73,129 @@ public abstract class MessageLayoutRendererBase<T extends UIComponent & Supports
 
   @Override
   public void encodeBeginMessageField(final FacesContext facesContext, final T component) throws IOException {
-    encodeBeginMessagesContainer(facesContext, component);
-    encodeBeginField(facesContext, component);
-  }
+    final TobagoResponseWriter writer = getResponseWriter(facesContext);
+    final Integer tabIndex = component instanceof AbstractUIInput ? ((AbstractUIInput) component).getTabIndex() : null;
+    final SupportsDecorationPosition supportsDecorationPosition = component instanceof SupportsDecorationPosition
+        ? ((SupportsDecorationPosition) component) : null;
 
-  @Override
-  public void encodeEndMessageField(final FacesContext facesContext, final T component) throws IOException {
-    encodeEndField(facesContext, component);
-    encodeEndMessagesContainer(facesContext, component);
-  }
+    final DecorationPosition helpPosition = supportsDecorationPosition != null
+        ? supportsDecorationPosition.getHelpPosition() : DecorationPosition.none;
+    final String help = component instanceof SupportsHelp ? ((SupportsHelp) component).getHelp() : null;
 
-  private void encodeBeginMessagesContainer(final FacesContext facesContext, final T component)
-      throws IOException {
-    final TobagoResponseWriter writer = getResponseWriter(facesContext);
+    if (!StringUtils.isEmpty(help)) {
+      writer.startElement(HtmlElements.DIV);
+      writer.writeClassAttribute(TobagoClass.HELP__CONTAINER, TobagoClass.valueOf(helpPosition));
+      writer.writeAttribute(DataAttributes.HELP, help, true);
+
+      switch (helpPosition) {
+        case buttonLeft:
+          final String title = ResourceUtils.getString(facesContext, "help.title");
+          encodePopover(writer, BootstrapClass.BTN_OUTLINE_INFO, Icons.QUESTION_LG, title, help, tabIndex);
+          break;
+        case textTop:
+          writer.startElement(HtmlElements.DIV);
+          writer.writeClassAttribute(BootstrapClass.HELP_FEEDBACK);
+          writer.writeText(help);
+          writer.endElement(HtmlElements.DIV);
+        default:
+      }
+    }
 
+    final DecorationPosition messagePosition = supportsDecorationPosition != null
+        ? supportsDecorationPosition.getMessagePosition() : DecorationPosition.none;
     final String clientId = component.getClientId();
     final List<FacesMessage> messages = facesContext.getMessageList(clientId);
-    final String help = component instanceof SupportsHelp ? ((SupportsHelp) component).getHelp() : null;
-    final boolean hasMessage = !messages.isEmpty();
-    final boolean hasHelp = !StringUtils.isEmpty(help);
+    final String message = getMessage(messages);
+    final FacesMessage.Severity severity = ComponentUtils.getMaximumSeverity(messages);
 
-    if (hasMessage || hasHelp) {
+    if (!StringUtils.isEmpty(message)) {
       writer.startElement(HtmlElements.DIV);
-      writer.writeClassAttribute(TobagoClass.MESSAGES__CONTAINER);
+      writer.writeClassAttribute(TobagoClass.MESSAGES__CONTAINER, TobagoClass.valueOf(messagePosition));
+      writer.writeAttribute(DataAttributes.FACES_MESSAGE, message, true);
+
+      switch (messagePosition) {
+        case buttonLeft:
+          final CssItem buttonColor = BootstrapClass.buttonColor(severity);
+          encodePopover(writer, buttonColor, Icons.EXCLAMATION_LG, getTitle(messages), message, tabIndex);
+          break;
+        case textTop:
+          final CssItem feedback = BootstrapClass.feedbackColor(severity);
+          writer.startElement(HtmlElements.DIV);
+          writer.writeClassAttribute(feedback);
+          writer.writeText(message);
+          writer.endElement(HtmlElements.DIV);
+        default:
+      }
     }
+
+    encodeBeginField(facesContext, component);
   }
 
-  private void encodeEndMessagesContainer(final FacesContext facesContext, final T component)
-      throws IOException {
+  @Override
+  public void encodeEndMessageField(final FacesContext facesContext, final T component) throws IOException {
     final TobagoResponseWriter writer = getResponseWriter(facesContext);
+    final Integer tabIndex = component instanceof AbstractUIInput ? ((AbstractUIInput) component).getTabIndex() : null;
+    final SupportsDecorationPosition supportsDecorationPosition = component instanceof SupportsDecorationPosition
+        ? ((SupportsDecorationPosition) component) : null;
 
+    encodeEndField(facesContext, component);
+
+    final DecorationPosition messagePosition = supportsDecorationPosition != null
+        ? supportsDecorationPosition.getMessagePosition() : DecorationPosition.none;
     final String clientId = component.getClientId();
     final List<FacesMessage> messages = facesContext.getMessageList(clientId);
-    final String help = component instanceof SupportsHelp ? ((SupportsHelp) component).getHelp() : null;
-    final boolean hasMessage = !messages.isEmpty();
-    final boolean hasHelp = !StringUtils.isEmpty(help);
-
-    if (hasMessage || hasHelp) {
-      Integer tabIndex = (component instanceof AbstractUIInput) ? ((AbstractUIInput) component).getTabIndex() : null;
-      if (hasMessage) {
-        encodePopover(writer,
-            BootstrapClass.buttonColor(ComponentUtils.getMaximumSeverity(messages)),
-            Icons.EXCLAMATION_LG, getTitle(messages), getMessage(messages), tabIndex);
+    final String message = getMessage(messages);
+    final FacesMessage.Severity severity = ComponentUtils.getMaximumSeverity(messages);
+
+    if (!StringUtils.isEmpty(message)) {
+      switch (messagePosition) {
+        case buttonRight:
+          final CssItem buttonColor = BootstrapClass.buttonColor(severity);
+          encodePopover(writer, buttonColor, Icons.EXCLAMATION_LG, getTitle(messages), message, tabIndex);
+          break;
+        case tooltip:
+          final CssItem tooltip = BootstrapClass.tooltipColor(severity);
+          writer.startElement(HtmlElements.DIV);
+          writer.writeClassAttribute(tooltip);
+          writer.writeText(message);
+          writer.endElement(HtmlElements.DIV);
+          break;
+        case textBottom:
+          final CssItem feedback = BootstrapClass.feedbackColor(severity);
+          writer.startElement(HtmlElements.DIV);
+          writer.writeClassAttribute(feedback);
+          writer.writeText(message);
+          writer.endElement(HtmlElements.DIV);
+        default:
       }
-      if (hasHelp) {
-        encodePopover(writer,
-            BootstrapClass.BTN_OUTLINE_INFO, Icons.QUESTION_LG,
-            ResourceUtils.getString(facesContext, "help.title"), help, tabIndex);
+
+      writer.endElement(HtmlElements.DIV);
+    }
+
+    final DecorationPosition helpPosition = supportsDecorationPosition != null
+        ? supportsDecorationPosition.getHelpPosition() : DecorationPosition.none;
+    final String title = ResourceUtils.getString(facesContext, "help.title");
+    final String help = component instanceof SupportsHelp ? ((SupportsHelp) component).getHelp() : null;
+
+    if (!StringUtils.isEmpty(help)) {
+      switch (helpPosition) {
+        case buttonRight:
+          encodePopover(writer, BootstrapClass.BTN_OUTLINE_INFO, Icons.QUESTION_LG, title, help, tabIndex);
+          break;
+        case tooltip:
+          writer.startElement(HtmlElements.DIV);
+          writer.writeClassAttribute(BootstrapClass.HELP_TOOLTIP);
+          writer.writeText(help);
+          writer.endElement(HtmlElements.DIV);
+          break;
+        case textBottom:
+          writer.startElement(HtmlElements.DIV);
+          writer.writeClassAttribute(BootstrapClass.HELP_FEEDBACK);
+          writer.writeText(help);
+          writer.endElement(HtmlElements.DIV);
+        default:
       }
+
       writer.endElement(HtmlElements.DIV);
     }
   }
@@ -215,8 +292,7 @@ public abstract class MessageLayoutRendererBase<T extends UIComponent & Supports
 
   private void encodePopover(
       final TobagoResponseWriter writer, final CssItem buttonColor, final Icons icon, final String title,
-      final String content, final Integer tabIndex)
-      throws IOException {
+      final String content, final Integer tabIndex) throws IOException {
     writer.startElement(HtmlElements.TOBAGO_POPOVER);
     writer.writeAttribute(DataAttributes.BS_TOGGLE, "popover", false);
     writer.writeAttribute(HtmlAttributes.TITLE, title, true);
@@ -236,8 +312,8 @@ public abstract class MessageLayoutRendererBase<T extends UIComponent & Supports
   }
 
   protected void encodeGroupAddon(
-      final FacesContext facesContext, final TobagoResponseWriter writer,
-      final UIComponent addon, final boolean isAfterFacet) throws IOException {
+      final FacesContext facesContext, final TobagoResponseWriter writer, final UIComponent addon,
+      final boolean isAfterFacet) throws IOException {
     if (addon != null) {
       for (final UIComponent child : RenderUtils.getFacetChildren(addon)) {
         insideBegin(facesContext, isAfterFacet ? Facets.after : Facets.before);
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/FileRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/FileRenderer.java
index b2c1de17eb..284db56453 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/FileRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/FileRenderer.java
@@ -52,7 +52,7 @@ import java.util.List;
 
 @ListenerFor(systemEventClass = PostAddToViewEvent.class)
 public class FileRenderer<T extends AbstractUIFile>
-    extends MessageLayoutRendererBase<T> implements ComponentSystemEventListener {
+    extends DecorationPositionRendererBase<T> implements ComponentSystemEventListener {
 
   private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/InRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/InRenderer.java
index e80e011919..4daf31b59e 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/InRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/InRenderer.java
@@ -44,7 +44,7 @@ import org.slf4j.LoggerFactory;
 import java.io.IOException;
 import java.lang.invoke.MethodHandles;
 
-public class InRenderer<T extends AbstractUIIn> extends MessageLayoutRendererBase<T> {
+public class InRenderer<T extends AbstractUIIn> extends DecorationPositionRendererBase<T> {
 
   private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/OutRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/OutRenderer.java
index 94a707d02d..4684c3c4cc 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/OutRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/OutRenderer.java
@@ -43,7 +43,7 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.StringTokenizer;
 
-public class OutRenderer<T extends AbstractUIOut> extends MessageLayoutRendererBase<T> {
+public class OutRenderer<T extends AbstractUIOut> extends DecorationPositionRendererBase<T> {
 
   private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/RangeRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/RangeRenderer.java
index e32c2856f5..be0e481521 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/RangeRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/RangeRenderer.java
@@ -35,7 +35,7 @@ import jakarta.faces.context.FacesContext;
 
 import java.io.IOException;
 
-public class RangeRenderer<T extends AbstractUIRange> extends MessageLayoutRendererBase<T> {
+public class RangeRenderer<T extends AbstractUIRange> extends DecorationPositionRendererBase<T> {
 
   @Override
   protected boolean isOutputOnly(T component) {
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectBooleanRendererBase.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectBooleanRendererBase.java
index 3aa44fd850..c5714c186c 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectBooleanRendererBase.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectBooleanRendererBase.java
@@ -40,7 +40,7 @@ import java.io.IOException;
 import java.lang.invoke.MethodHandles;
 
 public abstract class SelectBooleanRendererBase<T extends AbstractUISelectBoolean>
-    extends MessageLayoutRendererBase<T> {
+    extends DecorationPositionRendererBase<T> {
 
   private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectManyRendererBase.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectManyRendererBase.java
index c70877b2a7..213eef58af 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectManyRendererBase.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectManyRendererBase.java
@@ -55,7 +55,8 @@ import java.util.Set;
 import java.util.SortedSet;
 import java.util.TreeSet;
 
-public abstract class SelectManyRendererBase<T extends AbstractUISelectManyBase> extends MessageLayoutRendererBase<T> {
+public abstract class SelectManyRendererBase<T extends AbstractUISelectManyBase> extends
+    DecorationPositionRendererBase<T> {
 
   private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectOneRendererBase.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectOneRendererBase.java
index e0b85d3b07..b86f41d2d9 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectOneRendererBase.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectOneRendererBase.java
@@ -27,7 +27,8 @@ import jakarta.faces.context.FacesContext;
 
 import java.lang.invoke.MethodHandles;
 
-public abstract class SelectOneRendererBase<T extends AbstractUISelectOneBase> extends MessageLayoutRendererBase<T> {
+public abstract class SelectOneRendererBase<T extends AbstractUISelectOneBase> extends
+    DecorationPositionRendererBase<T> {
 
   private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/StarsRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/StarsRenderer.java
index 579391b5b5..4bbcae9917 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/StarsRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/StarsRenderer.java
@@ -33,7 +33,7 @@ import jakarta.faces.context.FacesContext;
 
 import java.io.IOException;
 
-public class StarsRenderer<T extends AbstractUIStars> extends MessageLayoutRendererBase<T> {
+public class StarsRenderer<T extends AbstractUIStars> extends DecorationPositionRendererBase<T> {
 
   @Override
   protected boolean isOutputOnly(T component) {
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/TextareaRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/TextareaRenderer.java
index 72eabd236b..5f6bc4ed58 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/TextareaRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/TextareaRenderer.java
@@ -42,7 +42,7 @@ import jakarta.faces.validator.Validator;
 
 import java.io.IOException;
 
-public class TextareaRenderer<T extends AbstractUITextarea> extends MessageLayoutRendererBase<T> {
+public class TextareaRenderer<T extends AbstractUITextarea> extends DecorationPositionRendererBase<T> {
 
   @Override
   protected boolean isOutputOnly(T component) {
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/DateTagDeclaration.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/DateTagDeclaration.java
index 323265bd0c..102c085175 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/DateTagDeclaration.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/DateTagDeclaration.java
@@ -36,6 +36,7 @@ import org.apache.myfaces.tobago.internal.taglib.declaration.HasHelp;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasIdBindingAndRendered;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasLabel;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasLabelLayout;
+import org.apache.myfaces.tobago.internal.taglib.declaration.HasDecorationPosition;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasPlaceholder;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasRequiredMessage;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasTabIndex;
@@ -93,7 +94,7 @@ import jakarta.faces.component.UIInput;
 public interface DateTagDeclaration
     extends HasAccessKey, HasValidator, HasValue, HasValueChangeListener, HasTabIndex, IsFocus, IsVisual,
     HasValidatorMessage, HasConverterMessage, HasRequiredMessage, HasIdBindingAndRendered, IsReadonly,
-    IsDisabled, HasConverter, HasLabel, HasHelp, HasLabelLayout,
+    IsDisabled, HasConverter, HasLabel, HasHelp, HasLabelLayout, HasDecorationPosition,
     HasTip, IsRequired, HasPlaceholder, HasAutoSpacing {
 
   /**
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/FileTagDeclaration.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/FileTagDeclaration.java
index f0d7b8195f..0aa510ea0b 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/FileTagDeclaration.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/FileTagDeclaration.java
@@ -28,18 +28,19 @@ import org.apache.myfaces.tobago.apt.annotation.UIComponentTagAttribute;
 import org.apache.myfaces.tobago.component.ClientBehaviors;
 import org.apache.myfaces.tobago.component.RendererTypes;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasAccessKey;
+import org.apache.myfaces.tobago.internal.taglib.declaration.HasAutoSpacing;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasConverterMessage;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasHelp;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasIdBindingAndRendered;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasLabel;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasLabelLayout;
+import org.apache.myfaces.tobago.internal.taglib.declaration.HasDecorationPosition;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasRequiredMessage;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasTabIndex;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasTip;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasValidator;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasValidatorMessage;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasValueChangeListener;
-import org.apache.myfaces.tobago.internal.taglib.declaration.HasAutoSpacing;
 import org.apache.myfaces.tobago.internal.taglib.declaration.IsDisabled;
 import org.apache.myfaces.tobago.internal.taglib.declaration.IsFocus;
 import org.apache.myfaces.tobago.internal.taglib.declaration.IsMultiple;
@@ -83,7 +84,7 @@ public interface FileTagDeclaration
     extends HasValidator, HasValidatorMessage, HasRequiredMessage, HasConverterMessage,
     HasValueChangeListener, HasIdBindingAndRendered, IsDisabled, IsFocus, IsMultiple,
     HasLabel, HasLabelLayout, HasAccessKey, HasTip, HasHelp, IsReadonly, IsRequired, HasTabIndex, IsVisual,
-    HasAutoSpacing {
+    HasAutoSpacing, HasDecorationPosition {
 
   /**
    * Value binding expression pointing to a
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/InTagDeclaration.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/InTagDeclaration.java
index 5bc422135a..d90fc08392 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/InTagDeclaration.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/InTagDeclaration.java
@@ -28,6 +28,7 @@ import org.apache.myfaces.tobago.component.ClientBehaviors;
 import org.apache.myfaces.tobago.component.Facets;
 import org.apache.myfaces.tobago.component.RendererTypes;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasAccessKey;
+import org.apache.myfaces.tobago.internal.taglib.declaration.HasAutoSpacing;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasAutocomplete;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasConverter;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasConverterMessage;
@@ -35,6 +36,7 @@ import org.apache.myfaces.tobago.internal.taglib.declaration.HasHelp;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasIdBindingAndRendered;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasLabel;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasLabelLayout;
+import org.apache.myfaces.tobago.internal.taglib.declaration.HasDecorationPosition;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasPlaceholder;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasRequiredMessage;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasTabIndex;
@@ -43,7 +45,6 @@ import org.apache.myfaces.tobago.internal.taglib.declaration.HasValidator;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasValidatorMessage;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasValue;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasValueChangeListener;
-import org.apache.myfaces.tobago.internal.taglib.declaration.HasAutoSpacing;
 import org.apache.myfaces.tobago.internal.taglib.declaration.IsDisabled;
 import org.apache.myfaces.tobago.internal.taglib.declaration.IsFocus;
 import org.apache.myfaces.tobago.internal.taglib.declaration.IsPassword;
@@ -98,7 +99,6 @@ import jakarta.faces.component.UIInput;
 public interface InTagDeclaration
     extends HasIdBindingAndRendered, HasConverter, IsReadonly, IsDisabled, IsRequired, HasHelp, HasTip, IsPassword,
     HasAccessKey, HasValidator, HasValue, HasValueChangeListener, HasTabIndex, IsFocus, IsVisual,
-    HasValidatorMessage, HasConverterMessage, HasRequiredMessage, HasLabel, HasLabelLayout,
+    HasValidatorMessage, HasConverterMessage, HasRequiredMessage, HasLabel, HasLabelLayout, HasDecorationPosition,
     HasAutocomplete, HasPlaceholder, HasAutoSpacing {
-
 }
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/OutTagDeclaration.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/OutTagDeclaration.java
index 8813a028b5..9ac6225d15 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/OutTagDeclaration.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/OutTagDeclaration.java
@@ -31,6 +31,7 @@ import org.apache.myfaces.tobago.internal.taglib.declaration.HasConverter;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasIdBindingAndRendered;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasLabel;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasLabelLayout;
+import org.apache.myfaces.tobago.internal.taglib.declaration.HasDecorationPosition;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasSanitize;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasTip;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasValue;
@@ -57,7 +58,7 @@ import java.text.MessageFormat;
 
 public interface OutTagDeclaration
     extends HasIdBindingAndRendered, HasConverter, HasTip, HasValue, IsVisual,
-    HasSanitize, HasLabel, HasLabelLayout, IsPlain, HasAutoSpacing {
+    HasSanitize, HasLabel, HasLabelLayout, IsPlain, HasAutoSpacing, HasDecorationPosition {
 
   /**
    * Flag indicating that characters that are
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/RangeTagDeclaration.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/RangeTagDeclaration.java
index e9d6e26e24..7d34bcc4f4 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/RangeTagDeclaration.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/RangeTagDeclaration.java
@@ -35,6 +35,7 @@ import org.apache.myfaces.tobago.internal.taglib.declaration.HasHelp;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasIdBindingAndRendered;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasLabel;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasLabelLayout;
+import org.apache.myfaces.tobago.internal.taglib.declaration.HasDecorationPosition;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasTabIndex;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasTip;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasValidator;
@@ -76,7 +77,7 @@ import jakarta.faces.component.UIInput;
 public interface RangeTagDeclaration
     extends HasIdBindingAndRendered, HasConverter, IsReadonly, IsDisabled, HasHelp, HasTip,
     HasAccessKey, HasValidator, HasValue, HasValueChangeListener, HasTabIndex, IsFocus, IsVisual,
-    HasValidatorMessage, HasConverterMessage, HasLabel, HasLabelLayout, HasAutoSpacing {
+    HasValidatorMessage, HasConverterMessage, HasLabel, HasLabelLayout, HasDecorationPosition, HasAutoSpacing {
 
   /**
    * Sets the minimum value of the range.
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectBooleanCheckboxTagDeclaration.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectBooleanCheckboxTagDeclaration.java
index a79166fc85..339c495202 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectBooleanCheckboxTagDeclaration.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectBooleanCheckboxTagDeclaration.java
@@ -26,6 +26,7 @@ import org.apache.myfaces.tobago.apt.annotation.UIComponentTag;
 import org.apache.myfaces.tobago.component.ClientBehaviors;
 import org.apache.myfaces.tobago.component.RendererTypes;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasAccessKey;
+import org.apache.myfaces.tobago.internal.taglib.declaration.HasAutoSpacing;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasConverter;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasConverterMessage;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasHelp;
@@ -34,6 +35,7 @@ import org.apache.myfaces.tobago.internal.taglib.declaration.HasItemImage;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasItemLabel;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasLabel;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasLabelLayout;
+import org.apache.myfaces.tobago.internal.taglib.declaration.HasDecorationPosition;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasRequiredMessageForSelect;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasTabIndex;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasTip;
@@ -41,7 +43,6 @@ import org.apache.myfaces.tobago.internal.taglib.declaration.HasValidator;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasValidatorMessage;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasValue;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasValueChangeListener;
-import org.apache.myfaces.tobago.internal.taglib.declaration.HasAutoSpacing;
 import org.apache.myfaces.tobago.internal.taglib.declaration.IsDisabled;
 import org.apache.myfaces.tobago.internal.taglib.declaration.IsFocus;
 import org.apache.myfaces.tobago.internal.taglib.declaration.IsReadonly;
@@ -81,5 +82,5 @@ public interface SelectBooleanCheckboxTagDeclaration extends HasValidator,
     HasValueChangeListener, HasIdBindingAndRendered, HasValue, IsDisabled,
     HasTip, HasHelp, IsReadonly, HasTabIndex, IsRequiredForSelect, HasConverter, IsFocus,
     HasValidatorMessage, HasRequiredMessageForSelect, HasConverterMessage, IsVisual,
-    HasAccessKey, HasItemLabel, HasItemImage, HasLabel, HasLabelLayout, HasAutoSpacing {
+    HasAccessKey, HasItemLabel, HasItemImage, HasLabel, HasLabelLayout, HasAutoSpacing, HasDecorationPosition {
 }
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectBooleanToggleTagDeclaration.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectBooleanToggleTagDeclaration.java
index aef3f28d4f..d4509049d4 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectBooleanToggleTagDeclaration.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectBooleanToggleTagDeclaration.java
@@ -26,6 +26,7 @@ import org.apache.myfaces.tobago.apt.annotation.UIComponentTag;
 import org.apache.myfaces.tobago.component.ClientBehaviors;
 import org.apache.myfaces.tobago.component.RendererTypes;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasAccessKey;
+import org.apache.myfaces.tobago.internal.taglib.declaration.HasAutoSpacing;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasConverter;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasConverterMessage;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasHelp;
@@ -34,6 +35,7 @@ import org.apache.myfaces.tobago.internal.taglib.declaration.HasItemImage;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasItemLabel;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasLabel;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasLabelLayout;
+import org.apache.myfaces.tobago.internal.taglib.declaration.HasDecorationPosition;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasRequiredMessageForSelect;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasTabIndex;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasTip;
@@ -41,7 +43,6 @@ import org.apache.myfaces.tobago.internal.taglib.declaration.HasValidator;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasValidatorMessage;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasValue;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasValueChangeListener;
-import org.apache.myfaces.tobago.internal.taglib.declaration.HasAutoSpacing;
 import org.apache.myfaces.tobago.internal.taglib.declaration.IsDisabled;
 import org.apache.myfaces.tobago.internal.taglib.declaration.IsFocus;
 import org.apache.myfaces.tobago.internal.taglib.declaration.IsReadonly;
@@ -81,5 +82,5 @@ public interface SelectBooleanToggleTagDeclaration extends HasValidator,
     HasValueChangeListener, HasIdBindingAndRendered, HasValue, IsDisabled,
     HasTip, HasHelp, IsReadonly, HasTabIndex, IsRequiredForSelect, HasConverter, IsFocus,
     HasValidatorMessage, HasRequiredMessageForSelect, HasConverterMessage, IsVisual,
-    HasAccessKey, HasItemLabel, HasItemImage, HasLabel, HasLabelLayout, HasAutoSpacing {
+    HasAccessKey, HasItemLabel, HasItemImage, HasLabel, HasLabelLayout, HasAutoSpacing, HasDecorationPosition {
 }
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectManyCheckboxTagDeclaration.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectManyCheckboxTagDeclaration.java
index aa380d1b1a..d3327b56a8 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectManyCheckboxTagDeclaration.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectManyCheckboxTagDeclaration.java
@@ -36,6 +36,7 @@ import org.apache.myfaces.tobago.internal.taglib.declaration.HasHelp;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasId;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasLabel;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasLabelLayout;
+import org.apache.myfaces.tobago.internal.taglib.declaration.HasDecorationPosition;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasRenderRange;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasRequiredMessageForSelect;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasTabIndex;
@@ -83,7 +84,7 @@ import jakarta.faces.component.UISelectMany;
     })
 public interface SelectManyCheckboxTagDeclaration extends
     IsDisabled, HasId, HasTip, HasHelp, IsInline, HasRenderRange, IsRendered, IsRequiredForSelect,
-    HasBinding, IsReadonly, HasConverter, HasLabelLayout,
+    HasBinding, IsReadonly, HasConverter, HasLabelLayout, HasDecorationPosition,
     HasLabel, HasValidator, HasValueChangeListener,
     HasValidatorMessage, HasConverterMessage, HasRequiredMessageForSelect, HasTabIndex, IsFocus, IsVisual,
     HasAutoSpacing, HasGroup {
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectManyListTagDeclaration.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectManyListTagDeclaration.java
index ad0d7bea28..c0f03f1be3 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectManyListTagDeclaration.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectManyListTagDeclaration.java
@@ -37,6 +37,7 @@ import org.apache.myfaces.tobago.internal.taglib.declaration.HasHelp;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasId;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasLabel;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasLabelLayout;
+import org.apache.myfaces.tobago.internal.taglib.declaration.HasDecorationPosition;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasRequiredMessageForSelect;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasTabIndex;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasTip;
@@ -82,7 +83,7 @@ public interface SelectManyListTagDeclaration
     extends HasId, IsDisabled, IsRendered, HasBinding, HasTip, HasHelp,
     IsReadonly, HasConverter, IsRequiredForSelect, HasLabel, HasValidator, HasValueChangeListener, HasLabelLayout,
     HasValidatorMessage, HasConverterMessage, HasRequiredMessageForSelect, HasTabIndex, IsFocus, IsVisual,
-    HasAutoSpacing, HasFilter, IsExpanded {
+    HasAutoSpacing, HasFilter, IsExpanded, HasDecorationPosition {
 
   /**
    * The value of the multi select.
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectManyListboxTagDeclaration.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectManyListboxTagDeclaration.java
index d025e8f809..57c9ed48a4 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectManyListboxTagDeclaration.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectManyListboxTagDeclaration.java
@@ -27,6 +27,7 @@ import org.apache.myfaces.tobago.apt.annotation.UIComponentTag;
 import org.apache.myfaces.tobago.apt.annotation.UIComponentTagAttribute;
 import org.apache.myfaces.tobago.component.ClientBehaviors;
 import org.apache.myfaces.tobago.component.RendererTypes;
+import org.apache.myfaces.tobago.internal.taglib.declaration.HasAutoSpacing;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasBinding;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasConverter;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasConverterMessage;
@@ -34,6 +35,7 @@ import org.apache.myfaces.tobago.internal.taglib.declaration.HasHelp;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasId;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasLabel;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasLabelLayout;
+import org.apache.myfaces.tobago.internal.taglib.declaration.HasDecorationPosition;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasRequiredMessageForSelect;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasSize;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasTabIndex;
@@ -41,7 +43,6 @@ import org.apache.myfaces.tobago.internal.taglib.declaration.HasTip;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasValidator;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasValidatorMessage;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasValueChangeListener;
-import org.apache.myfaces.tobago.internal.taglib.declaration.HasAutoSpacing;
 import org.apache.myfaces.tobago.internal.taglib.declaration.IsDisabled;
 import org.apache.myfaces.tobago.internal.taglib.declaration.IsFocus;
 import org.apache.myfaces.tobago.internal.taglib.declaration.IsReadonly;
@@ -87,7 +88,7 @@ public interface SelectManyListboxTagDeclaration
     extends HasId, IsDisabled, IsRendered, HasBinding, HasTip, HasHelp,
     IsReadonly, HasConverter, IsRequiredForSelect, HasLabel, HasValidator, HasValueChangeListener, HasLabelLayout,
     HasValidatorMessage, HasConverterMessage, HasRequiredMessageForSelect, HasTabIndex, IsFocus, IsVisual, HasSize,
-    HasAutoSpacing {
+    HasAutoSpacing, HasDecorationPosition {
 
   /**
    * The value of the multi select.
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectManyShuttleTagDeclaration.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectManyShuttleTagDeclaration.java
index 375088e3c0..adcf1aea2c 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectManyShuttleTagDeclaration.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectManyShuttleTagDeclaration.java
@@ -28,6 +28,7 @@ import org.apache.myfaces.tobago.apt.annotation.UIComponentTag;
 import org.apache.myfaces.tobago.apt.annotation.UIComponentTagAttribute;
 import org.apache.myfaces.tobago.component.ClientBehaviors;
 import org.apache.myfaces.tobago.component.RendererTypes;
+import org.apache.myfaces.tobago.internal.taglib.declaration.HasAutoSpacing;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasBinding;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasConverter;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasConverterMessage;
@@ -35,6 +36,7 @@ import org.apache.myfaces.tobago.internal.taglib.declaration.HasHelp;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasId;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasLabel;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasLabelLayout;
+import org.apache.myfaces.tobago.internal.taglib.declaration.HasDecorationPosition;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasRequiredMessageForSelect;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasSize;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasTabIndex;
@@ -42,7 +44,6 @@ import org.apache.myfaces.tobago.internal.taglib.declaration.HasTip;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasValidator;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasValidatorMessage;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasValueChangeListener;
-import org.apache.myfaces.tobago.internal.taglib.declaration.HasAutoSpacing;
 import org.apache.myfaces.tobago.internal.taglib.declaration.IsDisabled;
 import org.apache.myfaces.tobago.internal.taglib.declaration.IsFocus;
 import org.apache.myfaces.tobago.internal.taglib.declaration.IsReadonly;
@@ -87,7 +88,7 @@ public interface SelectManyShuttleTagDeclaration extends
     IsDisabled, HasId, HasTip, HasHelp, IsRendered, IsRequiredForSelect, HasBinding, IsReadonly, HasConverter,
     HasLabel, HasValidator, HasValueChangeListener, HasLabelLayout,
     HasValidatorMessage, HasConverterMessage, HasRequiredMessageForSelect, HasTabIndex, IsFocus, IsVisual, HasSize,
-    HasAutoSpacing {
+    HasAutoSpacing, HasDecorationPosition {
 
   /**
    * The value of the multi select.
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectOneChoiceTagDeclaration.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectOneChoiceTagDeclaration.java
index 3271510c20..351674f969 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectOneChoiceTagDeclaration.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectOneChoiceTagDeclaration.java
@@ -27,6 +27,7 @@ import org.apache.myfaces.tobago.apt.annotation.UIComponentTag;
 import org.apache.myfaces.tobago.apt.annotation.UIComponentTagAttribute;
 import org.apache.myfaces.tobago.component.ClientBehaviors;
 import org.apache.myfaces.tobago.component.RendererTypes;
+import org.apache.myfaces.tobago.internal.taglib.declaration.HasAutoSpacing;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasBinding;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasConverter;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasConverterMessage;
@@ -34,6 +35,7 @@ import org.apache.myfaces.tobago.internal.taglib.declaration.HasHelp;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasId;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasLabel;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasLabelLayout;
+import org.apache.myfaces.tobago.internal.taglib.declaration.HasDecorationPosition;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasRequiredMessage;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasTabIndex;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasTip;
@@ -41,7 +43,6 @@ import org.apache.myfaces.tobago.internal.taglib.declaration.HasValidator;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasValidatorMessage;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasValue;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasValueChangeListener;
-import org.apache.myfaces.tobago.internal.taglib.declaration.HasAutoSpacing;
 import org.apache.myfaces.tobago.internal.taglib.declaration.IsDisabled;
 import org.apache.myfaces.tobago.internal.taglib.declaration.IsFocus;
 import org.apache.myfaces.tobago.internal.taglib.declaration.IsReadonly;
@@ -82,7 +83,7 @@ import jakarta.faces.component.UISelectOne;
 public interface SelectOneChoiceTagDeclaration
     extends HasValidator, HasValue, HasValueChangeListener, HasTabIndex, IsFocus, IsVisual,
     HasValidatorMessage, HasConverterMessage, HasRequiredMessage, HasId, IsDisabled, IsReadonly, HasLabel,
-    IsRendered, HasConverter, HasBinding, HasTip, HasHelp, HasLabelLayout, HasAutoSpacing {
+    IsRendered, HasConverter, HasBinding, HasTip, HasHelp, HasLabelLayout, HasAutoSpacing, HasDecorationPosition {
 
   /**
    * Flag indicating that selecting an Item representing a value is required.
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectOneListboxTagDeclaration.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectOneListboxTagDeclaration.java
index 744352b201..f006090b52 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectOneListboxTagDeclaration.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectOneListboxTagDeclaration.java
@@ -28,6 +28,7 @@ import org.apache.myfaces.tobago.apt.annotation.UIComponentTag;
 import org.apache.myfaces.tobago.apt.annotation.UIComponentTagAttribute;
 import org.apache.myfaces.tobago.component.ClientBehaviors;
 import org.apache.myfaces.tobago.component.RendererTypes;
+import org.apache.myfaces.tobago.internal.taglib.declaration.HasAutoSpacing;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasBinding;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasConverter;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasConverterMessage;
@@ -35,6 +36,7 @@ import org.apache.myfaces.tobago.internal.taglib.declaration.HasHelp;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasId;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasLabel;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasLabelLayout;
+import org.apache.myfaces.tobago.internal.taglib.declaration.HasDecorationPosition;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasRequiredMessage;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasSize;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasTabIndex;
@@ -43,7 +45,6 @@ import org.apache.myfaces.tobago.internal.taglib.declaration.HasValidator;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasValidatorMessage;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasValue;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasValueChangeListener;
-import org.apache.myfaces.tobago.internal.taglib.declaration.HasAutoSpacing;
 import org.apache.myfaces.tobago.internal.taglib.declaration.IsDisabled;
 import org.apache.myfaces.tobago.internal.taglib.declaration.IsFocus;
 import org.apache.myfaces.tobago.internal.taglib.declaration.IsReadonly;
@@ -90,7 +91,7 @@ import jakarta.faces.component.UISelectOne;
 public interface SelectOneListboxTagDeclaration
     extends HasValidator, HasValue, HasValueChangeListener, HasTabIndex, IsFocus, IsVisual,
     HasValidatorMessage, HasConverterMessage, HasRequiredMessage, HasId, IsDisabled, IsReadonly, HasLabel, IsRendered,
-    HasBinding, HasTip, HasHelp, HasConverter, HasLabelLayout, HasSize, HasAutoSpacing {
+    HasBinding, HasTip, HasHelp, HasConverter, HasLabelLayout, HasSize, HasAutoSpacing, HasDecorationPosition {
 
   /**
    * Flag indicating that selecting an Item representing a Value is Required.
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectOneRadioTagDeclaration.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectOneRadioTagDeclaration.java
index 0cae987c4b..6c6dc09044 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectOneRadioTagDeclaration.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectOneRadioTagDeclaration.java
@@ -27,6 +27,7 @@ import org.apache.myfaces.tobago.apt.annotation.UIComponentTag;
 import org.apache.myfaces.tobago.apt.annotation.UIComponentTagAttribute;
 import org.apache.myfaces.tobago.component.ClientBehaviors;
 import org.apache.myfaces.tobago.component.RendererTypes;
+import org.apache.myfaces.tobago.internal.taglib.declaration.HasAutoSpacing;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasBinding;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasConverter;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasConverterMessage;
@@ -35,6 +36,7 @@ import org.apache.myfaces.tobago.internal.taglib.declaration.HasHelp;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasId;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasLabel;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasLabelLayout;
+import org.apache.myfaces.tobago.internal.taglib.declaration.HasDecorationPosition;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasRenderRange;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasRequiredMessage;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasTabIndex;
@@ -43,7 +45,6 @@ import org.apache.myfaces.tobago.internal.taglib.declaration.HasValidator;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasValidatorMessage;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasValue;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasValueChangeListener;
-import org.apache.myfaces.tobago.internal.taglib.declaration.HasAutoSpacing;
 import org.apache.myfaces.tobago.internal.taglib.declaration.IsDisabled;
 import org.apache.myfaces.tobago.internal.taglib.declaration.IsFocus;
 import org.apache.myfaces.tobago.internal.taglib.declaration.IsInline;
@@ -86,7 +87,7 @@ public interface SelectOneRadioTagDeclaration
     extends HasValidator, HasValue, HasValueChangeListener, HasTabIndex, IsFocus, IsVisual,
     HasValidatorMessage, HasConverterMessage, HasRequiredMessage, IsDisabled, IsReadonly, HasId, HasTip, HasHelp,
     IsInline, HasRenderRange, IsRendered, HasBinding, HasConverter, HasLabel, HasLabelLayout, HasAutoSpacing,
-    HasGroup {
+    HasGroup, HasDecorationPosition {
 
   /**
    * Flag indicating that selecting an Item representing a Value is Required.
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/StarsTagDeclaration.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/StarsTagDeclaration.java
index aff193ff8d..445e184fb3 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/StarsTagDeclaration.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/StarsTagDeclaration.java
@@ -28,12 +28,14 @@ import org.apache.myfaces.tobago.apt.annotation.UIComponentTagAttribute;
 import org.apache.myfaces.tobago.component.ClientBehaviors;
 import org.apache.myfaces.tobago.component.RendererTypes;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasAccessKey;
+import org.apache.myfaces.tobago.internal.taglib.declaration.HasAutoSpacing;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasConverter;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasConverterMessage;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasHelp;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasIdBindingAndRendered;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasLabel;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasLabelLayout;
+import org.apache.myfaces.tobago.internal.taglib.declaration.HasDecorationPosition;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasRequiredMessage;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasTabIndex;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasTip;
@@ -41,7 +43,6 @@ import org.apache.myfaces.tobago.internal.taglib.declaration.HasValidator;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasValidatorMessage;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasValue;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasValueChangeListener;
-import org.apache.myfaces.tobago.internal.taglib.declaration.HasAutoSpacing;
 import org.apache.myfaces.tobago.internal.taglib.declaration.IsDisabled;
 import org.apache.myfaces.tobago.internal.taglib.declaration.IsFocus;
 import org.apache.myfaces.tobago.internal.taglib.declaration.IsReadonly;
@@ -76,7 +77,7 @@ import jakarta.faces.component.UIInput;
 public interface StarsTagDeclaration extends HasIdBindingAndRendered, HasConverter, HasConverterMessage, IsDisabled,
     IsFocus, HasTabIndex, HasLabel, HasLabelLayout, IsReadonly, IsRequired, HasRequiredMessage, HasTip,
     HasValidator, HasValidatorMessage, HasValue, HasValueChangeListener, IsVisual, HasAccessKey, HasHelp,
-    HasAutoSpacing {
+    HasAutoSpacing, HasDecorationPosition {
 
   /**
    * The current value of this component. May be a java.lang.Number or a javax.swing.BoundedRangeModel
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/TextareaTagDeclaration.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/TextareaTagDeclaration.java
index ec8cb3ef4f..633824dd22 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/TextareaTagDeclaration.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/TextareaTagDeclaration.java
@@ -35,6 +35,7 @@ import org.apache.myfaces.tobago.internal.taglib.declaration.HasHelp;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasIdBindingAndRendered;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasLabel;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasLabelLayout;
+import org.apache.myfaces.tobago.internal.taglib.declaration.HasDecorationPosition;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasPlaceholder;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasRequiredMessage;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasSanitize;
@@ -94,7 +95,7 @@ public interface TextareaTagDeclaration
     extends HasIdBindingAndRendered, HasConverter, IsReadonly, IsDisabled, IsRequired, HasLabel, HasLabelLayout, HasTip,
     HasHelp, HasAccessKey, HasValidator, HasValue, HasValueChangeListener, HasTabIndex, IsFocus, IsVisual,
     HasValidatorMessage, HasConverterMessage, HasRequiredMessage, HasSanitize, HasPlaceholder, HasAutoSpacing,
-    HasAutocomplete {
+    HasAutocomplete, HasDecorationPosition {
 
   /**
    * The row count for this component.
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/declaration/HasDecorationPosition.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/declaration/HasDecorationPosition.java
new file mode 100644
index 0000000000..de0353d4ea
--- /dev/null
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/declaration/HasDecorationPosition.java
@@ -0,0 +1,47 @@
+/*
+ * 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.internal.taglib.declaration;
+
+import org.apache.myfaces.tobago.apt.annotation.TagAttribute;
+import org.apache.myfaces.tobago.apt.annotation.UIComponentTagAttribute;
+
+public interface HasDecorationPosition {
+
+  /**
+   * Defines the position and the appearance of additional faces messages (like error message or help message) on a
+   * component.
+   * The default is popoverRight.
+   */
+  @TagAttribute
+  @UIComponentTagAttribute(type = "org.apache.myfaces.tobago.component.DecorationPosition",
+      defaultCode = "DecorationPosition.valueOf(org.apache.myfaces.tobago.context.TobagoContext"
+          + ".getInstance(getFacesContext()).getTheme().getTagAttributeDefault(TAG, \"messagePosition\"))")
+  void setMessagePosition(String messagePosition);
+
+  /**
+   * Defines the position and the appearance of a help message on a component.
+   * The default is popoverRight.
+   */
+  @TagAttribute
+  @UIComponentTagAttribute(type = "org.apache.myfaces.tobago.component.DecorationPosition",
+      defaultCode = "DecorationPosition.valueOf(org.apache.myfaces.tobago.context.TobagoContext"
+          + ".getInstance(getFacesContext()).getTheme().getTagAttributeDefault(TAG, \"helpPosition\"))")
+  void setHelpPosition(String helpPosition);
+}
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/css/BootstrapClass.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/css/BootstrapClass.java
index 903585b334..d7f72fd1f8 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/css/BootstrapClass.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/css/BootstrapClass.java
@@ -312,6 +312,8 @@ public enum BootstrapClass implements CssItem {
   DROPDOWN_MENU("dropdown-menu"),
   DROPDOWN_MENU_END("dropdown-menu-end"),
   DROPDOWN_TOGGLE("dropdown-toggle"),
+  ERROR_FEEDBACK("error-feedback"),
+  ERROR_TOOLTIP("error-tooltip"),
   FADE("fade"),
   FIGURE("figure"),
   FIGURE_CAPTION("figure-caption"),
@@ -393,6 +395,10 @@ public enum BootstrapClass implements CssItem {
   FW_NORMAL("fw-normal"),
   FW_LIGHT("fw-light"),
   FW_LIGHTER("fw-lighter"),
+  HELP_FEEDBACK("help-feedback"),
+  HELP_TOOLTIP("help-tooltip"),
+  INFO_FEEDBACK("info-feedback"),
+  INFO_TOOLTIP("info-tooltip"),
   INPUT_GROUP("input-group"),
   /**
    * @deprecated since 5.0.0
@@ -624,7 +630,9 @@ public enum BootstrapClass implements CssItem {
   TABLE_SM("table-sm"),
   TABLE_STRIPED("table-striped"),
   TOOLTIP_ARROW("tooltip-arrow"),
-  VISUALLY_HIDDEN("visually-hidden");
+  VISUALLY_HIDDEN("visually-hidden"),
+  WARNING_FEEDBACK("warning-feedback"),
+  WARNING_TOOLTIP("warning-tooltip");
 
   private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
@@ -683,6 +691,20 @@ public enum BootstrapClass implements CssItem {
     return getSeverityCssItem(severity, BTN_INFO, BTN_WARNING, BTN_DANGER);
   }
 
+  public static CssItem feedbackColor(final FacesMessage.Severity severity) {
+    if (severity == null) {
+      return null;
+    }
+    return getSeverityCssItem(severity, INFO_FEEDBACK, WARNING_FEEDBACK, ERROR_FEEDBACK);
+  }
+
+  public static CssItem tooltipColor(final FacesMessage.Severity severity) {
+    if (severity == null) {
+      return null;
+    }
+    return getSeverityCssItem(severity, INFO_TOOLTIP, WARNING_TOOLTIP, ERROR_TOOLTIP);
+  }
+
   private static CssItem getSeverityCssItem(
       FacesMessage.Severity severity,
       BootstrapClass info, BootstrapClass warning, BootstrapClass error) {
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/css/TobagoClass.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/css/TobagoClass.java
index 30bff979e3..4e6efa107e 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/css/TobagoClass.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/css/TobagoClass.java
@@ -19,6 +19,12 @@
 
 package org.apache.myfaces.tobago.renderkit.css;
 
+import org.apache.myfaces.tobago.component.DecorationPosition;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.lang.invoke.MethodHandles;
+
 /**
  * Declaration of the Tobago CSS classes.
  *
@@ -53,6 +59,7 @@ public enum TobagoClass implements CssItem {
   FOLDER("tobago-folder"),
   FILTER("tobago-filter"),
   HEADER("tobago-header"),
+  HELP__CONTAINER("tobago-help-container"),
   LABEL("tobago-label"),
   LABEL__CONTAINER("tobago-label-container"),
   LEVEL("tobago-level"),
@@ -61,6 +68,7 @@ public enum TobagoClass implements CssItem {
   MESSAGES__CONTAINER("tobago-messages-container"),
   NOW("tobago-now"),
   NUMBER("tobago-number"),
+  NONE("tobago-none"),
   OBJECT("tobago-object"),
   OPTIONS("tobago-options"),
   OUT("tobago-out"),
@@ -70,6 +78,8 @@ public enum TobagoClass implements CssItem {
   PAGING("tobago-paging"),
   PANEL("tobago-panel"),
   POPOVER__BOX("tobago-popover-box"),
+  BUTTON__LEFT("tobago-button-left"),
+  BUTTON__RIGHT("tobago-button-right"),
   RANGE("tobago-range"),
   REQUIRED("tobago-required"),
   RESIZE("tobago-resize"),
@@ -88,11 +98,15 @@ public enum TobagoClass implements CssItem {
   STARS__TOOLTIP("tobago-stars-tooltip"),
   STARS__UNSELECTED("tobago-stars-unselected"),
   TABLE_LAYOUT__FIXED("tobago-tableLayout-fixed"),
+  TEXT__BOTTOM("tobago-text-bottom"),
   TEXT__JUSTIFY("tobago-text-justify"),
+  TEXT__TOP("tobago-text-top"),
   TOGGLE("tobago-toggle"),
   TOOLTIP("tobago-tooltip"),
   UNSELECTED("tobago-unselected");
 
+  private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+
   private final String name;
 
   TobagoClass(final String name) {
@@ -103,4 +117,28 @@ public enum TobagoClass implements CssItem {
   public String getName() {
     return name;
   }
+
+  public static CssItem valueOf(final DecorationPosition decorationPosition) {
+    if (decorationPosition == null) {
+      return null;
+    } else {
+      switch (decorationPosition) {
+        case none:
+          return NONE;
+        case buttonLeft:
+          return BUTTON__LEFT;
+        case buttonRight:
+          return BUTTON__RIGHT;
+        case tooltip:
+          return TOOLTIP;
+        case textTop:
+          return TEXT__TOP;
+        case textBottom:
+          return TEXT__BOTTOM;
+        default:
+          LOG.warn("Undefined decoration position: '{}'.", decorationPosition);
+          return null;
+      }
+    }
+  }
 }
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/html/DataAttributes.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/html/DataAttributes.java
index 97dd1807c1..ee53200501 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/html/DataAttributes.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/html/DataAttributes.java
@@ -67,6 +67,10 @@ public enum DataAttributes implements MarkupLanguageAttributes {
 
   DELAY("data-tobago-delay"),
 
+  /**
+   * Faces message for further use with custom JavaScript.
+   */
+  FACES_MESSAGE("data-tobago-faces-message"),
   FOR("data-tobago-for"),
 
   /**
@@ -79,6 +83,11 @@ public enum DataAttributes implements MarkupLanguageAttributes {
    */
   FIRST_DAY_OF_WEEK("data-tobago-first-day-of-week"),
 
+  /**
+   * Help message for further use with custom JavaScript.
+   */
+  HELP("data-tobago-help"),
+
   /**
    * Defines e.g. the index of a tab inside a tab group.
    */
diff --git a/tobago-core/src/test/resources/renderer/date/error-message.html b/tobago-core/src/test/resources/renderer/date/error-message.html
index 160c282281..a66c1fb999 100644
--- a/tobago-core/src/test/resources/renderer/date/error-message.html
+++ b/tobago-core/src/test/resources/renderer/date/error-message.html
@@ -16,7 +16,7 @@
 -->
 
 <tobago-date id='id' class='tobago-auto-spacing'>
-  <div class='tobago-messages-container'>
+  <div class='tobago-messages-container tobago-button-right' data-tobago-faces-message='a test'>
     <div class='input-group'>
       <input type='date' name='id' id='id::field' title='a test' class='is-error form-control' autofocus='autofocus'>
     </div>
diff --git a/tobago-core/src/test/resources/renderer/date/help.html b/tobago-core/src/test/resources/renderer/date/help.html
index 5d8f4aed8e..d94906c635 100644
--- a/tobago-core/src/test/resources/renderer/date/help.html
+++ b/tobago-core/src/test/resources/renderer/date/help.html
@@ -16,7 +16,7 @@
 -->
 
 <tobago-date id='id' class='tobago-auto-spacing'>
-  <div class='tobago-messages-container'>
+  <div class='tobago-help-container tobago-button-right' data-tobago-help='Help!'>
     <div class='input-group'>
       <input type='date' name='id' id='id::field' value='1957-10-05' class='form-control'>
     </div>
@@ -24,4 +24,4 @@
       <a tabindex='0' role='button' class='btn btn-outline-info'><i class='bi-question-lg'></i></a>
     </tobago-popover>
   </div>
-</tobago-date>
\ No newline at end of file
+</tobago-date>
diff --git a/tobago-core/src/test/resources/renderer/in/error-message.html b/tobago-core/src/test/resources/renderer/in/error-message.html
index 132f9be199..d5be97cb78 100644
--- a/tobago-core/src/test/resources/renderer/in/error-message.html
+++ b/tobago-core/src/test/resources/renderer/in/error-message.html
@@ -17,7 +17,7 @@
 
 <tobago-in id='id' class='tobago-label-container tobago-auto-spacing'>
   <label for='id::field' class='col-form-label'>label</label>
-  <div class='tobago-messages-container'>
+  <div class='tobago-messages-container tobago-button-right' data-tobago-faces-message='a test'>
     <input type='text' name='id' id='id::field' title='a test' class='is-error form-control' autofocus='autofocus'>
     <tobago-popover data-bs-toggle='popover' title='Error' data-bs-content='a test' data-bs-trigger='focus'>
       <a tabindex='0' role='button' class='btn btn-danger'><i class='bi-exclamation-lg'></i></a>
diff --git a/tobago-core/src/test/resources/renderer/in/help.html b/tobago-core/src/test/resources/renderer/in/help.html
index a99cc8192e..919eb90301 100644
--- a/tobago-core/src/test/resources/renderer/in/help.html
+++ b/tobago-core/src/test/resources/renderer/in/help.html
@@ -17,10 +17,10 @@
 
 <tobago-in id='id' class='tobago-label-container tobago-auto-spacing'>
   <label for='id::field' class='col-form-label'>label</label>
-  <div class='tobago-messages-container'>
+  <div class='tobago-help-container tobago-button-right' data-tobago-help='Help!'>
     <input type='text' name='id' id='id::field' class='form-control'>
     <tobago-popover data-bs-toggle='popover' title='Help' data-bs-content='Help!' data-bs-trigger='focus'>
       <a tabindex='0' role='button' class='btn btn-outline-info'><i class='bi-question-lg'></i></a>
     </tobago-popover>
   </div>
-</tobago-in>
\ No newline at end of file
+</tobago-in>
diff --git a/tobago-core/src/test/resources/renderer/selectBooleanCheckbox/selectBooleanCheckboxError.html b/tobago-core/src/test/resources/renderer/selectBooleanCheckbox/selectBooleanCheckboxError.html
index 23684c6ff8..441867ce85 100644
--- a/tobago-core/src/test/resources/renderer/selectBooleanCheckbox/selectBooleanCheckboxError.html
+++ b/tobago-core/src/test/resources/renderer/selectBooleanCheckbox/selectBooleanCheckboxError.html
@@ -16,7 +16,7 @@
 -->
 
 <tobago-select-boolean-checkbox id='id' class='tobago-auto-spacing'>
-  <div class='tobago-messages-container'>
+  <div class='tobago-messages-container tobago-button-right' data-tobago-faces-message='This is a custom error'>
     <div class='form-check col-form-label' title='This is a custom error'>
       <input class='form-check-input is-error' type='checkbox' value='true' name='id' id='id::field' autofocus='autofocus'>
       <label class='form-check-label' for='id::field'></label>
diff --git a/tobago-core/src/test/resources/renderer/selectBooleanCheckbox/selectBooleanCheckboxFatal.html b/tobago-core/src/test/resources/renderer/selectBooleanCheckbox/selectBooleanCheckboxFatal.html
index 18fa4c6bfc..85646283e3 100644
--- a/tobago-core/src/test/resources/renderer/selectBooleanCheckbox/selectBooleanCheckboxFatal.html
+++ b/tobago-core/src/test/resources/renderer/selectBooleanCheckbox/selectBooleanCheckboxFatal.html
@@ -16,7 +16,7 @@
 -->
 
 <tobago-select-boolean-checkbox id='id' class='tobago-auto-spacing'>
-  <div class='tobago-messages-container'>
+  <div class='tobago-messages-container tobago-button-right' data-tobago-faces-message='This is a custom fatal error'>
     <div class='form-check col-form-label' title='This is a custom fatal error'>
       <input class='form-check-input is-error' type='checkbox' value='true' name='id' id='id::field' autofocus='autofocus'>
       <label class='form-check-label' for='id::field'></label>
diff --git a/tobago-core/src/test/resources/renderer/selectBooleanCheckbox/selectBooleanCheckboxInfo.html b/tobago-core/src/test/resources/renderer/selectBooleanCheckbox/selectBooleanCheckboxInfo.html
index 8f14af4d7c..788f10c314 100644
--- a/tobago-core/src/test/resources/renderer/selectBooleanCheckbox/selectBooleanCheckboxInfo.html
+++ b/tobago-core/src/test/resources/renderer/selectBooleanCheckbox/selectBooleanCheckboxInfo.html
@@ -16,7 +16,7 @@
 -->
 
 <tobago-select-boolean-checkbox id='id' class='tobago-auto-spacing'>
-  <div class='tobago-messages-container'>
+  <div class='tobago-messages-container tobago-button-right' data-tobago-faces-message='This is a custom information'>
     <div class='form-check col-form-label' title='This is a custom information'>
       <input class='form-check-input is-info' type='checkbox' value='true' name='id' id='id::field' autofocus='autofocus'>
       <label class='form-check-label' for='id::field'></label>
diff --git a/tobago-core/src/test/resources/renderer/selectBooleanCheckbox/selectBooleanCheckboxWarning.html b/tobago-core/src/test/resources/renderer/selectBooleanCheckbox/selectBooleanCheckboxWarning.html
index 8bf12390c3..b1eae4fa7a 100644
--- a/tobago-core/src/test/resources/renderer/selectBooleanCheckbox/selectBooleanCheckboxWarning.html
+++ b/tobago-core/src/test/resources/renderer/selectBooleanCheckbox/selectBooleanCheckboxWarning.html
@@ -16,7 +16,7 @@
 -->
 
 <tobago-select-boolean-checkbox id='id' class='tobago-auto-spacing'>
-  <div class='tobago-messages-container'>
+  <div class='tobago-messages-container tobago-button-right' data-tobago-faces-message='This is a custom warning'>
     <div class='form-check col-form-label' title='This is a custom warning'>
       <input class='form-check-input is-warning' type='checkbox' value='true' name='id' id='id::field' autofocus='autofocus'>
       <label class='form-check-label' for='id::field'></label>
diff --git a/tobago-core/src/test/resources/renderer/selectManyCheckbox/selectManyCheckboxFatal.html b/tobago-core/src/test/resources/renderer/selectManyCheckbox/selectManyCheckboxFatal.html
index 80620beab9..f44dac8a44 100644
--- a/tobago-core/src/test/resources/renderer/selectManyCheckbox/selectManyCheckboxFatal.html
+++ b/tobago-core/src/test/resources/renderer/selectManyCheckbox/selectManyCheckboxFatal.html
@@ -16,7 +16,7 @@
 -->
 
 <tobago-select-many-checkbox id='id' class='tobago-auto-spacing'>
-  <div class='tobago-messages-container'>
+  <div class='tobago-messages-container tobago-button-right' data-tobago-faces-message='This is a custom fatal error'>
     <div title='This is a custom fatal error'>
       <div class='form-check'>
         <input class='form-check-input is-error' type='checkbox' name='id' id='id::0' value='' autofocus='autofocus'>
diff --git a/tobago-core/src/test/resources/renderer/selectManyShuttle/error-message.html b/tobago-core/src/test/resources/renderer/selectManyShuttle/error-message.html
index 3ad5a23987..bdf7cef9bb 100644
--- a/tobago-core/src/test/resources/renderer/selectManyShuttle/error-message.html
+++ b/tobago-core/src/test/resources/renderer/selectManyShuttle/error-message.html
@@ -16,7 +16,7 @@
 -->
 
 <tobago-select-many-shuttle id='id' class='tobago-auto-spacing'>
-  <div class='tobago-messages-container'>
+  <div class='tobago-messages-container tobago-button-right' data-tobago-faces-message='a test'>
     <div class='tobago-body' title='a test'>
       <select id='id::unselected' class='tobago-unselected form-control' multiple='multiple' size='2'>
         <option value=''>Value 1
diff --git a/tobago-core/src/test/resources/renderer/selectManyShuttle/help.html b/tobago-core/src/test/resources/renderer/selectManyShuttle/help.html
index b87cee67fa..97739d3f61 100644
--- a/tobago-core/src/test/resources/renderer/selectManyShuttle/help.html
+++ b/tobago-core/src/test/resources/renderer/selectManyShuttle/help.html
@@ -16,7 +16,7 @@
 -->
 
 <tobago-select-many-shuttle id='id' class='tobago-auto-spacing'>
-  <div class='tobago-messages-container'>
+  <div class='tobago-help-container tobago-button-right' data-tobago-help='Help!'>
     <div class='tobago-body'>
       <select id='id::unselected' class='tobago-unselected form-control' multiple='multiple' size='2'>
         <option value=''>Value 1
@@ -42,4 +42,4 @@
       <a tabindex='0' role='button' class='btn btn-outline-info'><i class='bi-question-lg'></i></a>
     </tobago-popover>
   </div>
-</tobago-select-many-shuttle>
\ No newline at end of file
+</tobago-select-many-shuttle>
diff --git a/tobago-core/src/test/resources/tobago-config-for-unit-tests.xml b/tobago-core/src/test/resources/tobago-config-for-unit-tests.xml
index 6fec7d5f74..047f70b834 100644
--- a/tobago-core/src/test/resources/tobago-config-for-unit-tests.xml
+++ b/tobago-core/src/test/resources/tobago-config-for-unit-tests.xml
@@ -31,48 +31,83 @@
       <tags>
         <tag name="date">
           <attribute name="labelLayout" default="flexLeft"/>
+          <attribute name="messagePosition" default="buttonRight"/>
+          <attribute name="helpPosition" default="buttonRight"/>
         </tag>
         <tag name="file">
           <attribute name="labelLayout" default="flexLeft"/>
+          <attribute name="messagePosition" default="buttonRight"/>
+          <attribute name="helpPosition" default="buttonRight"/>
         </tag>
         <tag name="in">
           <attribute name="labelLayout" default="flexLeft"/>
+          <attribute name="messagePosition" default="buttonRight"/>
+          <attribute name="helpPosition" default="buttonRight"/>
         </tag>
         <tag name="out">
           <attribute name="labelLayout" default="flexLeft"/>
+          <attribute name="messagePosition" default="buttonRight"/>
+          <attribute name="helpPosition" default="buttonRight"/>
         </tag>
         <tag name="range">
           <attribute name="labelLayout" default="flexLeft"/>
+          <attribute name="messagePosition" default="buttonRight"/>
+          <attribute name="helpPosition" default="buttonRight"/>
         </tag>
         <tag name="selectBooleanCheckbox">
           <attribute name="labelLayout" default="flexLeft"/>
+          <attribute name="messagePosition" default="buttonRight"/>
+          <attribute name="helpPosition" default="buttonRight"/>
         </tag>
         <tag name="selectBooleanToggle">
           <attribute name="labelLayout" default="flexLeft"/>
+          <attribute name="messagePosition" default="buttonRight"/>
+          <attribute name="helpPosition" default="buttonRight"/>
         </tag>
         <tag name="selectManyCheckbox">
           <attribute name="labelLayout" default="flexLeft"/>
+          <attribute name="messagePosition" default="buttonRight"/>
+          <attribute name="helpPosition" default="buttonRight"/>
+        </tag>
+        <tag name="selectManyList">
+          <attribute name="labelLayout" default="flexLeft"/>
+          <attribute name="messagePosition" default="buttonRight"/>
+          <attribute name="helpPosition" default="buttonRight"/>
         </tag>
         <tag name="selectManyListbox">
           <attribute name="labelLayout" default="flexLeft"/>
+          <attribute name="messagePosition" default="buttonRight"/>
+          <attribute name="helpPosition" default="buttonRight"/>
         </tag>
         <tag name="selectManyShuttle">
           <attribute name="labelLayout" default="flexLeft"/>
+          <attribute name="messagePosition" default="buttonRight"/>
+          <attribute name="helpPosition" default="buttonRight"/>
         </tag>
         <tag name="selectOneChoice">
           <attribute name="labelLayout" default="flexLeft"/>
+          <attribute name="messagePosition" default="buttonRight"/>
+          <attribute name="helpPosition" default="buttonRight"/>
         </tag>
         <tag name="selectOneListbox">
           <attribute name="labelLayout" default="flexLeft"/>
+          <attribute name="messagePosition" default="buttonRight"/>
+          <attribute name="helpPosition" default="buttonRight"/>
         </tag>
         <tag name="selectOneRadio">
           <attribute name="labelLayout" default="flexLeft"/>
+          <attribute name="messagePosition" default="buttonRight"/>
+          <attribute name="helpPosition" default="buttonRight"/>
         </tag>
         <tag name="stars">
           <attribute name="labelLayout" default="flexLeft"/>
+          <attribute name="messagePosition" default="buttonRight"/>
+          <attribute name="helpPosition" default="buttonRight"/>
         </tag>
         <tag name="textarea">
           <attribute name="labelLayout" default="flexLeft"/>
+          <attribute name="messagePosition" default="buttonRight"/>
+          <attribute name="helpPosition" default="buttonRight"/>
         </tag>
       </tags>
 
diff --git a/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/DecorationPositionController.java b/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/DecorationPositionController.java
new file mode 100644
index 0000000000..e53afe8d9c
--- /dev/null
+++ b/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/DecorationPositionController.java
@@ -0,0 +1,54 @@
+/*
+ * 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.example.demo;
+
+import jakarta.enterprise.context.SessionScoped;
+import jakarta.inject.Named;
+import org.apache.myfaces.tobago.component.DecorationPosition;
+
+import java.io.Serializable;
+
+@Named
+@SessionScoped
+public class DecorationPositionController implements Serializable {
+
+  private DecorationPosition messagePosition = DecorationPosition.buttonRight;
+  private DecorationPosition helpPosition = DecorationPosition.buttonRight;
+
+  public DecorationPosition getMessagePosition() {
+    return messagePosition;
+  }
+
+  public void setMessagePosition(DecorationPosition messagePosition) {
+    this.messagePosition = messagePosition;
+  }
+
+  public DecorationPosition getHelpPosition() {
+    return helpPosition;
+  }
+
+  public void setHelpPosition(DecorationPosition helpPosition) {
+    this.helpPosition = helpPosition;
+  }
+
+  public DecorationPosition[] getDecorationPositions() {
+    return DecorationPosition.values();
+  }
+}
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/900-test/4900-messageLayout/100-position/decorationPosition.xhtml b/tobago-example/tobago-example-demo/src/main/webapp/content/900-test/4900-messageLayout/100-position/decorationPosition.xhtml
new file mode 100644
index 0000000000..083bbc744c
--- /dev/null
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/900-test/4900-messageLayout/100-position/decorationPosition.xhtml
@@ -0,0 +1,117 @@
+<?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.
+-->
+
+<ui:composition template="/main.xhtml"
+                xmlns="http://www.w3.org/1999/xhtml"
+                xmlns:f="http://xmlns.jcp.org/jsf/core"
+                xmlns:tc="http://myfaces.apache.org/tobago/component"
+                xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
+  <ui:param name="title" value="messages"/>
+
+  <tc:section label="Change Layout">
+    <tc:form id="changeLayout">
+      <tc:segmentLayout small="6seg">
+        <tc:selectOneRadio label="MessagePosition" labelLayout="top"
+                           value="#{decorationPositionController.messagePosition}">
+          <f:selectItems value="#{decorationPositionController.decorationPositions}"/>
+        </tc:selectOneRadio>
+        <tc:selectOneRadio label="HelpPosition" labelLayout="top" value="#{decorationPositionController.helpPosition}">
+          <f:selectItems value="#{decorationPositionController.decorationPositions}"/>
+        </tc:selectOneRadio>
+      </tc:segmentLayout>
+      <tc:button label="Change"/>
+    </tc:form>
+  </tc:section>
+
+  <tc:section label="Test Layout">
+    <tc:button id="submit" label="Submit"/>
+    <tc:segmentLayout medium="4seg">
+      <tc:in id="fatalIn" help="help message" validator="#{severityController.addError}"
+             messagePosition="#{decorationPositionController.messagePosition}"
+             helpPosition="#{decorationPositionController.helpPosition}"/>
+      <tc:date id="fatalDate" help="help message" validator="#{severityController.addError}"
+               messagePosition="#{decorationPositionController.messagePosition}"
+               helpPosition="#{decorationPositionController.helpPosition}"/>
+      <tc:textarea id="fatalTextarea" help="help message" validator="#{severityController.addError}"
+                   messagePosition="#{decorationPositionController.messagePosition}"
+                   helpPosition="#{decorationPositionController.helpPosition}"/>
+    </tc:segmentLayout>
+    <tc:segmentLayout medium="3seg">
+      <tc:selectBooleanCheckbox id="fatalCheckbox" help="help message" validator="#{severityController.addError}"
+                                messagePosition="#{decorationPositionController.messagePosition}"
+                                helpPosition="#{decorationPositionController.helpPosition}"/>
+      <tc:selectBooleanToggle id="fatalToggle" help="help message" validator="#{severityController.addError}"
+                              messagePosition="#{decorationPositionController.messagePosition}"
+                              helpPosition="#{decorationPositionController.helpPosition}"/>
+      <tc:selectManyCheckbox id="fatalCheckboxes" help="help message" validator="#{severityController.addError}"
+                             messagePosition="#{decorationPositionController.messagePosition}"
+                             helpPosition="#{decorationPositionController.helpPosition}">
+        <tc:selectItem itemValue="Entry One"/>
+        <tc:selectItem itemValue="Entry Two"/>
+      </tc:selectManyCheckbox>
+      <tc:selectOneRadio id="fatalRadio" value="Entry One" help="help message"
+                         validator="#{severityController.addError}"
+                         messagePosition="#{decorationPositionController.messagePosition}"
+                         helpPosition="#{decorationPositionController.helpPosition}">
+        <tc:selectItem itemValue="Entry One"/>
+        <tc:selectItem itemValue="Entry Two"/>
+      </tc:selectOneRadio>
+    </tc:segmentLayout>
+    <tc:segmentLayout medium="4seg">
+      <tc:selectOneChoice id="fatalDropdown" help="help message" validator="#{severityController.addError}"
+                          messagePosition="#{decorationPositionController.messagePosition}"
+                          helpPosition="#{decorationPositionController.helpPosition}">
+        <tc:selectItem itemValue="Entry One"/>
+        <tc:selectItem itemValue="Entry Two"/>
+      </tc:selectOneChoice>
+      <tc:selectOneListbox id="fatalOneListbox" value="Entry One" help="help message"
+                           validator="#{severityController.addError}"
+                           messagePosition="#{decorationPositionController.messagePosition}"
+                           helpPosition="#{decorationPositionController.helpPosition}">
+        <tc:selectItem itemValue="Entry One"/>
+        <tc:selectItem itemValue="Entry Two"/>
+      </tc:selectOneListbox>
+      <tc:selectManyListbox id="fatalManyListbox" help="help message" validator="#{severityController.addError}"
+                            messagePosition="#{decorationPositionController.messagePosition}"
+                            helpPosition="#{decorationPositionController.helpPosition}">
+        <tc:selectItem itemValue="Entry One"/>
+        <tc:selectItem itemValue="Entry Two"/>
+      </tc:selectManyListbox>
+    </tc:segmentLayout>
+    <tc:segmentLayout medium="6seg">
+      <tc:file id="fatalFile" required="true" help="help message" validator="#{severityController.addError}"
+               messagePosition="#{decorationPositionController.messagePosition}"
+               helpPosition="#{decorationPositionController.helpPosition}"/>
+      <tc:selectManyShuttle id="fatalShuttle" help="help message" validator="#{severityController.addError}"
+                            messagePosition="#{decorationPositionController.messagePosition}"
+                            helpPosition="#{decorationPositionController.helpPosition}">
+        <tc:selectItem itemValue="Entry One"/>
+        <tc:selectItem itemValue="Entry Two"/>
+      </tc:selectManyShuttle>
+    </tc:segmentLayout>
+    <tc:segmentLayout medium="6seg">
+      <tc:range id="fatalRange" help="help message" validator="#{severityController.addError}"
+                messagePosition="#{decorationPositionController.messagePosition}"
+                helpPosition="#{decorationPositionController.helpPosition}"/>
+      <tc:stars id="fatalStars" help="help message" validator="#{severityController.addError}"
+                messagePosition="#{decorationPositionController.messagePosition}"
+                helpPosition="#{decorationPositionController.helpPosition}"/>
+    </tc:segmentLayout>
+  </tc:section>
+</ui:composition>
diff --git a/tobago-theme/src/main/scss/_tobago.scss b/tobago-theme/src/main/scss/_tobago.scss
index 95dda23f87..f70111ca33 100644
--- a/tobago-theme/src/main/scss/_tobago.scss
+++ b/tobago-theme/src/main/scss/_tobago.scss
@@ -151,6 +151,44 @@ $form-select-disabled-color: rgba($form-select-color, $tobago-form-disabled-alph
   }
 }
 
+@mixin messagesHelpContainer($tobago-form-validation-states) {
+  @each $state, $data in $tobago-form-validation-states {
+    @include form-validation-state($state, $data...);
+  }
+
+  width: 100%;
+
+  &.tobago-button-left, &.tobago-button-right {
+    @include messageLayoutPopover();
+    display: flex;
+    align-items: flex-start;
+  }
+
+  &.tobago-tooltip {
+    position: relative;
+  }
+
+  .tobago-none {
+    //this is for TobagoClassUnitTest
+  }
+}
+
+@mixin messageLayoutPopover() {
+  &.tobago-button-left {
+    > tobago-popover {
+      margin-right: 0.75rem;
+    }
+  }
+  &.tobago-button-right {
+    > tobago-popover {
+      margin-left: 0.75rem;
+    }
+  }
+  tobago-popover > a {
+    --bs-btn-padding-x: .4rem;
+  }
+}
+
 @mixin radioCheckboxInline() {
   label + .form-check-inline {
     display: block; // must be 'block' to make labelLayout=top work for inline=true
@@ -423,8 +461,6 @@ tobago-flex-layout {
   }
 }
 
-/* flowLayout ---------------------------------------------------------- */
-
 tobago-flow-layout {
   &.tobago-text-justify {
     /* added here, because Bootstrap has removed .text-justify */
@@ -439,8 +475,6 @@ tobago-focus {
   display: none;
 }
 
-/* footer -------------------------------------------------------------- */
-
 tobago-footer {
   display: block;
   background-color: $white;
@@ -485,6 +519,36 @@ tobago-header {
   }
 }
 
+.tobago-help-container {
+  @function exclamation-circle-icon($color) {
+    @return url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='#{$color}'><circle cx='6' cy='6' r='4.5'/><path stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/><circle cx='6' cy='8.2' r='.6' fill='#{$color}' stroke='none'/></svg>");
+  }
+  $tobago-form-validation-states: (
+      "help": (
+          "color": $info,
+          "icon": none
+      )
+  );
+
+  @include messagesHelpContainer($tobago-form-validation-states);
+
+  &.tobago-tooltip .help-tooltip {
+    display: block;
+  }
+
+  &.tobago-text-top, &.tobago-text-bottom {
+    .help-feedback {
+      display: block;
+    }
+  }
+
+  &.tobago-text-top {
+    .help-feedback {
+      margin-bottom: $form-feedback-margin-top;
+    }
+  }
+}
+
 /* image ----------------------------------------------------------- */
 
 tobago-image.disabled {
@@ -678,8 +742,6 @@ button {
   padding-right: 0;
 }
 
-/* messages / help text ----------------------------------------------- */
-$enable-validation-icons: false;
 .tobago-messages-container {
   @function exclamation-circle-icon($color) {
     @return url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='#{$color}'><circle cx='6' cy='6' r='4.5'/><path stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/><circle cx='6' cy='8.2' r='.6' fill='#{$color}' stroke='none'/></svg>");
@@ -699,24 +761,30 @@ $enable-validation-icons: false;
       )
   );
 
-  @each $state, $data in $tobago-form-validation-states {
-    @include form-validation-state($state, $data...);
-  }
+  @include messagesHelpContainer($tobago-form-validation-states);
 
-  display: flex;
-  align-items: flex-start;
+  &.tobago-button-left, &.tobago-button-right {
+    .form-control {
+      padding-right: $input-padding-x;
+      background-image: none;
+    }
+  }
 
-  .tobago-messages:first-child small label {
-    margin-right: 0; /* for tc:in margin 5px is already set */
-    margin-bottom: 5px;
+  &.tobago-tooltip {
+    .error-tooltip, .warning-tooltip, .info-tooltip {
+      display: block;
+    }
   }
 
-  tobago-popover {
-    margin-left: 0.75rem;
+  &.tobago-text-top, &.tobago-text-bottom {
+    .error-feedback, .warning-feedback, .info-feedback {
+      display: block;
+    }
+  }
 
-    .btn {
-      padding-left: 0.4rem;
-      padding-right: 0.4rem;
+  &.tobago-text-top {
+    .error-feedback, .warning-feedback, .info-feedback {
+      margin-bottom: $form-feedback-margin-top;
     }
   }
 }
@@ -773,6 +841,10 @@ tobago-messages {
       content: $icon-alert-info;
     }
   }
+
+  .tobago-messages {
+    //this is for TobagoClassUnitTest
+  }
 }
 
 .popover .popover-body {
@@ -1327,7 +1399,7 @@ tobago-select-many-shuttle {
     }
   }
 
-  &.tobago-label-container, .tobago-messages-container {
+  &.tobago-label-container, .tobago-help-container, .tobago-messages-container {
     > .tobago-body {
       flex: 1 0 0px;
     }
diff --git a/tobago-theme/tobago-theme-standard/src/main/resources/META-INF/tobago-config.xml b/tobago-theme/tobago-theme-standard/src/main/resources/META-INF/tobago-config.xml
index 6fb651c48f..1d41a5a942 100644
--- a/tobago-theme/tobago-theme-standard/src/main/resources/META-INF/tobago-config.xml
+++ b/tobago-theme/tobago-theme-standard/src/main/resources/META-INF/tobago-config.xml
@@ -55,51 +55,83 @@
       <tags>
         <tag name="date">
           <attribute name="labelLayout" default="flexLeft"/>
+          <attribute name="messagePosition" default="buttonRight"/>
+          <attribute name="helpPosition" default="buttonRight"/>
         </tag>
         <tag name="file">
           <attribute name="labelLayout" default="flexLeft"/>
+          <attribute name="messagePosition" default="buttonRight"/>
+          <attribute name="helpPosition" default="buttonRight"/>
         </tag>
         <tag name="in">
           <attribute name="labelLayout" default="flexLeft"/>
+          <attribute name="messagePosition" default="buttonRight"/>
+          <attribute name="helpPosition" default="buttonRight"/>
         </tag>
         <tag name="out">
           <attribute name="labelLayout" default="flexLeft"/>
+          <attribute name="messagePosition" default="buttonRight"/>
+          <attribute name="helpPosition" default="buttonRight"/>
         </tag>
         <tag name="range">
           <attribute name="labelLayout" default="flexLeft"/>
+          <attribute name="messagePosition" default="buttonRight"/>
+          <attribute name="helpPosition" default="buttonRight"/>
         </tag>
         <tag name="selectBooleanCheckbox">
           <attribute name="labelLayout" default="flexLeft"/>
+          <attribute name="messagePosition" default="buttonRight"/>
+          <attribute name="helpPosition" default="buttonRight"/>
         </tag>
         <tag name="selectBooleanToggle">
           <attribute name="labelLayout" default="flexLeft"/>
+          <attribute name="messagePosition" default="buttonRight"/>
+          <attribute name="helpPosition" default="buttonRight"/>
         </tag>
         <tag name="selectManyCheckbox">
           <attribute name="labelLayout" default="flexLeft"/>
+          <attribute name="messagePosition" default="buttonRight"/>
+          <attribute name="helpPosition" default="buttonRight"/>
         </tag>
         <tag name="selectManyList">
           <attribute name="labelLayout" default="flexLeft"/>
+          <attribute name="messagePosition" default="buttonRight"/>
+          <attribute name="helpPosition" default="buttonRight"/>
         </tag>
         <tag name="selectManyListbox">
           <attribute name="labelLayout" default="flexLeft"/>
+          <attribute name="messagePosition" default="buttonRight"/>
+          <attribute name="helpPosition" default="buttonRight"/>
         </tag>
         <tag name="selectManyShuttle">
           <attribute name="labelLayout" default="flexLeft"/>
+          <attribute name="messagePosition" default="buttonRight"/>
+          <attribute name="helpPosition" default="buttonRight"/>
         </tag>
         <tag name="selectOneChoice">
           <attribute name="labelLayout" default="flexLeft"/>
+          <attribute name="messagePosition" default="buttonRight"/>
+          <attribute name="helpPosition" default="buttonRight"/>
         </tag>
         <tag name="selectOneListbox">
           <attribute name="labelLayout" default="flexLeft"/>
+          <attribute name="messagePosition" default="buttonRight"/>
+          <attribute name="helpPosition" default="buttonRight"/>
         </tag>
         <tag name="selectOneRadio">
           <attribute name="labelLayout" default="flexLeft"/>
+          <attribute name="messagePosition" default="buttonRight"/>
+          <attribute name="helpPosition" default="buttonRight"/>
         </tag>
         <tag name="stars">
           <attribute name="labelLayout" default="flexLeft"/>
+          <attribute name="messagePosition" default="buttonRight"/>
+          <attribute name="helpPosition" default="buttonRight"/>
         </tag>
         <tag name="textarea">
           <attribute name="labelLayout" default="flexLeft"/>
+          <attribute name="messagePosition" default="buttonRight"/>
+          <attribute name="helpPosition" default="buttonRight"/>
         </tag>
       </tags>
     </theme-definition>
diff --git a/tobago-tool/tobago-tool-apt/src/main/resources/org/apache/myfaces/tobago/apt/component.stg b/tobago-tool/tobago-tool-apt/src/main/resources/org/apache/myfaces/tobago/apt/component.stg
index 306e856bf5..1b03633905 100644
--- a/tobago-tool/tobago-tool-apt/src/main/resources/org/apache/myfaces/tobago/apt/component.stg
+++ b/tobago-tool/tobago-tool-apt/src/main/resources/org/apache/myfaces/tobago/apt/component.stg
@@ -423,6 +423,10 @@ LabelLayoutProperty(property) ::= <<
 <NormalProperty(property)>
 >>
 
+DecorationPositionProperty(property) ::= <<
+<NormalProperty(property)>
+>>
+
 ClientBehaviorsProperty(property) ::= <<
 <NormalProperty(property)>
 >>