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 2022/05/13 09:30:06 UTC

[myfaces-tobago] branch master updated (51c324fd6e -> 0143179e85)

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

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


    from 51c324fd6e docs: small improvement of date demo
     new f8ec931076 fix(labelLayout): required component
     new 0143179e85 build(theme): rebuild after fixing label for required components

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:
 .../renderer/LabelLayoutRendererBase.java          |   4 +-
 .../renderkit/renderer/InRendererUnitTest.java     | 145 ++++++++++++++
 ...-flexLeft.html => required-label-flexLeft.html} |   8 +-
 ...flexLeft.html => required-label-flexRight.html} |   8 +-
 ...ridBottom.html => required-label-flowLeft.html} |   6 +-
 ...idBottom.html => required-label-flowRight.html} |   6 +-
 ...dBottom.html => required-label-gridBottom.html} |   6 +-
 ...ridBottom.html => required-label-gridLeft.html} |   6 +-
 ...idBottom.html => required-label-gridRight.html} |   6 +-
 ...gridBottom.html => required-label-gridTop.html} |   6 +-
 .../{label-none.html => required-label-none.html}  |   4 +-
 ...ntLeft.html => required-label-segmentLeft.html} |   6 +-
 ...tLeft.html => required-label-segmentRight.html} |  10 +-
 ...bel-gridBottom.html => required-label-top.html} |   6 +-
 .../350-label-required/Label_Required.xhtml        |  44 +++++
 .../src/main/webapp/css/jasmine.css                |   3 -
 .../tobago-example-demo/src/main/webapp/js/demo.js |  20 +-
 .../src/main/webapp/js/demo.js.map                 |   2 +-
 .../src/main/webapp/js/jasmine.js                  | 215 ++++++++++++++-------
 tobago-theme/src/main/scss/_tobago.scss            |   1 -
 .../src/main/css/tobago.css                        |   1 -
 .../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                        |   1 -
 .../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                        |   1 -
 .../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  |   1 -
 .../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  |   1 -
 .../src/main/css/tobago.css.map                    |   2 +-
 .../src/main/css/tobago.min.css                    |   2 +-
 .../src/main/css/tobago.min.css.map                |   2 +-
 40 files changed, 407 insertions(+), 140 deletions(-)
 copy tobago-core/src/test/resources/renderer/in/{label-flexLeft.html => required-label-flexLeft.html} (87%)
 copy tobago-core/src/test/resources/renderer/in/{label-flexLeft.html => required-label-flexRight.html} (87%)
 copy tobago-core/src/test/resources/renderer/in/{label-gridBottom.html => required-label-flowLeft.html} (82%)
 copy tobago-core/src/test/resources/renderer/in/{label-gridBottom.html => required-label-flowRight.html} (82%)
 copy tobago-core/src/test/resources/renderer/in/{label-gridBottom.html => required-label-gridBottom.html} (83%)
 copy tobago-core/src/test/resources/renderer/in/{label-gridBottom.html => required-label-gridLeft.html} (83%)
 copy tobago-core/src/test/resources/renderer/in/{label-gridBottom.html => required-label-gridRight.html} (83%)
 copy tobago-core/src/test/resources/renderer/in/{label-gridBottom.html => required-label-gridTop.html} (83%)
 copy tobago-core/src/test/resources/renderer/in/{label-none.html => required-label-none.html} (90%)
 copy tobago-core/src/test/resources/renderer/in/{label-segmentLeft.html => required-label-segmentLeft.html} (85%)
 copy tobago-core/src/test/resources/renderer/in/{label-segmentLeft.html => required-label-segmentRight.html} (85%)
 copy tobago-core/src/test/resources/renderer/in/{label-gridBottom.html => required-label-top.html} (84%)
 create mode 100644 tobago-example/tobago-example-demo/src/main/webapp/content/900-test/4800-labelLayout/350-label-required/Label_Required.xhtml


[myfaces-tobago] 02/02: build(theme): rebuild after fixing label for required components

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

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

commit 0143179e85937c745fe7a1aa15bbd2205cc8265a
Author: Henning Noeth <hn...@apache.org>
AuthorDate: Fri May 13 11:20:57 2022 +0200

    build(theme): rebuild after fixing label for required components
---
 .../src/main/webapp/css/jasmine.css                |   3 -
 .../tobago-example-demo/src/main/webapp/js/demo.js |  20 +-
 .../src/main/webapp/js/demo.js.map                 |   2 +-
 .../src/main/webapp/js/jasmine.js                  | 215 ++++++++++++++-------
 .../src/main/css/tobago.css                        |   1 -
 .../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                        |   1 -
 .../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                        |   1 -
 .../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  |   1 -
 .../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  |   1 -
 .../src/main/css/tobago.css.map                    |   2 +-
 .../src/main/css/tobago.min.css                    |   2 +-
 .../src/main/css/tobago.min.css.map                |   2 +-
 24 files changed, 176 insertions(+), 99 deletions(-)

diff --git a/tobago-example/tobago-example-demo/src/main/webapp/css/jasmine.css b/tobago-example/tobago-example-demo/src/main/webapp/css/jasmine.css
index 70ab359222..ed7899182e 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/css/jasmine.css
+++ b/tobago-example/tobago-example-demo/src/main/webapp/css/jasmine.css
@@ -40,9 +40,6 @@ body {
 .jasmine_html-reporter .jasmine-banner .jasmine-title {
   background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFoAAAAZCAMAAACGusnyAAACdlBMVEX/////AP+AgICqVaqAQICZM5mAVYCSSZKAQICOOY6ATYCLRouAQICJO4mSSYCIRIiPQICHPIeOR4CGQ4aMQICGPYaLRoCFQ4WKQICPPYWJRYCOQoSJQICNPoSIRICMQoSHQICHRICKQoOHQICKPoOJO4OJQYOMQICMQ4CIQYKLQICIPoKLQ4CKQICNPoKJQISMQ4KJQoSLQYKJQISLQ4KIQoSKQYKIQICIQISMQoSKQYKLQIOLQoOJQYGLQIOKQIOMQoGKQYOLQYGKQIOLQoGJQYOJQIOKQYGJQIOKQoGKQIGLQIKLQ4KKQoGLQYKJQIGKQYKJQIGKQIKJQoGKQYKLQIGKQYKLQIOJQoKKQoOJQYKKQIOJQoKKQoOKQIOLQoKKQYOLQYKJQIO [...]
   background: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhLS0gQ3JlYXRlZCB3aXRoIElua3NjYXBlIChodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy8pIC0tPgoKPHN2ZwogICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiCiAgIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyIKICAgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM9Imh0dHA6Ly93d3cudzM [...]
-  -moz-background-size: 100%;
-  -o-background-size: 100%;
-  -webkit-background-size: 100%;
   background-size: 100%;
   display: block;
   float: left;
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/js/demo.js b/tobago-example/tobago-example-demo/src/main/webapp/js/demo.js
index a671b452f9..bc8034fe70 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/js/demo.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/js/demo.js
@@ -1718,8 +1718,24 @@
 
     Prism.languages.insertBefore('javascript', 'keyword', {
     	'regex': {
-    		// eslint-disable-next-line regexp/no-dupe-characters-character-class
-    		pattern: /((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)\/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/,
+    		pattern: RegExp(
+    			// lookbehind
+    			// eslint-disable-next-line regexp/no-dupe-characters-character-class
+    			/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)/.source +
+    			// Regex pattern:
+    			// There are 2 regex patterns here. The RegExp set notation proposal added support for nested character
+    			// classes if the `v` flag is present. Unfortunately, nested CCs are both context-free and incompatible
+    			// with the only syntax, so we have to define 2 different regex patterns.
+    			/\//.source +
+    			'(?:' +
+    			/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}/.source +
+    			'|' +
+    			// `v` flag syntax. This supports 3 levels of nested character classes.
+    			/(?:\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.)*\])*\])*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}v[dgimyus]{0,7}/.source +
+    			')' +
+    			// lookahead
+    			/(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/.source
+    		),
     		lookbehind: true,
     		greedy: true,
     		inside: {
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/js/demo.js.map b/tobago-example/tobago-example-demo/src/main/webapp/js/demo.js.map
index 7bcb96c3e3..c619ad7fa2 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/js/demo.js.map
+++ b/tobago-example/tobago-example-demo/src/main/webapp/js/demo.js.map
@@ -1 +1 @@
-{"version":3,"file":"demo.js","sources":["demo-alert.js","demo-copy-to-clipboard.js","../../../../node_modules/prismjs/prism.js","demo-highlight.js","demo-inspect.js","demo-login.js","demo-search.js","demo-test.js"],"sourcesContent":["/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You [...]
\ No newline at end of file
+{"version":3,"file":"demo.js","sources":["demo-alert.js","demo-copy-to-clipboard.js","../../../../node_modules/prismjs/prism.js","demo-highlight.js","demo-inspect.js","demo-login.js","demo-search.js","demo-test.js"],"sourcesContent":["/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You [...]
\ No newline at end of file
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/js/jasmine.js b/tobago-example/tobago-example-demo/src/main/webapp/js/jasmine.js
index 25b5f5a9b7..f6049e3177 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/js/jasmine.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/js/jasmine.js
@@ -152,6 +152,7 @@ getJasmineRequireObj().requireMatchers = function(jRequire, j$) {
       'toHaveBeenCalledTimes',
       'toHaveBeenCalledWith',
       'toHaveClass',
+      'toHaveSpyInteractions',
       'toMatch',
       'toThrow',
       'toThrowError',
@@ -640,6 +641,8 @@ getJasmineRequireObj().util = function(j$) {
       // All falsey values are either primitives, `null`, or `undefined.
       if (!argsAsArray[i] || str.match(primitives)) {
         clonedArgs.push(argsAsArray[i]);
+      } else if (str === '[object Date]') {
+        clonedArgs.push(new Date(argsAsArray[i].valueOf()));
       } else {
         clonedArgs.push(j$.util.clone(argsAsArray[i]));
       }
@@ -659,18 +662,6 @@ getJasmineRequireObj().util = function(j$) {
     return descriptor;
   };
 
-  util.objectDifference = function(obj, toRemove) {
-    var diff = {};
-
-    for (var key in obj) {
-      if (util.has(obj, key) && !util.has(toRemove, key)) {
-        diff[key] = obj[key];
-      }
-    }
-
-    return diff;
-  };
-
   util.has = function(obj, key) {
     return Object.prototype.hasOwnProperty.call(obj, key);
   };
@@ -1039,7 +1030,7 @@ getJasmineRequireObj().Spec = function(j$) {
       boilerplateEnd =
         boilerplateStart + Spec.pendingSpecExceptionMessage.length;
 
-    return fullMessage.substr(boilerplateEnd);
+    return fullMessage.slice(boilerplateEnd);
   };
 
   Spec.pendingSpecExceptionMessage = '=> marked Pending';
@@ -2169,7 +2160,10 @@ getJasmineRequireObj().Env = function(j$) {
       }
       addSpecsToSuite(suite, specDefinitions);
       if (suite.parentSuite && !suite.children.length) {
-        throw new Error('describe with no children (describe() or it())');
+        throw new Error(
+          'describe with no children (describe() or it()): ' +
+            suite.getFullName()
+        );
       }
       return suite.metadata;
     };
@@ -5534,12 +5528,12 @@ getJasmineRequireObj().MatchersUtil = function(j$) {
     }
 
     // Deep compare objects.
-    var aKeys = keys(a, className == '[object Array]'),
+    var aKeys = MatchersUtil.keys(a, className == '[object Array]'),
       key;
     size = aKeys.length;
 
     // Ensure that both objects contain the same number of properties before comparing deep equality.
-    if (keys(b, className == '[object Array]').length !== size) {
+    if (MatchersUtil.keys(b, className == '[object Array]').length !== size) {
       diffBuilder.recordMismatch(
         objectKeysAreDifferentFormatter.bind(null, this.pp)
       );
@@ -5575,18 +5569,24 @@ getJasmineRequireObj().MatchersUtil = function(j$) {
     return result;
   };
 
-  function keys(obj, isArray) {
-    var allKeys = Object.keys
-      ? Object.keys(obj)
-      : (function(o) {
-          var keys = [];
-          for (var key in o) {
-            if (j$.util.has(o, key)) {
-              keys.push(key);
-            }
-          }
-          return keys;
-        })(obj);
+  MatchersUtil.keys = function(obj, isArray) {
+    var allKeys = (function(o) {
+      var keys = [];
+      for (var key in o) {
+        if (j$.util.has(o, key)) {
+          keys.push(key);
+        }
+      }
+
+      var symbols = Object.getOwnPropertySymbols(o);
+      for (var i = 0; i < symbols.length; i++) {
+        if (o.propertyIsEnumerable(symbols[i])) {
+          keys.push(symbols[i]);
+        }
+      }
+
+      return keys;
+    })(obj);
 
     if (!isArray) {
       return allKeys;
@@ -5598,21 +5598,29 @@ getJasmineRequireObj().MatchersUtil = function(j$) {
 
     var extraKeys = [];
     for (var i = 0; i < allKeys.length; i++) {
-      if (!/^[0-9]+$/.test(allKeys[i])) {
+      if (typeof allKeys[i] === 'symbol' || !/^[0-9]+$/.test(allKeys[i])) {
         extraKeys.push(allKeys[i]);
       }
     }
 
     return extraKeys;
-  }
+  };
 
   function isFunction(obj) {
     return typeof obj === 'function';
   }
 
+  // Returns an array of [k, v] pairs for eacch property that's in objA
+  // and not in objB.
+  function extraKeysAndValues(objA, objB) {
+    return MatchersUtil.keys(objA)
+      .filter(key => !j$.util.has(objB, key))
+      .map(key => [key, objA[key]]);
+  }
+
   function objectKeysAreDifferentFormatter(pp, actual, expected, path) {
-    var missingProperties = j$.util.objectDifference(expected, actual),
-      extraProperties = j$.util.objectDifference(actual, expected),
+    var missingProperties = extraKeysAndValues(expected, actual),
+      extraProperties = extraKeysAndValues(actual, expected),
       missingPropertiesMessage = formatKeyValuePairs(pp, missingProperties),
       extraPropertiesMessage = formatKeyValuePairs(pp, extraProperties),
       messages = [];
@@ -5662,11 +5670,13 @@ getJasmineRequireObj().MatchersUtil = function(j$) {
     );
   }
 
-  function formatKeyValuePairs(pp, obj) {
-    var formatted = '';
-    for (var key in obj) {
-      formatted += '\n    ' + key + ': ' + pp(obj[key]);
+  function formatKeyValuePairs(pp, keyValuePairs) {
+    let formatted = '';
+
+    for (const [key, value] of keyValuePairs) {
+      formatted += '\n    ' + key.toString() + ': ' + pp(value);
     }
+
     return formatted;
   }
 
@@ -5844,8 +5854,8 @@ getJasmineRequireObj().ObjectPath = function(j$) {
   };
 
   function formatPropertyAccess(prop) {
-    if (typeof prop === 'number') {
-      return '[' + prop + ']';
+    if (typeof prop === 'number' || typeof prop === 'symbol') {
+      return '[' + prop.toString() + ']';
     }
 
     if (isValidIdentifier(prop)) {
@@ -5956,6 +5966,14 @@ getJasmineRequireObj().toBeCloseTo = function() {
           );
         }
 
+        // Infinity is close to Infinity and -Infinity is close to -Infinity,
+        // regardless of the precision.
+        if (expected === Infinity || expected === -Infinity) {
+          return {
+            pass: actual === expected
+          };
+        }
+
         var pow = Math.pow(10, precision + 1);
         var delta = Math.abs(expected - actual);
         var maxDelta = Math.pow(10, -precision) / 2;
@@ -6926,6 +6944,82 @@ getJasmineRequireObj().toHaveSize = function(j$) {
   return toHaveSize;
 };
 
+getJasmineRequireObj().toHaveSpyInteractions = function(j$) {
+  var getErrorMsg = j$.formatErrorMsg(
+    '<toHaveSpyInteractions>',
+    'expect(<spyObj>).toHaveSpyInteractions()'
+  );
+
+  /**
+   * {@link expect} the actual (a {@link SpyObj}) spies to have been called.
+   * @function
+   * @name matchers#toHaveSpyInteractions
+   * @since 4.1.0
+   * @example
+   * expect(mySpyObj).toHaveSpyInteractions();
+   * expect(mySpyObj).not.toHaveSpyInteractions();
+   */
+  function toHaveSpyInteractions(matchersUtil) {
+    return {
+      compare: function(actual) {
+        var result = {};
+
+        if (!j$.isObject_(actual)) {
+          throw new Error(
+            getErrorMsg('Expected a spy object, but got ' + typeof actual + '.')
+          );
+        }
+
+        if (arguments.length > 1) {
+          throw new Error(getErrorMsg('Does not take arguments'));
+        }
+
+        result.pass = false;
+        let hasSpy = false;
+        const calledSpies = [];
+        for (const spy of Object.values(actual)) {
+          if (!j$.isSpy(spy)) continue;
+          hasSpy = true;
+
+          if (spy.calls.any()) {
+            result.pass = true;
+            calledSpies.push([spy.and.identity, spy.calls.count()]);
+          }
+        }
+
+        if (!hasSpy) {
+          throw new Error(
+            getErrorMsg(
+              'Expected a spy object with spies, but object has no spies.'
+            )
+          );
+        }
+
+        let resultMessage;
+        if (result.pass) {
+          resultMessage =
+            'Expected spy object spies not to have been called, ' +
+            'but the following spies were called: ';
+          resultMessage += calledSpies
+            .map(([spyName, spyCount]) => {
+              return `${spyName} called ${spyCount} time(s)`;
+            })
+            .join(', ');
+        } else {
+          resultMessage =
+            'Expected spy object spies to have been called, ' +
+            'but no spies were called.';
+        }
+        result.message = resultMessage;
+
+        return result;
+      }
+    };
+  }
+
+  return toHaveSpyInteractions;
+};
+
 getJasmineRequireObj().toMatch = function(j$) {
   var getErrorMsg = j$.formatErrorMsg(
     '<toMatch>',
@@ -7488,7 +7582,7 @@ getJasmineRequireObj().makePrettyPrinter = function(j$) {
         this.emitScalar('<global>');
       } else if (value.jasmineToString) {
         this.emitScalar(value.jasmineToString(this.pp_));
-      } else if (typeof value === 'string') {
+      } else if (j$.isString_(value)) {
         this.emitString(value);
       } else if (j$.isSpy(value)) {
         this.emitScalar('spy on ' + value.and.identity);
@@ -7554,7 +7648,7 @@ getJasmineRequireObj().makePrettyPrinter = function(j$) {
   };
 
   SinglePrettyPrintRun.prototype.iterateObject = function(obj, fn) {
-    var objKeys = keys(obj, j$.isArray_(obj));
+    var objKeys = j$.MatchersUtil.keys(obj, j$.isArray_(obj));
     var isGetter = function isGetter(prop) {};
 
     if (obj.__lookupGetter__) {
@@ -7749,8 +7843,14 @@ getJasmineRequireObj().makePrettyPrinter = function(j$) {
     property,
     isGetter
   ) {
-    this.append(property);
+    if (typeof property === 'symbol') {
+      this.append(property.toString());
+    } else {
+      this.append(property);
+    }
+
     this.append(': ');
+
     if (isGetter) {
       this.append('<getter>');
     } else {
@@ -7792,37 +7892,6 @@ getJasmineRequireObj().makePrettyPrinter = function(j$) {
 
   MaxCharsReachedError.prototype = new Error();
 
-  function keys(obj, isArray) {
-    var allKeys = Object.keys
-      ? Object.keys(obj)
-      : (function(o) {
-          var keys = [];
-          for (var key in o) {
-            if (j$.util.has(o, key)) {
-              keys.push(key);
-            }
-          }
-          return keys;
-        })(obj);
-
-    if (!isArray) {
-      return allKeys;
-    }
-
-    if (allKeys.length === 0) {
-      return allKeys;
-    }
-
-    var extraKeys = [];
-    for (var i = 0; i < allKeys.length; i++) {
-      if (!/^[0-9]+$/.test(allKeys[i])) {
-        extraKeys.push(allKeys[i]);
-      }
-    }
-
-    return extraKeys;
-  }
-
   function customFormat(value, customObjectFormatters) {
     var i, result;
 
@@ -10199,5 +10268,5 @@ getJasmineRequireObj().UserContext = function(j$) {
 };
 
 getJasmineRequireObj().version = function() {
-  return '4.0.1';
+  return '4.1.1';
 };
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 3d58b632e5..586f73a3cd 100644
--- a/tobago-theme/tobago-theme-charlotteville/src/main/css/tobago.css
+++ b/tobago-theme/tobago-theme-charlotteville/src/main/css/tobago.css
@@ -12075,7 +12075,6 @@ tobago-range .tobago-tooltip {
   border-radius: 0.25rem;
 }
 
-.tobago-required label:after,
 label.tobago-required:after {
   content: "*";
   color: #ff00be;
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 7d50c4b887..d2393e0a89 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/bootstrap.scss","../../../../node_modules/bootstrap/scss/_root.scss","../../../../node_modules/bootstrap/scss/_reboot.scss","../../../../node_modules/bootstrap/scss/vendor/_rfs.scss","../../../../node_modules/bootstrap/scss/_variables.scss","../../../../node_modules/bootstrap/scss/mixins/_border-radius.scss","../../../../node_modules/bootstrap/scss/_type.scss", [...]
\ No newline at end of file
+{"version":3,"sources":["tobago.css","../scss/tobago-theme.scss","../scss/_custom.scss","../../../../node_modules/bootstrap/scss/bootstrap.scss","../../../../node_modules/bootstrap/scss/_root.scss","../../../../node_modules/bootstrap/scss/_reboot.scss","../../../../node_modules/bootstrap/scss/vendor/_rfs.scss","../../../../node_modules/bootstrap/scss/_variables.scss","../../../../node_modules/bootstrap/scss/mixins/_border-radius.scss","../../../../node_modules/bootstrap/scss/_type.scss", [...]
\ 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 ceb08dc18f..a1420d04e4 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-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-primary:#529696;-- [...]
+@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-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-primary:#529696;-- [...]
 /*# 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 e74cc80b63..da329bbd3f 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,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,iBAAkB,G [...]
\ 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,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,iBAAkB,G [...]
\ 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 3ac9f30a9e..d2b19d6dbb 100644
--- a/tobago-theme/tobago-theme-roxborough/src/main/css/tobago.css
+++ b/tobago-theme/tobago-theme-roxborough/src/main/css/tobago.css
@@ -12098,7 +12098,6 @@ tobago-range .tobago-tooltip {
   border-radius: 0.25rem;
 }
 
-.tobago-required label:after,
 label.tobago-required:after {
   content: "*";
   color: #ffb243;
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 69ae1714f2..f3a31f2ce3 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/bootstrap.scss","../../../../node_modules/bootstrap/scss/_root.scss","../../../../node_modules/bootstrap/scss/_reboot.scss","../../../../node_modules/bootstrap/scss/vendor/_rfs.scss","../../../../node_modules/bootstrap/scss/_variables.scss","../../../../node_modules/bootstrap/scss/mixins/_border-radius.scss","../../../../node_modules/bootstrap/scss/_type.scss", [...]
\ No newline at end of file
+{"version":3,"sources":["tobago.css","../scss/tobago-theme.scss","../scss/_custom.scss","../../../../node_modules/bootstrap/scss/bootstrap.scss","../../../../node_modules/bootstrap/scss/_root.scss","../../../../node_modules/bootstrap/scss/_reboot.scss","../../../../node_modules/bootstrap/scss/vendor/_rfs.scss","../../../../node_modules/bootstrap/scss/_variables.scss","../../../../node_modules/bootstrap/scss/mixins/_border-radius.scss","../../../../node_modules/bootstrap/scss/_type.scss", [...]
\ 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 db6daa5f50..c42a1ab00f 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 8548edd63e..80e13e23bb 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,mBAEvB,mBAAxB,uBACE,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,KACZ,UAAW,QACX,eAAgB,QAChB, [...]
\ 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,mBAEvB,mBAAxB,uBACE,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,KACZ,UAAW,QACX,eAAgB,QAChB, [...]
\ 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 3bc5b3846a..723dc65eaf 100644
--- a/tobago-theme/tobago-theme-scarborough/src/main/css/tobago.css
+++ b/tobago-theme/tobago-theme-scarborough/src/main/css/tobago.css
@@ -12085,7 +12085,6 @@ tobago-range .tobago-tooltip {
   border-radius: 0.25rem;
 }
 
-.tobago-required label:after,
 label.tobago-required:after {
   content: "*";
   color: #dc3545;
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 0c46c81363..29ced36be3 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/bootstrap.scss","../../../../node_modules/bootstrap/scss/_root.scss","../../../../node_modules/bootstrap/scss/_reboot.scss","../../../../node_modules/bootstrap/scss/vendor/_rfs.scss","../../../../node_modules/bootstrap/scss/_variables.scss","../../../../node_modules/bootstrap/scss/mixins/_border-radius.scss","../../../../node_modules/bootstrap/scss/_type.scss","../../../../node_modul [...]
\ No newline at end of file
+{"version":3,"sources":["tobago.css","../scss/tobago-theme.scss","../../../../node_modules/bootstrap/scss/bootstrap.scss","../../../../node_modules/bootstrap/scss/_root.scss","../../../../node_modules/bootstrap/scss/_reboot.scss","../../../../node_modules/bootstrap/scss/vendor/_rfs.scss","../../../../node_modules/bootstrap/scss/_variables.scss","../../../../node_modules/bootstrap/scss/mixins/_border-radius.scss","../../../../node_modules/bootstrap/scss/_type.scss","../../../../node_modul [...]
\ 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 10a34dd7f7..1ee1e40c27 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-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-primary:#0d6efd;--bs- [...]
+@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-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-primary:#0d6efd;--bs- [...]
 /*# 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 7eac4b8b0f..65ccc97993 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,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,iBAAkB,EAAE [...]
\ 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,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,iBAAkB,EAAE [...]
\ 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 1c876a8f6a..071a04e8cd 100644
--- a/tobago-theme/tobago-theme-speyside/src/main/css/tobago.css
+++ b/tobago-theme/tobago-theme-speyside/src/main/css/tobago.css
@@ -11784,7 +11784,6 @@ tobago-range .tobago-tooltip {
   border-radius: 0.25rem;
 }
 
-.tobago-required label:after,
 label.tobago-required:after {
   content: "*";
   color: rgb(211, 0, 64);
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 8f53cb47e2..6f02743e5c 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/bootstrap.scss","../../../../node_modules/bootstrap/scss/_root.scss","../../../../node_modules/bootstrap/scss/_reboot.scss","../../../../node_modules/bootstrap/scss/vendor/_rfs.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/bootstrap.scss","../../../../node_modules/bootstrap/scss/_root.scss","../../../../node_modules/bootstrap/scss/_reboot.scss","../../../../node_modules/bootstrap/scss/vendor/_rfs.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 ae19e83e81..2b01bdc8cd 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-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-800:#323232;--b [...]
+@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-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-800:#323232;--b [...]
 /*# 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 26b9ccaa5d..b199fe2f63 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,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,IAC9B,iBAAkB [...]
\ 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,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,IAC9B,iBAAkB [...]
\ 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 424a3a5eae..4b1444ce63 100644
--- a/tobago-theme/tobago-theme-standard/src/main/css/tobago.css
+++ b/tobago-theme/tobago-theme-standard/src/main/css/tobago.css
@@ -12055,7 +12055,6 @@ tobago-range .tobago-tooltip {
   border-radius: 0.25rem;
 }
 
-.tobago-required label:after,
 label.tobago-required:after {
   content: "*";
   color: #dc3545;
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 23ccb8d186..8c154817c9 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/bootstrap.scss","../../../../node_modules/bootstrap/scss/_root.scss","../../../../node_modules/bootstrap/scss/_reboot.scss","../../../../node_modules/bootstrap/scss/vendor/_rfs.scss","../../../../node_modules/bootstrap/scss/_variables.scss","../../../../node_modules/bootstrap/scss/mixins/_border-radius.scss","../../../../node_modules/bootstrap/scss/_type.scss","../../../../node_modul [...]
\ No newline at end of file
+{"version":3,"sources":["tobago.css","../scss/tobago-theme.scss","../../../../node_modules/bootstrap/scss/bootstrap.scss","../../../../node_modules/bootstrap/scss/_root.scss","../../../../node_modules/bootstrap/scss/_reboot.scss","../../../../node_modules/bootstrap/scss/vendor/_rfs.scss","../../../../node_modules/bootstrap/scss/_variables.scss","../../../../node_modules/bootstrap/scss/mixins/_border-radius.scss","../../../../node_modules/bootstrap/scss/_type.scss","../../../../node_modul [...]
\ 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 fdb631bf50..ad6966ac1d 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-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-primary:#0d6efd;--bs- [...]
+@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-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-primary:#0d6efd;--bs- [...]
 /*# 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 f107fb8981..1d80634be2 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,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,iBAAkB,EAAE,CA [...]
\ 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,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,iBAAkB,EAAE,CA [...]
\ No newline at end of file


[myfaces-tobago] 01/02: fix(labelLayout): required component

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

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

commit f8ec931076089a1fbfcbe11e73bcdbe0aa0d747a
Author: Henning Noeth <hn...@apache.org>
AuthorDate: Fri May 13 10:07:21 2022 +0200

    fix(labelLayout): required component
    
    The label must indicate if a component is required.
    
    * add .tobago-required to label tag
    * cleanup scss
    * add tests
    
    Issue: TOBAGO-2132
---
 .../renderer/LabelLayoutRendererBase.java          |   4 +-
 .../renderkit/renderer/InRendererUnitTest.java     | 145 +++++++++++++++++++++
 .../renderer/in/required-label-flexLeft.html       |  21 +++
 .../renderer/in/required-label-flexRight.html      |  21 +++
 .../renderer/in/required-label-flowLeft.html       |  21 +++
 .../renderer/in/required-label-flowRight.html      |  21 +++
 .../renderer/in/required-label-gridBottom.html     |  21 +++
 .../renderer/in/required-label-gridLeft.html       |  21 +++
 .../renderer/in/required-label-gridRight.html      |  21 +++
 .../renderer/in/required-label-gridTop.html        |  21 +++
 .../resources/renderer/in/required-label-none.html |  20 +++
 .../renderer/in/required-label-segmentLeft.html    |  27 ++++
 .../renderer/in/required-label-segmentRight.html   |  27 ++++
 .../resources/renderer/in/required-label-top.html  |  21 +++
 .../350-label-required/Label_Required.xhtml        |  44 +++++++
 tobago-theme/src/main/scss/_tobago.scss            |   1 -
 16 files changed, 455 insertions(+), 2 deletions(-)

diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/LabelLayoutRendererBase.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/LabelLayoutRendererBase.java
index 0642757f61..9a33642757 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/LabelLayoutRendererBase.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/LabelLayoutRendererBase.java
@@ -237,7 +237,9 @@ public abstract class LabelLayoutRendererBase<T extends UIComponent & SupportsLa
         writer.writeIdAttribute(labelId);
       }
       writer.writeAttribute(HtmlAttributes.FOR, getFieldId(facesContext, component), false);
-      writer.writeClassAttribute(BootstrapClass.COL_FORM_LABEL);
+      writer.writeClassAttribute(
+        ComponentUtils.getBooleanAttribute(component, Attributes.required) ? TobagoClass.REQUIRED : null,
+        BootstrapClass.COL_FORM_LABEL);
       if (component instanceof SupportsAccessKey) {
         final LabelWithAccessKey labelWithAccessKey = new LabelWithAccessKey((SupportsAccessKey) component);
         HtmlRendererUtils.writeLabelWithAccessKey(writer, labelWithAccessKey);
diff --git a/tobago-core/src/test/java/org/apache/myfaces/tobago/internal/renderkit/renderer/InRendererUnitTest.java b/tobago-core/src/test/java/org/apache/myfaces/tobago/internal/renderkit/renderer/InRendererUnitTest.java
index 1a381ce634..e520519c8d 100644
--- a/tobago-core/src/test/java/org/apache/myfaces/tobago/internal/renderkit/renderer/InRendererUnitTest.java
+++ b/tobago-core/src/test/java/org/apache/myfaces/tobago/internal/renderkit/renderer/InRendererUnitTest.java
@@ -398,4 +398,149 @@ public class InRendererUnitTest extends RendererTestBase {
     Assertions.assertEquals(loadHtml("renderer/in/ajax.html"), formattedResult());
   }
 
+  @Test
+  public void requiredLabelLayoutFlexLeft() throws IOException {
+    final UIIn c = (UIIn) ComponentUtils.createComponent(
+      facesContext, Tags.in.componentType(), RendererTypes.In, "id");
+    c.setLabel("label");
+    c.setRequired(true);
+    c.setLabelLayout(LabelLayout.flexLeft); // same as default
+    c.encodeAll(facesContext);
+
+    Assertions.assertEquals(loadHtml("renderer/in/required-label-flexLeft.html"), formattedResult());
+  }
+
+  @Test
+  public void requiredLabelLayoutFlexRight() throws IOException {
+    final UIIn c = (UIIn) ComponentUtils.createComponent(
+      facesContext, Tags.in.componentType(), RendererTypes.In, "id");
+    c.setLabel("label");
+    c.setRequired(true);
+    c.setLabelLayout(LabelLayout.flexRight);
+    c.encodeAll(facesContext);
+
+    Assertions.assertEquals(loadHtml("renderer/in/required-label-flexRight.html"), formattedResult());
+  }
+
+  @Test
+  public void requiredLabelLayoutFlowLeft() throws IOException {
+    final UIIn c = (UIIn) ComponentUtils.createComponent(
+      facesContext, Tags.in.componentType(), RendererTypes.In, "id");
+    c.setLabel("label");
+    c.setRequired(true);
+    c.setLabelLayout(LabelLayout.flowLeft);
+    c.encodeAll(facesContext);
+
+    Assertions.assertEquals(loadHtml("renderer/in/required-label-flowLeft.html"), formattedResult());
+  }
+
+  @Test
+  public void requiredLabelLayoutFlowRight() throws IOException {
+    final UIIn c = (UIIn) ComponentUtils.createComponent(
+      facesContext, Tags.in.componentType(), RendererTypes.In, "id");
+    c.setLabel("label");
+    c.setRequired(true);
+    c.setLabelLayout(LabelLayout.flowRight);
+    c.encodeAll(facesContext);
+
+    Assertions.assertEquals(loadHtml("renderer/in/required-label-flowRight.html"), formattedResult());
+  }
+
+  @Test
+  public void requiredLabelLayoutTop() throws IOException {
+    final UIIn c = (UIIn) ComponentUtils.createComponent(
+      facesContext, Tags.in.componentType(), RendererTypes.In, "id");
+    c.setLabel("label");
+    c.setRequired(true);
+    c.setLabelLayout(LabelLayout.top);
+    c.encodeAll(facesContext);
+
+    Assertions.assertEquals(loadHtml("renderer/in/required-label-top.html"), formattedResult());
+  }
+
+  @Test
+  public void requiredLabelLayoutGridLeft() throws IOException {
+    final UIIn c = (UIIn) ComponentUtils.createComponent(
+      facesContext, Tags.in.componentType(), RendererTypes.In, "id");
+    c.setLabel("label");
+    c.setRequired(true);
+    c.setLabelLayout(LabelLayout.gridLeft);
+    c.encodeAll(facesContext);
+
+    Assertions.assertEquals(loadHtml("renderer/in/required-label-gridLeft.html"), formattedResult());
+  }
+
+  @Test
+  public void requiredLabelLayoutGridRight() throws IOException {
+    final UIIn c = (UIIn) ComponentUtils.createComponent(
+      facesContext, Tags.in.componentType(), RendererTypes.In, "id");
+    c.setLabel("label");
+    c.setRequired(true);
+    c.setLabelLayout(LabelLayout.gridRight);
+    c.encodeAll(facesContext);
+
+    Assertions.assertEquals(loadHtml("renderer/in/required-label-gridRight.html"), formattedResult());
+  }
+
+  @Test
+  public void requiredLabelLayoutGridTop() throws IOException {
+    final UIIn c = (UIIn) ComponentUtils.createComponent(
+      facesContext, Tags.in.componentType(), RendererTypes.In, "id");
+    c.setLabel("label");
+    c.setRequired(true);
+    c.setLabelLayout(LabelLayout.gridTop);
+    c.encodeAll(facesContext);
+
+    Assertions.assertEquals(loadHtml("renderer/in/required-label-gridTop.html"), formattedResult());
+  }
+
+  @Test
+  public void requiredLabelLayoutGridBottom() throws IOException {
+    final UIIn c = (UIIn) ComponentUtils.createComponent(
+      facesContext, Tags.in.componentType(), RendererTypes.In, "id");
+    c.setLabel("label");
+    c.setRequired(true);
+    c.setLabelLayout(LabelLayout.gridBottom);
+    c.encodeAll(facesContext);
+
+    Assertions.assertEquals(loadHtml("renderer/in/required-label-gridBottom.html"), formattedResult());
+  }
+
+  @Test
+  public void requiredLabelLayoutSegmentLeft() throws IOException {
+
+    final UISegmentLayout l = (UISegmentLayout) ComponentUtils.createComponent(
+      facesContext, Tags.segmentLayout.componentType(), RendererTypes.SegmentLayout, "segid");
+    l.setMedium(SegmentMeasureList.parse("3seg 9seg"));
+
+    final UIIn c = (UIIn) ComponentUtils.createComponent(
+      facesContext, Tags.in.componentType(), RendererTypes.In, "id");
+    c.setLabel("label");
+    c.setRequired(true);
+    c.setLabelLayout(LabelLayout.segmentLeft);
+
+    l.getChildren().add(c);
+    l.encodeAll(facesContext);
+
+    Assertions.assertEquals(loadHtml("renderer/in/required-label-segmentLeft.html"), formattedResult());
+  }
+
+  @Test
+  public void requiredLabelLayoutSegmentRight() throws IOException {
+
+    final UISegmentLayout l = (UISegmentLayout) ComponentUtils.createComponent(
+      facesContext, Tags.segmentLayout.componentType(), RendererTypes.SegmentLayout, "segid");
+    l.setMedium(SegmentMeasureList.parse("9seg 3seg"));
+
+    final UIIn c = (UIIn) ComponentUtils.createComponent(
+      facesContext, Tags.in.componentType(), RendererTypes.In, "id");
+    c.setLabel("label");
+    c.setRequired(true);
+    c.setLabelLayout(LabelLayout.segmentRight);
+
+    l.getChildren().add(c);
+    l.encodeAll(facesContext);
+
+    Assertions.assertEquals(loadHtml("renderer/in/required-label-segmentRight.html"), formattedResult());
+  }
 }
diff --git a/tobago-core/src/test/resources/renderer/in/required-label-flexLeft.html b/tobago-core/src/test/resources/renderer/in/required-label-flexLeft.html
new file mode 100644
index 0000000000..901aa88b47
--- /dev/null
+++ b/tobago-core/src/test/resources/renderer/in/required-label-flexLeft.html
@@ -0,0 +1,21 @@
+<!--
+ * 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.
+-->
+
+<tobago-in id='id' class='tobago-label-container tobago-auto-spacing tobago-required'>
+  <label for='id::field' class='tobago-required col-form-label'>label</label>
+  <input type='text' name='id' id='id::field' class='form-control' required='required'>
+</tobago-in>
diff --git a/tobago-core/src/test/resources/renderer/in/required-label-flexRight.html b/tobago-core/src/test/resources/renderer/in/required-label-flexRight.html
new file mode 100644
index 0000000000..574baf4c5c
--- /dev/null
+++ b/tobago-core/src/test/resources/renderer/in/required-label-flexRight.html
@@ -0,0 +1,21 @@
+<!--
+ * 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.
+-->
+
+<tobago-in id='id' class='tobago-label-container tobago-auto-spacing tobago-required'>
+  <input type='text' name='id' id='id::field' class='form-control' required='required'>
+  <label for='id::field' class='tobago-required col-form-label'>label</label>
+</tobago-in>
diff --git a/tobago-core/src/test/resources/renderer/in/required-label-flowLeft.html b/tobago-core/src/test/resources/renderer/in/required-label-flowLeft.html
new file mode 100644
index 0000000000..b3a0490139
--- /dev/null
+++ b/tobago-core/src/test/resources/renderer/in/required-label-flowLeft.html
@@ -0,0 +1,21 @@
+<!--
+ * 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.
+-->
+
+<label for='id::field' class='tobago-required col-form-label'>label</label>
+<tobago-in id='id' class='tobago-auto-spacing tobago-required tobago-display-inline-block'>
+  <input type='text' name='id' id='id::field' class='form-control' required='required'>
+</tobago-in>
diff --git a/tobago-core/src/test/resources/renderer/in/required-label-flowRight.html b/tobago-core/src/test/resources/renderer/in/required-label-flowRight.html
new file mode 100644
index 0000000000..ab743d2e12
--- /dev/null
+++ b/tobago-core/src/test/resources/renderer/in/required-label-flowRight.html
@@ -0,0 +1,21 @@
+<!--
+ * 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.
+-->
+
+<tobago-in id='id' class='tobago-auto-spacing tobago-required tobago-display-inline-block'>
+  <input type='text' name='id' id='id::field' class='form-control' required='required'>
+</tobago-in>
+<label for='id::field' class='tobago-required col-form-label'>label</label>
diff --git a/tobago-core/src/test/resources/renderer/in/required-label-gridBottom.html b/tobago-core/src/test/resources/renderer/in/required-label-gridBottom.html
new file mode 100644
index 0000000000..f4b9a4ab63
--- /dev/null
+++ b/tobago-core/src/test/resources/renderer/in/required-label-gridBottom.html
@@ -0,0 +1,21 @@
+<!--
+ * 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.
+-->
+
+<label id='id::label' for='id::field' class='tobago-required col-form-label'>label</label>
+<tobago-in id='id' class='tobago-auto-spacing tobago-required'>
+  <input type='text' name='id' id='id::field' class='form-control' required='required'>
+</tobago-in>
diff --git a/tobago-core/src/test/resources/renderer/in/required-label-gridLeft.html b/tobago-core/src/test/resources/renderer/in/required-label-gridLeft.html
new file mode 100644
index 0000000000..f4b9a4ab63
--- /dev/null
+++ b/tobago-core/src/test/resources/renderer/in/required-label-gridLeft.html
@@ -0,0 +1,21 @@
+<!--
+ * 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.
+-->
+
+<label id='id::label' for='id::field' class='tobago-required col-form-label'>label</label>
+<tobago-in id='id' class='tobago-auto-spacing tobago-required'>
+  <input type='text' name='id' id='id::field' class='form-control' required='required'>
+</tobago-in>
diff --git a/tobago-core/src/test/resources/renderer/in/required-label-gridRight.html b/tobago-core/src/test/resources/renderer/in/required-label-gridRight.html
new file mode 100644
index 0000000000..f4b9a4ab63
--- /dev/null
+++ b/tobago-core/src/test/resources/renderer/in/required-label-gridRight.html
@@ -0,0 +1,21 @@
+<!--
+ * 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.
+-->
+
+<label id='id::label' for='id::field' class='tobago-required col-form-label'>label</label>
+<tobago-in id='id' class='tobago-auto-spacing tobago-required'>
+  <input type='text' name='id' id='id::field' class='form-control' required='required'>
+</tobago-in>
diff --git a/tobago-core/src/test/resources/renderer/in/required-label-gridTop.html b/tobago-core/src/test/resources/renderer/in/required-label-gridTop.html
new file mode 100644
index 0000000000..f4b9a4ab63
--- /dev/null
+++ b/tobago-core/src/test/resources/renderer/in/required-label-gridTop.html
@@ -0,0 +1,21 @@
+<!--
+ * 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.
+-->
+
+<label id='id::label' for='id::field' class='tobago-required col-form-label'>label</label>
+<tobago-in id='id' class='tobago-auto-spacing tobago-required'>
+  <input type='text' name='id' id='id::field' class='form-control' required='required'>
+</tobago-in>
diff --git a/tobago-core/src/test/resources/renderer/in/required-label-none.html b/tobago-core/src/test/resources/renderer/in/required-label-none.html
new file mode 100644
index 0000000000..3215ca5fbf
--- /dev/null
+++ b/tobago-core/src/test/resources/renderer/in/required-label-none.html
@@ -0,0 +1,20 @@
+<!--
+ * 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.
+-->
+
+<tobago-in id='id' class='tobago-auto-spacing tobago-required'>
+  <input type='text' name='id' id='id::field' class='form-control' required='required'>
+</tobago-in>
diff --git a/tobago-core/src/test/resources/renderer/in/required-label-segmentLeft.html b/tobago-core/src/test/resources/renderer/in/required-label-segmentLeft.html
new file mode 100644
index 0000000000..d19305d677
--- /dev/null
+++ b/tobago-core/src/test/resources/renderer/in/required-label-segmentLeft.html
@@ -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.
+-->
+
+<tobago-segment-layout id='segid' class='row'>
+  <div class='col-md-3'>
+    <label for='id::field' class='tobago-required col-form-label'>label</label>
+  </div>
+  <div class='col-md-9'>
+    <tobago-in id='id' class='tobago-auto-spacing tobago-required'>
+      <input type='text' name='id' id='id::field' class='form-control' required='required'>
+    </tobago-in>
+  </div>
+</tobago-segment-layout>
diff --git a/tobago-core/src/test/resources/renderer/in/required-label-segmentRight.html b/tobago-core/src/test/resources/renderer/in/required-label-segmentRight.html
new file mode 100644
index 0000000000..5c8b48b0c8
--- /dev/null
+++ b/tobago-core/src/test/resources/renderer/in/required-label-segmentRight.html
@@ -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.
+-->
+
+<tobago-segment-layout id='segid' class='row'>
+  <div class='col-md-9'>
+    <tobago-in id='id' class='tobago-auto-spacing tobago-required'>
+      <input type='text' name='id' id='id::field' class='form-control' required='required'>
+    </tobago-in>
+  </div>
+  <div class='col-md-3'>
+    <label for='id::field' class='tobago-required col-form-label'>label</label>
+  </div>
+</tobago-segment-layout>
diff --git a/tobago-core/src/test/resources/renderer/in/required-label-top.html b/tobago-core/src/test/resources/renderer/in/required-label-top.html
new file mode 100644
index 0000000000..1e83c30231
--- /dev/null
+++ b/tobago-core/src/test/resources/renderer/in/required-label-top.html
@@ -0,0 +1,21 @@
+<!--
+ * 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.
+-->
+
+<tobago-in id='id' class='tobago-auto-spacing tobago-required'>
+  <label for='id::field' class='tobago-required col-form-label'>label</label>
+  <input type='text' name='id' id='id::field' class='form-control' required='required'>
+</tobago-in>
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/900-test/4800-labelLayout/350-label-required/Label_Required.xhtml b/tobago-example/tobago-example-demo/src/main/webapp/content/900-test/4800-labelLayout/350-label-required/Label_Required.xhtml
new file mode 100644
index 0000000000..1a5edaed46
--- /dev/null
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/900-test/4800-labelLayout/350-label-required/Label_Required.xhtml
@@ -0,0 +1,44 @@
+<?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:tc="http://myfaces.apache.org/tobago/component"
+                xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
+
+  <tc:in label="none" value="none" required="true" labelLayout="none"/>
+  <tc:in label="flexLeft" value="flexLeft" required="true" labelLayout="flexLeft"/>
+  <tc:in label="flexRight" value="flexRight" required="true" labelLayout="flexRight"/>
+  <tc:in label="top" value="top" required="true" labelLayout="top"/>
+
+  <tc:segmentLayout medium="6seg">
+    <tc:in label="segmentLeft" value="segmentLeft" required="true" labelLayout="segmentLeft"/>
+    <tc:in label="segmentRight" value="segmentRight" required="true" labelLayout="segmentRight"/>
+  </tc:segmentLayout>
+
+  <tc:in label="flowLeft" value="flowLeft" required="true" labelLayout="flowLeft"/>
+  <tc:in label="flowRight" value="flowRight" required="true" labelLayout="flowRight"/>
+
+  <tc:gridLayout columns="1fr 1fr" rows="auto">
+    <tc:in label="gridLeft" value="gridLeft" required="true" labelLayout="gridLeft"/>
+    <tc:in label="gridRight" value="gridRight" required="true" labelLayout="gridRight"/>
+    <tc:in label="gridTop" value="gridTop" required="true" labelLayout="gridTop"/>
+    <tc:in label="gridBottom" value="gridBottom" required="true" labelLayout="gridBottom"/>
+  </tc:gridLayout>
+</ui:composition>
diff --git a/tobago-theme/src/main/scss/_tobago.scss b/tobago-theme/src/main/scss/_tobago.scss
index a3e9dc5b97..8069a36301 100644
--- a/tobago-theme/src/main/scss/_tobago.scss
+++ b/tobago-theme/src/main/scss/_tobago.scss
@@ -929,7 +929,6 @@ tobago-range {
   }
 }
 
-.tobago-required label:after,
 label.tobago-required:after {
   content: "*";
   color: $danger;