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/02/10 20:40:35 UTC

[myfaces-tobago] branch main updated (e949d2ed13 -> 4b8156e143)

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 e949d2ed13 build(theme): rebuild after fixing selectManyList
     new e0261c3b08 feat: tc:selectOneList
     new a08f4573ab fix(selectManyList): jakarta namespace
     new 4b8156e143 build(theme): rebuild after implementing tc:selectOneMany

The 3 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/RendererTypes.java    |   2 +
 .../org/apache/myfaces/tobago/component/Tags.java  |   2 +
 ...OneChoice.java => AbstractUISelectOneList.java} |  12 +-
 ...istRenderer.java => SelectOneListRenderer.java} |  83 +++----
 .../component/SelectManyListTagDeclaration.java    |   2 +-
 ...ation.java => SelectOneListTagDeclaration.java} |  55 ++---
 .../tobago/renderkit/html/HtmlElements.java        |   1 +
 ...ontroller.java => SelectOneListController.java} |  32 +--
 .../SelectOneList.xhtml}                           |  34 +--
 tobago-theme/src/main/scss/_tobago.scss            | 262 +++++++++++----------
 .../src/main/css/tobago.css                        | 126 +++++++++-
 .../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                        | 126 +++++++++-
 .../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                        | 126 +++++++++-
 .../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  | 126 +++++++++-
 .../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  | 126 +++++++++-
 .../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/js/tobago.js    |   4 +-
 .../src/main/js/tobago.js.map                      |   2 +-
 .../src/main/resources/META-INF/tobago-config.xml  |   5 +
 .../src/main/ts/tobago-all.ts                      |   1 +
 .../src/main/ts/tobago-select-list-base.ts         | 230 ++++++++++++++++++
 .../src/main/ts/tobago-select-many-list.ts         | 238 +++----------------
 .../src/main/ts/tobago-select-one-list.ts          | 171 ++++++++++++++
 37 files changed, 1294 insertions(+), 502 deletions(-)
 copy tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/{AbstractUISelectOneChoice.java => AbstractUISelectOneList.java} (84%)
 copy tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/{SelectManyListRenderer.java => SelectOneListRenderer.java} (90%)
 copy tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/{SelectManyListTagDeclaration.java => SelectOneListTagDeclaration.java} (69%)
 copy tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/{SelectManyListController.java => SelectOneListController.java} (79%)
 copy tobago-example/tobago-example-demo/src/main/webapp/content/030-select/{80-selectManyList/SelectManyList.xhtml => 45-selectOneList/SelectOneList.xhtml} (71%)
 create mode 100644 tobago-theme/tobago-theme-standard/src/main/ts/tobago-select-list-base.ts
 create mode 100644 tobago-theme/tobago-theme-standard/src/main/ts/tobago-select-one-list.ts


[myfaces-tobago] 01/03: feat: tc:selectOneList

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 e0261c3b081bad8bc3db39e751570cf4c8793667
Author: Henning Noeth <hn...@apache.org>
AuthorDate: Tue Feb 7 20:52:28 2023 +0100

    feat: tc:selectOneList
    
    * implement tc:selectOneList according to tc:selectManyList
    * add demo
    * make a typescript base class for Select[One/Many]List
    * fix: preselection if filter is active
    * fix: don't open dropdown menu if component is disabled
    * adjust the behavior of selectManyList to act like selectOneList
    ** remove value of filter input if leaving component
    ** use input event for filterInput instead of keyup
    ** initial focus doesn't open dropdownMenu like the regular tc:selectOneChoice component
    
    Issue: TOBAGO-2179
---
 .../myfaces/tobago/component/RendererTypes.java    |   2 +
 .../org/apache/myfaces/tobago/component/Tags.java  |   2 +
 .../component/AbstractUISelectOneList.java         |  36 +++
 .../renderkit/renderer/SelectOneListRenderer.java  | 212 +++++++++++++++++
 .../component/SelectOneListTagDeclaration.java     |  77 ++++++
 .../tobago/renderkit/html/HtmlElements.java        |   1 +
 .../example/demo/SelectOneListController.java      | 138 +++++++++++
 .../45-selectOneList/SelectOneList.xhtml           |  87 +++++++
 tobago-theme/src/main/scss/_tobago.scss            | 262 +++++++++++----------
 .../src/main/resources/META-INF/tobago-config.xml  |   5 +
 .../src/main/ts/tobago-all.ts                      |   1 +
 .../src/main/ts/tobago-select-list-base.ts         | 230 ++++++++++++++++++
 .../src/main/ts/tobago-select-many-list.ts         | 238 +++----------------
 .../src/main/ts/tobago-select-one-list.ts          | 171 ++++++++++++++
 14 files changed, 1125 insertions(+), 337 deletions(-)

diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/component/RendererTypes.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/component/RendererTypes.java
index d77b7b1c31..df34cb4c5b 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/component/RendererTypes.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/component/RendererTypes.java
@@ -73,6 +73,7 @@ public enum RendererTypes {
   SelectManyShuttle,
   SelectOneChoice,
   SelectOneRadio,
+  SelectOneList,
   SelectOneListbox,
   SelectReference,
   Separator,
@@ -147,6 +148,7 @@ public enum RendererTypes {
   public static final String SELECT_MANY_SHUTTLE = "SelectManyShuttle";
   public static final String SELECT_ONE_CHOICE = "SelectOneChoice";
   public static final String SELECT_ONE_RADIO = "SelectOneRadio";
+  public static final String SELECT_ONE_LIST = "SelectOneList";
   public static final String SELECT_ONE_LISTBOX = "SelectOneListbox";
   public static final String SELECT_REFERENCE = "SelectReference";
   public static final String SEPARATOR = "Separator";
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/component/Tags.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/component/Tags.java
index 9b6050a801..eb2624ec9b 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/component/Tags.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/component/Tags.java
@@ -80,6 +80,7 @@ public enum Tags {
   selectManyShuttle,
   selectOneChoice,
   selectOneRadio,
+  selectOneList,
   selectOneListbox,
   selectReference,
   separator,
@@ -153,6 +154,7 @@ public enum Tags {
   public static final String SELECT_MANY_SHUTTLE = "selectManyShuttle";
   public static final String SELECT_ONE_CHOICE = "selectOneChoice";
   public static final String SELECT_ONE_RADIO = "selectOneRadio";
+  public static final String SELECT_ONE_LIST = "selectOneList";
   public static final String SELECT_ONE_LISTBOX = "selectOneListbox";
   public static final String SELECT_REFERENCE = "selectReference";
   public static final String SEPARATOR = "separator";
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUISelectOneList.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUISelectOneList.java
new file mode 100644
index 0000000000..5ae6226f3f
--- /dev/null
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUISelectOneList.java
@@ -0,0 +1,36 @@
+/*
+ * 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.component;
+
+import jakarta.faces.context.FacesContext;
+import org.apache.myfaces.tobago.component.SupportFieldId;
+import org.apache.myfaces.tobago.util.ComponentUtils;
+
+public abstract class AbstractUISelectOneList extends AbstractUISelectOneBase implements SupportFieldId {
+
+  @Override
+  public String getFieldId(final FacesContext facesContext) {
+    return getClientId(facesContext) + ComponentUtils.SUB_SEPARATOR + "field";
+  }
+
+  public abstract String getFilter();
+
+  public abstract boolean isExpanded();
+}
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectOneListRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectOneListRenderer.java
new file mode 100644
index 0000000000..b68bf488b6
--- /dev/null
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SelectOneListRenderer.java
@@ -0,0 +1,212 @@
+/*
+ * 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.renderkit.renderer;
+
+import jakarta.faces.context.FacesContext;
+import jakarta.faces.model.SelectItem;
+import org.apache.myfaces.tobago.internal.component.AbstractUISelectOneList;
+import org.apache.myfaces.tobago.internal.util.HtmlRendererUtils;
+import org.apache.myfaces.tobago.internal.util.SelectItemUtils;
+import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
+import org.apache.myfaces.tobago.renderkit.css.CssItem;
+import org.apache.myfaces.tobago.renderkit.css.TobagoClass;
+import org.apache.myfaces.tobago.renderkit.html.Arias;
+import org.apache.myfaces.tobago.renderkit.html.CustomAttributes;
+import org.apache.myfaces.tobago.renderkit.html.DataAttributes;
+import org.apache.myfaces.tobago.renderkit.html.HtmlAttributes;
+import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
+import org.apache.myfaces.tobago.renderkit.html.HtmlInputTypes;
+import org.apache.myfaces.tobago.util.ComponentUtils;
+import org.apache.myfaces.tobago.webapp.TobagoResponseWriter;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+public class SelectOneListRenderer<T extends AbstractUISelectOneList> extends SelectOneRendererBase<T> {
+
+  @Override
+  protected void encodeBeginField(FacesContext facesContext, T component) throws IOException {
+    final TobagoResponseWriter writer = getResponseWriter(facesContext);
+
+    final String clientId = component.getClientId(facesContext);
+    final String fieldId = component.getFieldId(facesContext);
+    final String filterId = clientId + ComponentUtils.SUB_SEPARATOR + "filter";
+    final String selectedId = clientId + ComponentUtils.SUB_SEPARATOR + "selected";
+    final List<SelectItem> items = SelectItemUtils.getItemList(facesContext, component);
+    final boolean disabled = !items.iterator().hasNext() || component.isDisabled() || component.isReadonly();
+    final String filter = component.getFilter();
+    final boolean expanded = component.isExpanded();
+    final String title = HtmlRendererUtils.getTitleFromTipAndMessages(facesContext, component);
+    final Integer tabIndex = component.getTabIndex();
+
+    encodeHiddenSelect(facesContext, component, items, clientId, selectedId, disabled);
+
+    writer.startElement(HtmlElements.DIV);
+    writer.writeClassAttribute(
+        expanded ? BootstrapClass.LIST_GROUP : BootstrapClass.DROPDOWN,
+        expanded ? BootstrapClass.borderColor(ComponentUtils.getMaximumSeverity(component)) : null);
+
+    encodeSelectField(facesContext, component,
+        clientId, fieldId, filterId, filter, disabled, expanded, title, tabIndex);
+    encodeOptions(facesContext, component, items, clientId, expanded, disabled);
+
+    writer.endElement(HtmlElements.DIV);
+  }
+
+  private void encodeHiddenSelect(
+      final FacesContext facesContext, final T component, final List<SelectItem> items,
+      final String clientId, final String selectedId, final boolean disabled) throws IOException {
+    final TobagoResponseWriter writer = getResponseWriter(facesContext);
+
+    writer.startElement(HtmlElements.SELECT);
+    writer.writeIdAttribute(selectedId);
+    writer.writeNameAttribute(clientId);
+    writer.writeAttribute(HtmlAttributes.DISABLED, disabled);
+    writer.writeAttribute(HtmlAttributes.REQUIRED, component.isRequired());
+    writer.writeClassAttribute(BootstrapClass.D_NONE);
+
+    final String submittedValue = (String) component.getSubmittedValue();
+    renderSelectItems(component, null, items, component.getValue(), submittedValue, writer, facesContext);
+    writer.endElement(HtmlElements.SELECT);
+  }
+
+  private void encodeSelectField(
+      final FacesContext facesContext, final T component,
+      final String clientId, final String fieldId, final String filterId, final String filter, final boolean disabled,
+      final boolean expanded, final String title, final Integer tabIndex) throws IOException {
+    final TobagoResponseWriter writer = getResponseWriter(facesContext);
+
+    writer.startElement(HtmlElements.DIV);
+    writer.writeIdAttribute(fieldId);
+    writer.writeNameAttribute(clientId);
+    HtmlRendererUtils.writeDataAttributes(facesContext, writer, component);
+    writer.writeClassAttribute(
+        expanded ? BootstrapClass.FORM_CONTROL : BootstrapClass.FORM_SELECT,
+        TobagoClass.SELECT__FIELD,
+        expanded ? BootstrapClass.LIST_GROUP_ITEM : BootstrapClass.DROPDOWN_TOGGLE,
+        expanded ? null : BootstrapClass.borderColor(ComponentUtils.getMaximumSeverity(component)),
+        component.getCustomClass());
+    writer.writeAttribute(HtmlAttributes.TITLE, title, true);
+    writer.writeAttribute(Arias.EXPANDED, Boolean.FALSE.toString(), false);
+    writer.writeAttribute(HtmlAttributes.DISABLED, disabled);
+
+    writer.startElement(HtmlElements.SPAN);
+    writer.endElement(HtmlElements.SPAN);
+
+    writer.startElement(HtmlElements.INPUT);
+    writer.writeAttribute(HtmlAttributes.TYPE, HtmlInputTypes.TEXT);
+    writer.writeIdAttribute(filterId);
+    writer.writeClassAttribute(TobagoClass.FILTER, BootstrapClass.FORM_CONTROL);
+    writer.writeAttribute(HtmlAttributes.AUTOCOMPLETE, "off", false);
+    writer.writeAttribute(HtmlAttributes.READONLY, filter == null || filter.isEmpty());
+    writer.writeAttribute(HtmlAttributes.DISABLED, disabled);
+    writer.writeAttribute(HtmlAttributes.TABINDEX, tabIndex);
+    renderFocus(clientId, component.isFocus(), component.isError(), facesContext, writer);
+
+    writer.endElement(HtmlElements.INPUT);
+
+    writer.endElement(HtmlElements.DIV);
+  }
+
+  private void encodeOptions(
+      final FacesContext facesContext, final T component, final List<SelectItem> items,
+      final String clientId, final boolean expanded, final boolean disabled) throws IOException {
+    final TobagoResponseWriter writer = getResponseWriter(facesContext);
+
+    writer.startElement(HtmlElements.DIV);
+    writer.writeClassAttribute(
+        TobagoClass.OPTIONS,
+        expanded ? BootstrapClass.LIST_GROUP_ITEM : BootstrapClass.DROPDOWN_MENU);
+    writer.writeNameAttribute(clientId);
+
+    writer.startElement(HtmlElements.TABLE);
+    writer.writeClassAttribute(BootstrapClass.TABLE, BootstrapClass.TABLE_HOVER, BootstrapClass.TABLE_SM);
+    writer.startElement(HtmlElements.TBODY);
+
+    final Object value = component.getValue();
+    final Object submittedValue = component.getSubmittedValue();
+    for (SelectItem item : items) {
+      Object itemValue = item.getValue();
+      // when using selectItem tag with a literal value: use the converted value
+      if (itemValue instanceof String && value != null && !(value instanceof String)) {
+        itemValue = ComponentUtils.getConvertedValue(facesContext, component, (String) itemValue);
+      }
+      final String formattedValue = getFormattedValue(facesContext, (T) component, itemValue);
+      final boolean contains;
+      if (submittedValue != null) {
+        contains = submittedValue.equals(formattedValue);
+      } else {
+        contains = value != null && value.equals(itemValue);
+      }
+      writer.startElement(HtmlElements.TR);
+      writer.writeAttribute(DataAttributes.VALUE, formattedValue, true);
+      writer.writeClassAttribute(
+          contains ? BootstrapClass.TABLE_PRIMARY : null,
+          disabled || item.isDisabled() ? TobagoClass.DISABLED : null);
+
+      writer.startElement(HtmlElements.TD);
+      writer.writeAttribute(HtmlAttributes.VALUE, formattedValue, true);
+      writer.writeText(item.getLabel());
+      writer.endElement(HtmlElements.TD);
+      writer.endElement(HtmlElements.TR);
+    }
+
+    writer.endElement(HtmlElements.TBODY);
+    writer.endElement(HtmlElements.TABLE);
+    writer.endElement(HtmlElements.DIV);
+  }
+
+  @Override
+  protected void encodeEndField(FacesContext facesContext, T component) throws IOException {
+    final TobagoResponseWriter writer = getResponseWriter(facesContext);
+
+    encodeBehavior(writer, facesContext, component);
+  }
+
+  @Override
+  public HtmlElements getComponentTag() {
+    return HtmlElements.TOBAGO_SELECT_ONE_LIST;
+  }
+
+  @Override
+  protected CssItem[] getComponentCss(final FacesContext facesContext, final T component) {
+    final List<SelectItem> items = SelectItemUtils.getItemList(facesContext, component);
+    final boolean disabled = !items.iterator().hasNext() || component.isDisabled() || component.isReadonly();
+
+    List<CssItem> cssItems = new ArrayList<>();
+    if (disabled) {
+      cssItems.add(TobagoClass.DISABLED);
+    }
+    return cssItems.toArray(new CssItem[0]);
+  }
+
+  @Override
+  protected void writeAdditionalAttributes(FacesContext facesContext, TobagoResponseWriter writer, T input)
+      throws IOException {
+    super.writeAdditionalAttributes(facesContext, writer, input);
+    writer.writeAttribute(CustomAttributes.FILTER, input.getFilter(), true);
+  }
+
+  @Override
+  protected String getFieldId(FacesContext facesContext, T component) {
+    return component.getFieldId(facesContext);
+  }
+}
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectOneListTagDeclaration.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectOneListTagDeclaration.java
new file mode 100644
index 0000000000..7f7c01959b
--- /dev/null
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SelectOneListTagDeclaration.java
@@ -0,0 +1,77 @@
+/*
+ * 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.component;
+
+import jakarta.faces.component.UISelectMany;
+import org.apache.myfaces.tobago.apt.annotation.Behavior;
+import org.apache.myfaces.tobago.apt.annotation.Preliminary;
+import org.apache.myfaces.tobago.apt.annotation.Tag;
+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.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;
+import org.apache.myfaces.tobago.internal.taglib.declaration.HasDecorationPosition;
+import org.apache.myfaces.tobago.internal.taglib.declaration.HasFilter;
+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.HasRequiredMessageForSelect;
+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.HasValue;
+import org.apache.myfaces.tobago.internal.taglib.declaration.HasValueChangeListener;
+import org.apache.myfaces.tobago.internal.taglib.declaration.IsDisabled;
+import org.apache.myfaces.tobago.internal.taglib.declaration.IsExpanded;
+import org.apache.myfaces.tobago.internal.taglib.declaration.IsFocus;
+import org.apache.myfaces.tobago.internal.taglib.declaration.IsReadonly;
+import org.apache.myfaces.tobago.internal.taglib.declaration.IsRendered;
+import org.apache.myfaces.tobago.internal.taglib.declaration.IsRequiredForSelect;
+import org.apache.myfaces.tobago.internal.taglib.declaration.IsVisual;
+
+/**
+ * Render a single selection option list.
+ */
+@Preliminary
+@Tag(name = "selectOneList")
+@UIComponentTag(
+    uiComponent = "org.apache.myfaces.tobago.component.UISelectOneList",
+    uiComponentFacesClass = "jakarta.faces.component.UISelectOne",
+    componentFamily = UISelectMany.COMPONENT_FAMILY,
+    rendererType = RendererTypes.SELECT_ONE_LIST,
+    allowedChildComponenents = {"jakarta.faces.SelectItem", "jakarta.faces.SelectItems"},
+    behaviors = {
+        @Behavior(name = ClientBehaviors.CHANGE, isDefault = true),
+        @Behavior(name = ClientBehaviors.INPUT),
+        @Behavior(name = ClientBehaviors.CLICK),
+        @Behavior(name = ClientBehaviors.DBLCLICK),
+        @Behavior(name = ClientBehaviors.FOCUS),
+        @Behavior(name = ClientBehaviors.BLUR)})
+public interface SelectOneListTagDeclaration
+    extends HasId, IsDisabled, IsRendered, HasBinding, HasTip, HasHelp, IsReadonly, HasConverter, IsRequiredForSelect,
+    HasLabel, HasValidator, HasValue, HasValueChangeListener, HasLabelLayout, HasValidatorMessage, HasConverterMessage,
+    HasRequiredMessageForSelect, HasTabIndex, IsFocus, IsVisual, HasAutoSpacing, HasFilter, IsExpanded,
+    HasDecorationPosition {
+}
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/html/HtmlElements.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/html/HtmlElements.java
index 727dc64f3d..253a13f0f5 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/html/HtmlElements.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/html/HtmlElements.java
@@ -176,6 +176,7 @@ public enum HtmlElements {
   TOBAGO_SELECT_MANY_LISTBOX("tobago-select-many-listbox"),
   TOBAGO_SELECT_MANY_SHUTTLE("tobago-select-many-shuttle"),
   TOBAGO_SELECT_ONE_CHOICE("tobago-select-one-choice"),
+  TOBAGO_SELECT_ONE_LIST("tobago-select-one-list"),
   TOBAGO_SELECT_ONE_LISTBOX("tobago-select-one-listbox"),
   TOBAGO_SELECT_ONE_RADIO("tobago-select-one-radio"),
   TOBAGO_SEPARATOR("tobago-separator"),
diff --git a/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/SelectOneListController.java b/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/SelectOneListController.java
new file mode 100644
index 0000000000..25f2e1f7ca
--- /dev/null
+++ b/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/SelectOneListController.java
@@ -0,0 +1,138 @@
+/*
+ * 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.annotation.PostConstruct;
+import jakarta.enterprise.context.SessionScoped;
+import jakarta.faces.application.FacesMessage;
+import jakarta.faces.context.FacesContext;
+import jakarta.inject.Inject;
+import jakarta.inject.Named;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.io.Serializable;
+import java.lang.invoke.MethodHandles;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.List;
+
+@SessionScoped
+@Named
+public class SelectOneListController implements Serializable {
+
+  private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+
+  @Inject
+  private AstroData astroData;
+
+  private List<SolarObject> planets;
+  private SolarObject selected1;
+  private SolarObject selected2;
+  private SolarObject selected3;
+  private SolarObject selected4;
+  private List<String> names;
+  private String selected5;
+
+  private String filterType;
+
+  @PostConstruct
+  public void init() {
+    planets = astroData.getSatellites("Sun");
+
+    names = new ArrayList<>();
+    try (BufferedReader reader = new BufferedReader(new InputStreamReader(
+        Thread.currentThread().getContextClassLoader().getResourceAsStream(
+            "org/apache/myfaces/tobago/example/demo/names.txt"), StandardCharsets.UTF_8))) {
+      String line;
+      while ((line = reader.readLine()) != null) {
+        line = line.trim();
+        if (!line.startsWith("#") && line.length() > 0) {
+          names.add(line);
+        }
+      }
+    } catch (Exception e) {
+      LOG.error("Can't load names", e);
+    }
+  }
+
+  public List<SolarObject> getPlanets() {
+    return planets;
+  }
+
+  public SolarObject getSelected1() {
+    return selected1;
+  }
+
+  public void setSelected1(SolarObject selected1) {
+    this.selected1 = selected1;
+  }
+
+  public SolarObject getSelected2() {
+    return selected2;
+  }
+
+  public void setSelected2(SolarObject selected2) {
+    this.selected2 = selected2;
+  }
+
+  public SolarObject getSelected3() {
+    return selected3;
+  }
+
+  public void setSelected3(SolarObject selected3) {
+    this.selected3 = selected3;
+  }
+
+  public SolarObject getSelected4() {
+    return selected4;
+  }
+
+  public void setSelected4(SolarObject selected4) {
+    this.selected4 = selected4;
+  }
+
+  public List<String> getNames() {
+    if (names.size() < 1) {
+      FacesContext.getCurrentInstance().addMessage(null,
+          new FacesMessage(FacesMessage.SEVERITY_ERROR, "Names not loaded!", null));
+      return new ArrayList<>();
+    }
+    return names;
+  }
+
+  public String getSelected5() {
+    return selected5;
+  }
+
+  public void setSelected5(String selected5) {
+    this.selected5 = selected5;
+  }
+
+  public String getFilterType() {
+    return filterType;
+  }
+
+  public void setFilterType(String filterType) {
+    this.filterType = filterType;
+  }
+}
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/030-select/45-selectOneList/SelectOneList.xhtml b/tobago-example/tobago-example-demo/src/main/webapp/content/030-select/45-selectOneList/SelectOneList.xhtml
new file mode 100644
index 0000000000..1798beb163
--- /dev/null
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/030-select/45-selectOneList/SelectOneList.xhtml
@@ -0,0 +1,87 @@
+<?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"
+                xmlns:f="http://xmlns.jcp.org/jsf/core">
+
+  <!-- todo -->
+  <tc:badge markup="warning"
+            value="Preliminary feature, may be subject to change!"/><br/>
+
+  <tc:section label="not expanded / no filter">
+    <tc:selectOneList id="selected1" value="#{selectOneListController.selected1}">
+      <tc:selectItems value="#{selectOneListController.planets}"
+                      var="planet" itemLabel="#{planet.name}" itemValue="#{planet}"/>
+    </tc:selectOneList>
+  </tc:section>
+
+  <tc:section label="expanded / no filter">
+    <tc:selectOneList id="selected2" value="#{selectOneListController.selected2}" expanded="true">
+      <tc:selectItems value="#{selectOneListController.planets}"
+                      var="planet" itemLabel="#{planet.name}" itemValue="#{planet}"/>
+    </tc:selectOneList>
+    <tc:button label="Submit"/>
+  </tc:section>
+
+  <tc:section label="not expanded / with filter">
+    <tc:selectOneList id="selected3" value="#{selectOneListController.selected3}" filter="contains">
+      <tc:selectItems value="#{selectOneListController.planets}"
+                      var="planet" itemLabel="#{planet.name}" itemValue="#{planet}"/>
+    </tc:selectOneList>
+    <tc:button label="Submit"/>
+  </tc:section>
+
+  <tc:section label="expanded / with filter:">
+    <tc:selectOneList id="selected4" value="#{selectOneListController.selected4}" filter="contains" expanded="true">
+      <tc:selectItems value="#{selectOneListController.planets}"
+                      var="planet" itemLabel="#{planet.name}" itemValue="#{planet}"/>
+    </tc:selectOneList>
+    <tc:button label="Submit"/>
+  </tc:section>
+
+  <tc:section id="filter" label="Filter types: contains, startsWith, containsExact, startsWithExact">
+    <tc:selectOneRadio label="Filter type" value="#{selectOneListController.filterType}">
+      <tc:selectItem itemValue="#{null}" itemLabel="please select"/>
+      <tc:selectItem itemValue="contains"/>
+      <tc:selectItem itemValue="startsWith"/>
+      <tc:selectItem itemValue="containsExact"/>
+      <tc:selectItem itemValue="startsWithExact"/>
+      <f:ajax render="filter" execute="filter"/>
+    </tc:selectOneRadio>
+    <tc:selectOneList id="selected5" value="#{selectOneListController.selected5}"
+                       filter="#{selectOneListController.filterType}" expanded="true">
+      <tc:selectItems value="#{selectOneListController.names}"
+                      var="name" itemLabel="#{name}" itemValue="#{name}"/>
+      <tc:style maxHeight="300px"/>
+    </tc:selectOneList>
+
+    Dependent of the type of the filter:
+    Ignores case.
+    Ignores acute (é), grave (è), circumflex (â, î or ô), tilde (ñ), umlaut and
+    dieresis (ü or ï), and cedilla (ç).
+  </tc:section>
+
+  <tc:section label="Filter types: custom">
+    todo
+  </tc:section>
+
+</ui:composition>
diff --git a/tobago-theme/src/main/scss/_tobago.scss b/tobago-theme/src/main/scss/_tobago.scss
index a050c989e5..3440fae36c 100644
--- a/tobago-theme/src/main/scss/_tobago.scss
+++ b/tobago-theme/src/main/scss/_tobago.scss
@@ -195,6 +195,137 @@ $form-select-disabled-color: rgba($form-select-color, $tobago-form-disabled-alph
   }
 }
 
+@mixin selectListBase() {
+  display: block;
+
+  &.tobago-label-container {
+    .dropdown, .list-group {
+      flex: 1 0 0;
+    }
+  }
+
+  &.tobago-focus {
+    .dropdown .tobago-select-field {
+      @include formControlFocus();
+      @include selectListBorderColorShadow("danger", $danger);
+      @include selectListBorderColorShadow("warning", $warning);
+      @include selectListBorderColorShadow("info", $info);
+    }
+
+    .list-group {
+      --bs-list-group-color: #{$input-focus-color};
+      --bs-list-group-bg: #{$input-focus-bg};
+      --bs-list-group-border-color: #{$input-focus-border-color};
+
+      @include formControlFocusShadows();
+      @include selectListBorderColorShadow("danger", $danger);
+      @include selectListBorderColorShadow("warning", $warning);
+      @include selectListBorderColorShadow("info", $info);
+    }
+  }
+
+  &.tobago-disabled {
+    .tobago-select-field {
+      color: $form-select-disabled-color;
+      background-color: $form-select-disabled-bg;
+      border-color: $form-select-disabled-border-color;
+    }
+  }
+
+  .list-group {
+    height: inherit;
+    max-height: inherit;
+    @include box-shadow($form-select-box-shadow);
+    @include transition($form-select-transition);
+
+    &.border-danger, &.border-warning, &.border-info {
+      .list-group-item {
+        border-color: inherit;
+      }
+    }
+
+    .list-group-item.tobago-select-field {
+      border-bottom-color: $list-group-border-color;
+    }
+  }
+
+  .tobago-select-field {
+    display: flex;
+    flex-wrap: wrap;
+    align-items: center;
+
+    &.dropdown-toggle::after {
+      content: none;
+    }
+
+    &.list-group-item.form-control {
+      border-bottom-left-radius: 0;
+      border-bottom-right-radius: 0;
+
+      padding: $form-select-padding-y $form-select-indicator-padding $form-select-padding-y $form-select-padding-x;
+    }
+
+    .tobago-filter {
+      margin: 0;
+      border: 0;
+      border-radius: 0;
+      padding: 0;
+      flex: 1 0 0;
+      min-width: 8rem;
+      background-color: transparent;
+
+      &:focus {
+        box-shadow: none;
+      }
+
+      &:read-only {
+        width: 0;
+        min-width: 0;
+      }
+    }
+  }
+
+  .tobago-options {
+    &.list-group-item {
+      padding: 0;
+      overflow-y: auto;
+    }
+
+    .table {
+      margin-bottom: 0;
+
+      tr {
+        cursor: pointer;
+
+        &.tobago-disabled {
+          color: $form-select-disabled-color;
+          background-color: $form-select-disabled-bg;
+          border-color: $form-select-disabled-border-color;
+          cursor: initial;
+          pointer-events: none;
+        }
+
+        &.tobago-preselect {
+          --bs-table-accent-bg: var(--bs-table-hover-bg);
+          color: var(--bs-table-hover-color);
+        }
+
+        &:last-of-type {
+          td {
+            border-bottom-width: 0;
+          }
+        }
+      }
+    }
+  }
+}
+
+@mixin selectListBorderColorShadow($name, $color) {
+  &.border-#{$name} {
+    box-shadow: 0 0 $input-btn-focus-blur $input-focus-width rgba($color, $input-btn-focus-color-opacity);
+  }
+}
+
 @mixin tobagoTreeNodeToggle() {
   .tobago-toggle:not(.invisible) {
     cursor: pointer;
@@ -1194,6 +1325,10 @@ tobago-select-one-choice {
   }
 }
 
+tobago-select-one-list {
+  @include selectListBase();
+}
+
 tobago-select-one-listbox {
   display: block;
 
@@ -1216,81 +1351,9 @@ tobago-select-one-radio {
 }
 
 tobago-select-many-list {
-  display: block;
-
-  &.tobago-label-container {
-    .dropdown, .list-group {
-      flex: 1 0 0;
-    }
-  }
-
-  &.tobago-focus {
-    @mixin borderColorShadow($name, $color) {
-      &.border-#{$name} {
-        box-shadow: 0 0 $input-btn-focus-blur $input-focus-width rgba($color, $input-btn-focus-color-opacity);
-      }
-    }
-
-    .dropdown .tobago-select-field {
-      @include formControlFocus();
-      @include borderColorShadow("danger", $danger);
-      @include borderColorShadow("warning", $warning);
-      @include borderColorShadow("info", $info);
-    }
-
-    .list-group {
-      --bs-list-group-color: #{$input-focus-color};
-      --bs-list-group-bg: #{$input-focus-bg};
-      --bs-list-group-border-color: #{$input-focus-border-color};
-
-      @include formControlFocusShadows();
-      @include borderColorShadow("danger", $danger);
-      @include borderColorShadow("warning", $warning);
-      @include borderColorShadow("info", $info);
-    }
-  }
-
-  &.tobago-disabled {
-    .tobago-select-field {
-      color: $form-select-disabled-color;
-      background-color: $form-select-disabled-bg;
-      border-color: $form-select-disabled-border-color;
-    }
-  }
-
-  .list-group {
-    height: inherit;
-    max-height: inherit;
-    @include box-shadow($form-select-box-shadow);
-    @include transition($form-select-transition);
-
-    &.border-danger, &.border-warning, &.border-info {
-      .list-group-item {
-        border-color: inherit;
-      }
-    }
-
-    .list-group-item.tobago-select-field {
-      border-bottom-color: $list-group-border-color;
-    }
-  }
+  @include selectListBase();
 
   .tobago-select-field {
-    display: flex;
-    flex-wrap: wrap;
-    align-items: center;
-
-    &.dropdown-toggle::after {
-      content: none;
-    }
-
-    &.list-group-item.form-control {
-      border-bottom-left-radius: 0;
-      border-bottom-right-radius: 0;
-
-      padding: $form-select-padding-y $form-select-indicator-padding $form-select-padding-y $form-select-padding-x;
-    }
-
     .btn-group + .tobago-filter {
       margin-left: 0.25rem;
     }
@@ -1298,59 +1361,6 @@ tobago-select-many-list {
     .btn-group {
       margin-right: 0.25rem;
     }
-
-    .tobago-filter {
-      margin: 0;
-      border: 0;
-      border-radius: 0;
-      padding: 0;
-      flex: 1 0 0;
-      min-width: 8rem;
-      background-color: transparent;
-
-      &:focus {
-        box-shadow: none;
-      }
-
-      &:read-only {
-        width: 0;
-        min-width: 0;
-      }
-    }
-  }
-
-  .tobago-options {
-    &.list-group-item {
-      padding: 0;
-      overflow-y: auto;
-    }
-
-    .table {
-      margin-bottom: 0;
-
-      tr {
-        cursor: pointer;
-
-        &.tobago-disabled {
-          color: $form-select-disabled-color;
-          background-color: $form-select-disabled-bg;
-          border-color: $form-select-disabled-border-color;
-          cursor: initial;
-          pointer-events: none;
-        }
-
-        &.tobago-preselect {
-          --bs-table-accent-bg: var(--bs-table-hover-bg);
-          color: var(--bs-table-hover-color);
-        }
-
-        &:last-of-type {
-          td {
-            border-bottom-width: 0;
-          }
-        }
-      }
-    }
   }
 }
 
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 1d41a5a942..cd5ab25166 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
@@ -113,6 +113,11 @@
           <attribute name="messagePosition" default="buttonRight"/>
           <attribute name="helpPosition" default="buttonRight"/>
         </tag>
+        <tag name="selectOneList">
+          <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"/>
diff --git a/tobago-theme/tobago-theme-standard/src/main/ts/tobago-all.ts b/tobago-theme/tobago-theme-standard/src/main/ts/tobago-all.ts
index d9f7acd722..2addc09525 100644
--- a/tobago-theme/tobago-theme-standard/src/main/ts/tobago-all.ts
+++ b/tobago-theme/tobago-theme-standard/src/main/ts/tobago-all.ts
@@ -41,6 +41,7 @@ import "./tobago-select-many-checkbox";
 import "./tobago-select-many-listbox";
 import "./tobago-select-many-shuttle";
 import "./tobago-select-one-choice";
+import "./tobago-select-one-list";
 import "./tobago-select-one-listbox";
 import "./tobago-select-one-radio";
 import "./tobago-sheet";
diff --git a/tobago-theme/tobago-theme-standard/src/main/ts/tobago-select-list-base.ts b/tobago-theme/tobago-theme-standard/src/main/ts/tobago-select-list-base.ts
new file mode 100644
index 0000000000..6059a0026f
--- /dev/null
+++ b/tobago-theme/tobago-theme-standard/src/main/ts/tobago-select-list-base.ts
@@ -0,0 +1,230 @@
+/*
+ * 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.
+ */
+
+import {createPopper, Instance} from "@popperjs/core";
+
+export class SelectListBase extends HTMLElement {
+  protected readonly CssClass = {
+    D_NONE: "d-none",
+    DROPDOWN_MENU: "dropdown-menu",
+    SHOW: "show",
+    TABLE_ACTIVE: "table-active",
+    TABLE_PRIMARY: "table-primary",
+    TOBAGO_DISABLED: "tobago-disabled",
+    TOBAGO_FOCUS: "tobago-focus",
+    TOBAGO_PRESELECT: "tobago-preselect",
+    TOBAGO_OPTIONS: "tobago-options"
+  };
+
+  protected readonly Key = {
+    ARROW_DOWN: "ArrowDown",
+    ARROW_UP: "ArrowUp",
+    BACKSPACE: "Backspace",
+    ENTER: "Enter",
+    ESCAPE: "Escape",
+    SPACE: " ",
+    TAB: "Tab"
+  };
+
+  private popper: Instance;
+
+  get disabled(): boolean {
+    return this.classList.contains(this.CssClass.TOBAGO_DISABLED);
+  }
+
+  get hiddenSelect(): HTMLSelectElement {
+    return this.querySelector("select");
+  }
+
+  get hiddenOptions(): NodeListOf<HTMLOptionElement> {
+    return this.hiddenSelect.querySelectorAll<HTMLOptionElement>("option");
+  }
+
+  get selectField(): HTMLDivElement {
+    return this.querySelector(".tobago-select-field");
+  }
+
+  get filter(): string {
+    return this.getAttribute("filter");
+  }
+
+  get filterEnabled(): boolean {
+    return this.filter?.length > 0;
+  }
+
+  get filterInput(): HTMLInputElement {
+    return this.querySelector(".tobago-filter");
+  }
+
+  get dropdownMenu(): HTMLDivElement {
+    const root = this.getRootNode() as ShadowRoot | Document;
+    return root.querySelector(`.dropdown-menu[name='${this.id}']`);
+  }
+
+  get menuStore(): HTMLDivElement {
+    const root = this.getRootNode() as ShadowRoot | Document;
+    return root.querySelector(".tobago-page-menuStore");
+  }
+
+  get tbody(): HTMLElement {
+    const root = this.getRootNode() as ShadowRoot | Document;
+    return root.querySelector(`.tobago-options[name='${this.id}'] tbody`);
+  }
+
+  get rows(): NodeListOf<HTMLTableRowElement> {
+    return this.tbody.querySelectorAll<HTMLTableRowElement>("tr");
+  }
+
+  get enabledRows(): NodeListOf<HTMLTableRowElement> {
+    return this.tbody.querySelectorAll<HTMLTableRowElement>("tr:not(." + this.CssClass.D_NONE + ")");
+  }
+
+  get preselectedRow(): HTMLTableRowElement {
+    return this.tbody.querySelector<HTMLTableRowElement>("." + this.CssClass.TOBAGO_PRESELECT);
+  }
+
+  connectedCallback(): void {
+    if (this.dropdownMenu) {
+      this.popper = createPopper(this.selectField, this.dropdownMenu, {});
+      window.addEventListener("resize", this.resizeEvent.bind(this));
+    }
+  }
+
+  protected focusEvent(): void {
+    if (!this.hiddenSelect.disabled) {
+      if (!this.classList.contains(this.CssClass.TOBAGO_FOCUS)) {
+        this.setFocus(true);
+      }
+    }
+  }
+
+  protected setFocus(focus: boolean): void {
+    if (focus) {
+      this.classList.add(this.CssClass.TOBAGO_FOCUS);
+    } else {
+      this.classList.remove(this.CssClass.TOBAGO_FOCUS);
+    }
+  }
+
+  protected preselectNextTableRow(): void {
+    const rows = this.enabledRows;
+    const index = this.preselectIndex(rows);
+    if (index >= 0) {
+      if (index + 1 < rows.length) {
+        rows.item(index).classList.remove(this.CssClass.TOBAGO_PRESELECT);
+        this.preselect(rows.item(index + 1));
+      } else {
+        rows.item(rows.length - 1).classList.remove(this.CssClass.TOBAGO_PRESELECT);
+        this.preselect(rows.item(0));
+      }
+    } else if (rows.length > 0) {
+      this.preselect(rows.item(0));
+    }
+  }
+
+  protected preselectPreviousTableRow(): void {
+    const rows = this.enabledRows;
+    const index = this.preselectIndex(rows);
+    if (index >= 0) {
+      if ((index - 1) >= 0) {
+        rows.item(index).classList.remove(this.CssClass.TOBAGO_PRESELECT);
+        this.preselect(rows.item(index - 1));
+      } else {
+        rows.item(0).classList.remove(this.CssClass.TOBAGO_PRESELECT);
+        this.preselect(rows.item(rows.length - 1));
+      }
+    } else if (rows.length > 0) {
+      this.preselect(rows.item(rows.length - 1));
+    }
+  }
+
+  protected removePreselection(): void {
+    this.preselectedRow?.classList.remove(this.CssClass.TOBAGO_PRESELECT);
+  }
+
+  protected isPartOfSelectField(element: Element): boolean {
+    if (element) {
+      if (this.selectField.id === element.id) {
+        return true;
+      } else {
+        return element.parentElement ? this.isPartOfSelectField(element.parentElement) : false;
+      }
+    } else {
+      return false;
+    }
+  }
+
+  protected isPartOfTobagoOptions(element: Element): boolean {
+    if (element) {
+      if (element.classList.contains(this.CssClass.TOBAGO_OPTIONS)
+          && this.id === element.getAttribute("name")) {
+        return true;
+      } else {
+        return element.parentElement ? this.isPartOfTobagoOptions(element.parentElement) : false;
+      }
+    } else {
+      return false;
+    }
+  }
+
+  protected showDropdown(): void {
+    if (this.dropdownMenu && !this.dropdownMenu.classList.contains(this.CssClass.SHOW)) {
+      this.selectField.classList.add(this.CssClass.SHOW);
+      this.selectField.ariaExpanded = "true";
+      this.dropdownMenu.classList.add(this.CssClass.SHOW);
+      this.updateDropdownMenuWidth();
+      this.popper.update();
+    }
+  }
+
+  protected hideDropdown(): void {
+    if (this.dropdownMenu?.classList.contains(this.CssClass.SHOW)) {
+      this.selectField.classList.remove(this.CssClass.SHOW);
+      this.selectField.ariaExpanded = "false";
+      this.dropdownMenu.classList.remove(this.CssClass.SHOW);
+    }
+  }
+
+  private preselect(row: HTMLTableRowElement): void {
+    row.classList.add(this.CssClass.TOBAGO_PRESELECT);
+    if (!this.dropdownMenu) {
+      row.scrollIntoView({block: "center"});
+    }
+
+    this.filterInput.disabled = false;
+    this.filterInput.focus({preventScroll: true});
+  }
+
+  private preselectIndex(rows: NodeListOf<HTMLTableRowElement>): number {
+    for (let i = 0; i < rows.length; i++) {
+      if (rows.item(i).classList.contains(this.CssClass.TOBAGO_PRESELECT)) {
+        return i;
+      }
+    }
+    return -1;
+  }
+
+  private resizeEvent(event: UIEvent): void {
+    this.updateDropdownMenuWidth();
+  }
+
+  private updateDropdownMenuWidth(): void {
+    if (this.dropdownMenu) {
+      this.dropdownMenu.style.width = `${this.selectField.offsetWidth}px`;
+    }
+  }
+}
diff --git a/tobago-theme/tobago-theme-standard/src/main/ts/tobago-select-many-list.ts b/tobago-theme/tobago-theme-standard/src/main/ts/tobago-select-many-list.ts
index 8058b29db2..f92709d9ce 100644
--- a/tobago-theme/tobago-theme-standard/src/main/ts/tobago-select-many-list.ts
+++ b/tobago-theme/tobago-theme-standard/src/main/ts/tobago-select-many-list.ts
@@ -16,83 +16,19 @@
  */
 
 import {TobagoFilterRegistry} from "./tobago-filter-registry";
-import {createPopper, Instance} from "@popperjs/core";
-
-class SelectManyList extends HTMLElement {
-  private popper: Instance;
-
-  private readonly CssClass = {
-    DROPDOWN_MENU: "dropdown-menu",
-    SHOW: "show",
-    TABLE_ACTIVE: "table-active",
-    TABLE_PRIMARY: "table-primary",
-    TOBAGO_DISABLED: "tobago-disabled",
-    TOBAGO_FOCUS: "tobago-focus",
-    TOBAGO_PRESELECT: "tobago-preselect",
-    TOBAGO_OPTIONS: "tobago-options"
-  };
-
-  private readonly Key = {
-    ARROW_DOWN: "ArrowDown",
-    ARROW_UP: "ArrowUp",
-    ENTER: "Enter",
-    ESCAPE: "Escape",
-    SPACE: " ",
-    TAB: "Tab"
-  };
+import {SelectListBase} from "./tobago-select-list-base";
 
+class SelectManyList extends SelectListBase {
   constructor() {
     super();
   }
 
-  get hiddenSelect(): HTMLSelectElement {
-    return this.querySelector("select");
-  }
-
-  get selectField(): HTMLDivElement {
-    return this.querySelector(".tobago-select-field");
-  }
-
   get badgeCloseButtons(): NodeListOf<HTMLButtonElement> {
     return this.selectField.querySelectorAll("button.btn.badge");
   }
 
-  get filter(): string {
-    return this.getAttribute("filter");
-  }
-
-  get filterInput(): HTMLInputElement {
-    return this.querySelector(".tobago-filter");
-  }
-
-  get dropdownMenu(): HTMLDivElement {
-    const root = this.getRootNode() as ShadowRoot | Document;
-    return root.querySelector(`.dropdown-menu[name='${this.id}']`);
-  }
-
-  get menuStore(): HTMLDivElement {
-    const root = this.getRootNode() as ShadowRoot | Document;
-    return root.querySelector(".tobago-page-menuStore");
-  }
-
-  get tbody(): HTMLElement {
-    const root = this.getRootNode() as ShadowRoot | Document;
-    return root.querySelector(`.tobago-options[name='${this.id}'] tbody`);
-  }
-
-  get enabledRows(): NodeListOf<HTMLTableRowElement> {
-    return this.tbody.querySelectorAll<HTMLTableRowElement>("tr:not(.tobago-disabled)");
-  }
-
-  get preselectedRow(): HTMLTableRowElement {
-    return this.tbody.querySelector<HTMLTableRowElement>("." + this.CssClass.TOBAGO_PRESELECT);
-  }
-
   connectedCallback(): void {
-    if (this.dropdownMenu) {
-      this.popper = createPopper(this.selectField, this.dropdownMenu, {});
-      window.addEventListener("resize", this.resizeEvent.bind(this));
-    }
+    super.connectedCallback();
     document.addEventListener("click", this.clickEvent.bind(this));
     this.filterInput.addEventListener("focus", this.focusEvent.bind(this));
     this.filterInput.addEventListener("blur", this.blurEvent.bind(this));
@@ -105,10 +41,8 @@ class SelectManyList extends HTMLElement {
 
     this.initList();
 
-    // init filter
     if (this.filter) {
-      const input = this.filterInput;
-      input.addEventListener("keyup", this.filterEvent.bind(this));
+      this.filterInput.addEventListener("input", this.filterEvent.bind(this));
     }
 
     // handle autofocus; trigger focus event
@@ -179,7 +113,7 @@ class SelectManyList extends HTMLElement {
       row.classList.remove(this.CssClass.TABLE_PRIMARY);
     }
 
-    if (!this.classList.contains(this.CssClass.TOBAGO_DISABLED) && !this.filter) {
+    if (!this.disabled && !this.filter) {
       // disable input field to prevent focus.
       if (this.badgeCloseButtons.length > 0 && this.filterInput.id === document.activeElement.id) {
         this.badgeCloseButtons.item(this.badgeCloseButtons.length - 1).focus();
@@ -212,30 +146,31 @@ class SelectManyList extends HTMLElement {
       this.querySelectorAll("tr").forEach(row => {
         const itemValue = row.dataset.tobagoValue;
         if (filterFunction(itemValue, searchString)) {
-          row.classList.remove("d-none");
+          row.classList.remove(this.CssClass.D_NONE);
         } else {
-          row.classList.add("d-none");
+          row.classList.add(this.CssClass.D_NONE);
         }
       });
     }
   }
 
   private clickEvent(event: MouseEvent): void {
-    if (this.isDeleted(event.target as Element)) {
-      // do nothing, this is probably a removed badge
-    } else if (this.isPartOfSelectField(event.target as Element)
-        || this.isPartOfTobagoOptions(event.target as Element)) {
+    if (!this.disabled) {
+      if (this.isDeleted(event.target as Element)) {
+        // do nothing, this is probably a removed badge
+      } else if (this.isPartOfSelectField(event.target as Element)
+          || this.isPartOfTobagoOptions(event.target as Element)) {
+
+        if (!this.filterInput.disabled) {
+          this.filterInput.focus();
+        } else if (this.badgeCloseButtons.length > 0) {
+          this.badgeCloseButtons[0].focus();
+        }
+        this.showDropdown();
 
-      if (!this.filterInput.disabled) {
-        this.filterInput.focus();
-      } else if (this.badgeCloseButtons.length > 0) {
-        this.badgeCloseButtons[0].focus();
+      } else {
+        this.leaveComponent();
       }
-      this.showDropdown();
-
-    } else {
-      this.hideDropdown();
-      this.setFocus(false);
     }
   }
 
@@ -273,146 +208,27 @@ class SelectManyList extends HTMLElement {
     }
   }
 
-  private preselectNextTableRow(): void {
-    const rows = this.enabledRows;
-    const index = this.preselectIndex(rows);
-    if (index >= 0) {
-      if (index + 1 < rows.length) {
-        rows.item(index).classList.remove(this.CssClass.TOBAGO_PRESELECT);
-        this.preselect(rows.item(index + 1));
-      } else {
-        rows.item(rows.length - 1).classList.remove(this.CssClass.TOBAGO_PRESELECT);
-        this.preselect(rows.item(0));
-      }
-    } else if (rows.length > 0) {
-      this.preselect(rows.item(0));
-    }
-  }
-
-  private preselectPreviousTableRow(): void {
-    const rows = this.enabledRows;
-    const index = this.preselectIndex(rows);
-    if (index >= 0) {
-      if ((index - 1) >= 0) {
-        rows.item(index).classList.remove(this.CssClass.TOBAGO_PRESELECT);
-        this.preselect(rows.item(index - 1));
-      } else {
-        rows.item(0).classList.remove(this.CssClass.TOBAGO_PRESELECT);
-        this.preselect(rows.item(rows.length - 1));
-      }
-    } else if (rows.length > 0) {
-      this.preselect(rows.item(rows.length - 1));
-    }
-  }
-
-  private preselect(row: HTMLTableRowElement): void {
-    row.classList.add(this.CssClass.TOBAGO_PRESELECT);
-    if (!this.dropdownMenu) {
-      row.scrollIntoView({block: "center"});
-    }
-
-    this.filterInput.disabled = false;
-    this.filterInput.focus({preventScroll: true});
-  }
-
-  private removePreselection(): void {
-    this.preselectedRow?.classList.remove(this.CssClass.TOBAGO_PRESELECT);
-  }
-
-  private preselectIndex(rows: NodeListOf<HTMLTableRowElement>): number {
-    for (let i = 0; i < rows.length; i++) {
-      if (rows.item(i).classList.contains(this.CssClass.TOBAGO_PRESELECT)) {
-        return i;
-      }
-    }
-    return -1;
-  }
-
-  private isPartOfSelectField(element: Element): boolean {
-    if (element) {
-      if (this.selectField.id === element.id) {
-        return true;
-      } else {
-        return element.parentElement ? this.isPartOfSelectField(element.parentElement) : false;
-      }
-    } else {
-      return false;
-    }
-  }
-
-  private isPartOfTobagoOptions(element: Element): boolean {
-    if (element) {
-      if (element.classList.contains(this.CssClass.TOBAGO_OPTIONS)
-          && this.id === element.getAttribute("name")) {
-        return true;
-      } else {
-        return element.parentElement ? this.isPartOfTobagoOptions(element.parentElement) : false;
-      }
-    } else {
-      return false;
-    }
+  private leaveComponent(): void {
+    this.setFocus(false);
+    this.filterInput.value = null;
+    this.filterInput.dispatchEvent(new Event("input"));
+    this.hideDropdown();
   }
 
   private isDeleted(element: Element): boolean {
     return element.closest("html") === null;
   }
 
-  private showDropdown(): void {
-    if (this.dropdownMenu && !this.dropdownMenu.classList.contains(this.CssClass.SHOW)) {
-      this.selectField.classList.add(this.CssClass.SHOW);
-      this.selectField.ariaExpanded = "true";
-      this.dropdownMenu.classList.add(this.CssClass.SHOW);
-      this.updateDropdownMenuWidth();
-      this.popper.update();
-    }
-  }
-
-  private hideDropdown(): void {
-    if (this.dropdownMenu?.classList.contains(this.CssClass.SHOW)) {
-      this.selectField.classList.remove(this.CssClass.SHOW);
-      this.selectField.ariaExpanded = "false";
-      this.dropdownMenu.classList.remove(this.CssClass.SHOW);
-    }
-  }
-
-  private resizeEvent(event: UIEvent): void {
-    this.updateDropdownMenuWidth();
-  }
-
-  private updateDropdownMenuWidth(): void {
-    if (this.dropdownMenu) {
-      this.dropdownMenu.style.width = `${this.selectField.offsetWidth}px`;
-    }
-  }
-
-  private focusEvent(): void {
-    if (!this.hiddenSelect.disabled) {
-      if (!this.classList.contains(this.CssClass.TOBAGO_FOCUS)) {
-        this.setFocus(true);
-        this.showDropdown();
-      }
-    }
-  }
-
   private blurEvent(event: FocusEvent): void {
     if (event.relatedTarget !== null) {
       //relatedTarget is the new focused element; null indicate a mouseclick or an inactive browser window
       if (!this.isPartOfSelectField(event.relatedTarget as Element)
           && !this.isPartOfTobagoOptions(event.relatedTarget as Element)) {
-        this.setFocus(false);
-        this.hideDropdown();
+        this.leaveComponent();
       }
     }
   }
 
-  private setFocus(focus: boolean): void {
-    if (focus) {
-      this.classList.add(this.CssClass.TOBAGO_FOCUS);
-    } else {
-      this.classList.remove(this.CssClass.TOBAGO_FOCUS);
-    }
-  }
-
   private initList() {
     const tbody = this.tbody;
     tbody.addEventListener("click", this.select.bind(this));
diff --git a/tobago-theme/tobago-theme-standard/src/main/ts/tobago-select-one-list.ts b/tobago-theme/tobago-theme-standard/src/main/ts/tobago-select-one-list.ts
new file mode 100644
index 0000000000..39a65efed2
--- /dev/null
+++ b/tobago-theme/tobago-theme-standard/src/main/ts/tobago-select-one-list.ts
@@ -0,0 +1,171 @@
+/*
+ * 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.
+ */
+
+import {TobagoFilterRegistry} from "./tobago-filter-registry";
+import {SelectListBase} from "./tobago-select-list-base";
+
+class SelectOneList extends SelectListBase {
+  constructor() {
+    super();
+  }
+
+  get spanText(): string {
+    return this.selectField.querySelector("span").textContent;
+  }
+
+  set spanText(text: string) {
+    this.selectField.querySelector("span").textContent = text;
+  }
+
+  connectedCallback(): void {
+    super.connectedCallback();
+    document.addEventListener("click", this.clickEvent.bind(this));
+    this.filterInput.addEventListener("focus", this.focusEvent.bind(this));
+    this.filterInput.addEventListener("blur", this.blurEvent.bind(this));
+    this.selectField.addEventListener("keydown", this.keydownEvent.bind(this));
+    this.tbody.addEventListener("click", this.select.bind(this));
+
+    this.sync();
+
+    if (this.filter) {
+      this.filterInput.addEventListener("input", this.filterEvent.bind(this));
+    }
+
+    if (document.activeElement.id === this.filterInput.id) {
+      this.focusEvent();
+    }
+  }
+
+  select(event: MouseEvent): void {
+    const target = <HTMLElement>event.target;
+    const row = target.closest("tr");
+    this.selectRow(row);
+  }
+
+  selectRow(row: HTMLTableRowElement): void {
+    const itemValue = row.dataset.tobagoValue;
+    const select = this.hiddenSelect;
+    const option: HTMLOptionElement = select.querySelector(`[value="${itemValue}"]`);
+    option.selected = true;
+    this.filterInput.value = null;
+    this.sync();
+  }
+
+  sync() {
+    this.rows.forEach((row) => {
+      if (row.dataset.tobagoValue === this.hiddenSelect.value) {
+        this.spanText = this.hiddenSelect.value;
+        row.classList.add(this.CssClass.TABLE_PRIMARY); // highlight list row
+      } else {
+        row.classList.remove(this.CssClass.TABLE_PRIMARY); // remove highlight list row
+      }
+    });
+  }
+
+  filterEvent(event: Event): void {
+    const input = event.currentTarget as HTMLInputElement;
+    const searchString = input.value;
+    if (searchString !== null) {
+      this.spanText = null;
+      this.showDropdown();
+    }
+    const filterFunction = TobagoFilterRegistry.get(this.filter);
+    // XXX todo: if filterFunction not found?
+    if (filterFunction != null) {
+      this.querySelectorAll("tr").forEach(row => {
+        const itemValue = row.dataset.tobagoValue;
+        if (filterFunction(itemValue, searchString)) {
+          row.classList.remove(this.CssClass.D_NONE);
+        } else {
+          row.classList.add(this.CssClass.D_NONE);
+        }
+      });
+    }
+  }
+
+  private clickEvent(event: MouseEvent): void {
+    if (!this.disabled) {
+      if (this.isPartOfSelectField(event.target as Element) || this.isPartOfTobagoOptions(event.target as Element)) {
+        if (!this.filterInput.disabled) {
+          this.filterInput.focus();
+        }
+        this.showDropdown();
+      } else {
+        this.leaveComponent();
+      }
+    }
+  }
+
+  private keydownEvent(event: KeyboardEvent) {
+    switch (event.key) {
+      case this.Key.ESCAPE:
+        this.hideDropdown();
+        this.removePreselection();
+        break;
+      case this.Key.ARROW_DOWN:
+        event.preventDefault();
+        this.showDropdown();
+        this.preselectNextTableRow();
+        break;
+      case this.Key.ARROW_UP:
+        event.preventDefault();
+        this.showDropdown();
+        this.preselectPreviousTableRow();
+        break;
+      case this.Key.BACKSPACE:
+        if (this.filterInput.value.length === 0) {
+          this.spanText = null;
+          this.filterInput.dispatchEvent(new Event("input"));
+        }
+        break;
+      case this.Key.ENTER:
+      case this.Key.SPACE:
+        if (this.preselectedRow) {
+          event.preventDefault();
+          const row = this.tbody.querySelector<HTMLTableRowElement>("." + this.CssClass.TOBAGO_PRESELECT);
+          this.selectRow(row);
+        } else if (document.activeElement.id === this.filterInput.id) {
+          this.showDropdown();
+        }
+        break;
+    }
+  }
+
+  private leaveComponent(): void {
+    this.setFocus(false);
+    this.filterInput.value = null;
+    this.filterInput.dispatchEvent(new Event("input"));
+    this.spanText = this.hiddenSelect.value;
+    this.hideDropdown();
+  }
+
+  private blurEvent(event: FocusEvent): void {
+    if (event.relatedTarget !== null) {
+      //relatedTarget is the new focused element; null indicate a mouseclick or an inactive browser window
+      if (!this.isPartOfSelectField(event.relatedTarget as Element)
+          && !this.isPartOfTobagoOptions(event.relatedTarget as Element)) {
+        this.leaveComponent();
+      }
+    }
+  }
+}
+
+document.addEventListener("tobago.init", function (event: Event): void {
+  if (window.customElements.get("tobago-select-one-list") == null) {
+    window.customElements.define("tobago-select-one-list", SelectOneList);
+  }
+});


[myfaces-tobago] 03/03: build(theme): rebuild after implementing tc:selectOneMany

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 4b8156e14379b4289c14269826b43f33fb73737c
Author: Henning Noeth <hn...@apache.org>
AuthorDate: Fri Feb 10 21:31:18 2023 +0100

    build(theme): rebuild after implementing tc:selectOneMany
---
 .../src/main/css/tobago.css                        | 126 ++++++++++++++++++++-
 .../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                        | 126 ++++++++++++++++++++-
 .../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                        | 126 ++++++++++++++++++++-
 .../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  | 126 ++++++++++++++++++++-
 .../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  | 126 ++++++++++++++++++++-
 .../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/js/tobago.js    |   4 +-
 .../src/main/js/tobago.js.map                      |   2 +-
 22 files changed, 618 insertions(+), 48 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 bd71b7ba5d..f9af53b4f2 100644
--- a/tobago-theme/tobago-theme-charlotteville/src/main/css/tobago.css
+++ b/tobago-theme/tobago-theme-charlotteville/src/main/css/tobago.css
@@ -12011,6 +12011,120 @@ tobago-select-one-choice select:disabled {
   color: rgba(160, 160, 160, 0.5);
 }
 
+tobago-select-one-list {
+  display: block;
+}
+tobago-select-one-list.tobago-label-container .dropdown, tobago-select-one-list.tobago-label-container .list-group {
+  flex: 1 0 0;
+}
+tobago-select-one-list.tobago-focus .dropdown .tobago-select-field {
+  color: #a0a0a0;
+  background-color: #fffbe8;
+  border-color: #d5cfb0;
+  outline: 0;
+  box-shadow: 0 0 0 0.25rem rgba(82, 150, 150, 0.25);
+}
+tobago-select-one-list.tobago-focus .dropdown .tobago-select-field.border-danger {
+  box-shadow: 0 0 0 0.25rem rgba(255, 0, 190, 0.25);
+}
+tobago-select-one-list.tobago-focus .dropdown .tobago-select-field.border-warning {
+  box-shadow: 0 0 0 0.25rem rgba(255, 0, 190, 0.25);
+}
+tobago-select-one-list.tobago-focus .dropdown .tobago-select-field.border-info {
+  box-shadow: 0 0 0 0.25rem rgba(56, 156, 48, 0.25);
+}
+tobago-select-one-list.tobago-focus .list-group {
+  --bs-list-group-color: #a0a0a0;
+  --bs-list-group-bg: #fffbe8;
+  --bs-list-group-border-color: #d5cfb0;
+  box-shadow: 0 0 0 0.25rem rgba(82, 150, 150, 0.25);
+}
+tobago-select-one-list.tobago-focus .list-group.border-danger {
+  box-shadow: 0 0 0 0.25rem rgba(255, 0, 190, 0.25);
+}
+tobago-select-one-list.tobago-focus .list-group.border-warning {
+  box-shadow: 0 0 0 0.25rem rgba(255, 0, 190, 0.25);
+}
+tobago-select-one-list.tobago-focus .list-group.border-info {
+  box-shadow: 0 0 0 0.25rem rgba(56, 156, 48, 0.25);
+}
+tobago-select-one-list.tobago-disabled .tobago-select-field {
+  color: rgba(160, 160, 160, 0.5);
+  background-color: #d0d0d0;
+}
+tobago-select-one-list .list-group {
+  height: inherit;
+  max-height: inherit;
+  transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
+}
+@media (prefers-reduced-motion: reduce) {
+  tobago-select-one-list .list-group {
+    transition: none;
+  }
+}
+tobago-select-one-list .list-group.border-danger .list-group-item, tobago-select-one-list .list-group.border-warning .list-group-item, tobago-select-one-list .list-group.border-info .list-group-item {
+  border-color: inherit;
+}
+tobago-select-one-list .list-group .list-group-item.tobago-select-field {
+  border-bottom-color: rgba(0, 0, 0, 0.125);
+}
+tobago-select-one-list .tobago-select-field {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+}
+tobago-select-one-list .tobago-select-field.dropdown-toggle::after {
+  content: none;
+}
+tobago-select-one-list .tobago-select-field.list-group-item.form-control {
+  border-bottom-left-radius: 0;
+  border-bottom-right-radius: 0;
+  padding: 0.375rem 2.25rem 0.375rem 0.75rem;
+}
+tobago-select-one-list .tobago-select-field .tobago-filter {
+  margin: 0;
+  border: 0;
+  border-radius: 0;
+  padding: 0;
+  flex: 1 0 0;
+  min-width: 8rem;
+  background-color: transparent;
+}
+tobago-select-one-list .tobago-select-field .tobago-filter:focus {
+  box-shadow: none;
+}
+tobago-select-one-list .tobago-select-field .tobago-filter:-moz-read-only {
+  width: 0;
+  min-width: 0;
+}
+tobago-select-one-list .tobago-select-field .tobago-filter:read-only {
+  width: 0;
+  min-width: 0;
+}
+tobago-select-one-list .tobago-options.list-group-item {
+  padding: 0;
+  overflow-y: auto;
+}
+tobago-select-one-list .tobago-options .table {
+  margin-bottom: 0;
+}
+tobago-select-one-list .tobago-options .table tr {
+  cursor: pointer;
+}
+tobago-select-one-list .tobago-options .table tr.tobago-disabled {
+  color: rgba(160, 160, 160, 0.5);
+  background-color: #d0d0d0;
+  cursor: initial;
+  pointer-events: none;
+}
+tobago-select-one-list .tobago-options .table tr.tobago-preselect {
+  --bs-table-accent-bg: var(--bs-table-hover-bg);
+  color: var(--bs-table-hover-color);
+}
+tobago-select-one-list .tobago-options .table tr:last-of-type td {
+  border-bottom-width: 0;
+}
+
 tobago-select-one-listbox {
   display: block;
 }
@@ -12106,12 +12220,6 @@ tobago-select-many-list .tobago-select-field.list-group-item.form-control {
   border-bottom-right-radius: 0;
   padding: 0.375rem 2.25rem 0.375rem 0.75rem;
 }
-tobago-select-many-list .tobago-select-field .btn-group + .tobago-filter {
-  margin-left: 0.25rem;
-}
-tobago-select-many-list .tobago-select-field .btn-group {
-  margin-right: 0.25rem;
-}
 tobago-select-many-list .tobago-select-field .tobago-filter {
   margin: 0;
   border: 0;
@@ -12155,6 +12263,12 @@ tobago-select-many-list .tobago-options .table tr.tobago-preselect {
 tobago-select-many-list .tobago-options .table tr:last-of-type td {
   border-bottom-width: 0;
 }
+tobago-select-many-list .tobago-select-field .btn-group + .tobago-filter {
+  margin-left: 0.25rem;
+}
+tobago-select-many-list .tobago-select-field .btn-group {
+  margin-right: 0.25rem;
+}
 
 tobago-select-many-checkbox {
   display: block;
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 f9753ca895..65b574b5c3 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 5a2c0c2be6..97e9f14b5e 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 caa622c32c..ddad7a3497 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 e5a4c47b66..3845f662b1 100644
--- a/tobago-theme/tobago-theme-roxborough/src/main/css/tobago.css
+++ b/tobago-theme/tobago-theme-roxborough/src/main/css/tobago.css
@@ -12038,6 +12038,120 @@ tobago-select-one-choice select:disabled {
   color: rgba(160, 160, 160, 0.5);
 }
 
+tobago-select-one-list {
+  display: block;
+}
+tobago-select-one-list.tobago-label-container .dropdown, tobago-select-one-list.tobago-label-container .list-group {
+  flex: 1 0 0;
+}
+tobago-select-one-list.tobago-focus .dropdown .tobago-select-field {
+  color: #a0a0a0;
+  background-color: #000000;
+  border-color: #ffbd57;
+  outline: 0;
+  box-shadow: 0 0 0 0.25rem rgba(214, 130, 0, 0.25);
+}
+tobago-select-one-list.tobago-focus .dropdown .tobago-select-field.border-danger {
+  box-shadow: 0 0 0 0.25rem rgba(255, 178, 67, 0.25);
+}
+tobago-select-one-list.tobago-focus .dropdown .tobago-select-field.border-warning {
+  box-shadow: 0 0 0 0.25rem rgba(178, 104, 18, 0.25);
+}
+tobago-select-one-list.tobago-focus .dropdown .tobago-select-field.border-info {
+  box-shadow: 0 0 0 0.25rem rgba(19, 14, 143, 0.25);
+}
+tobago-select-one-list.tobago-focus .list-group {
+  --bs-list-group-color: #a0a0a0;
+  --bs-list-group-bg: #000000;
+  --bs-list-group-border-color: #ffbd57;
+  box-shadow: 0 0 0 0.25rem rgba(214, 130, 0, 0.25);
+}
+tobago-select-one-list.tobago-focus .list-group.border-danger {
+  box-shadow: 0 0 0 0.25rem rgba(255, 178, 67, 0.25);
+}
+tobago-select-one-list.tobago-focus .list-group.border-warning {
+  box-shadow: 0 0 0 0.25rem rgba(178, 104, 18, 0.25);
+}
+tobago-select-one-list.tobago-focus .list-group.border-info {
+  box-shadow: 0 0 0 0.25rem rgba(19, 14, 143, 0.25);
+}
+tobago-select-one-list.tobago-disabled .tobago-select-field {
+  color: rgba(160, 160, 160, 0.5);
+  background-color: #e9ecef;
+}
+tobago-select-one-list .list-group {
+  height: inherit;
+  max-height: inherit;
+  transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
+}
+@media (prefers-reduced-motion: reduce) {
+  tobago-select-one-list .list-group {
+    transition: none;
+  }
+}
+tobago-select-one-list .list-group.border-danger .list-group-item, tobago-select-one-list .list-group.border-warning .list-group-item, tobago-select-one-list .list-group.border-info .list-group-item {
+  border-color: inherit;
+}
+tobago-select-one-list .list-group .list-group-item.tobago-select-field {
+  border-bottom-color: rgba(0, 0, 0, 0.125);
+}
+tobago-select-one-list .tobago-select-field {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+}
+tobago-select-one-list .tobago-select-field.dropdown-toggle::after {
+  content: none;
+}
+tobago-select-one-list .tobago-select-field.list-group-item.form-control {
+  border-bottom-left-radius: 0;
+  border-bottom-right-radius: 0;
+  padding: 0.375rem 2.25rem 0.375rem 0.75rem;
+}
+tobago-select-one-list .tobago-select-field .tobago-filter {
+  margin: 0;
+  border: 0;
+  border-radius: 0;
+  padding: 0;
+  flex: 1 0 0;
+  min-width: 8rem;
+  background-color: transparent;
+}
+tobago-select-one-list .tobago-select-field .tobago-filter:focus {
+  box-shadow: none;
+}
+tobago-select-one-list .tobago-select-field .tobago-filter:-moz-read-only {
+  width: 0;
+  min-width: 0;
+}
+tobago-select-one-list .tobago-select-field .tobago-filter:read-only {
+  width: 0;
+  min-width: 0;
+}
+tobago-select-one-list .tobago-options.list-group-item {
+  padding: 0;
+  overflow-y: auto;
+}
+tobago-select-one-list .tobago-options .table {
+  margin-bottom: 0;
+}
+tobago-select-one-list .tobago-options .table tr {
+  cursor: pointer;
+}
+tobago-select-one-list .tobago-options .table tr.tobago-disabled {
+  color: rgba(160, 160, 160, 0.5);
+  background-color: #e9ecef;
+  cursor: initial;
+  pointer-events: none;
+}
+tobago-select-one-list .tobago-options .table tr.tobago-preselect {
+  --bs-table-accent-bg: var(--bs-table-hover-bg);
+  color: var(--bs-table-hover-color);
+}
+tobago-select-one-list .tobago-options .table tr:last-of-type td {
+  border-bottom-width: 0;
+}
+
 tobago-select-one-listbox {
   display: block;
 }
@@ -12133,12 +12247,6 @@ tobago-select-many-list .tobago-select-field.list-group-item.form-control {
   border-bottom-right-radius: 0;
   padding: 0.375rem 2.25rem 0.375rem 0.75rem;
 }
-tobago-select-many-list .tobago-select-field .btn-group + .tobago-filter {
-  margin-left: 0.25rem;
-}
-tobago-select-many-list .tobago-select-field .btn-group {
-  margin-right: 0.25rem;
-}
 tobago-select-many-list .tobago-select-field .tobago-filter {
   margin: 0;
   border: 0;
@@ -12182,6 +12290,12 @@ tobago-select-many-list .tobago-options .table tr.tobago-preselect {
 tobago-select-many-list .tobago-options .table tr:last-of-type td {
   border-bottom-width: 0;
 }
+tobago-select-many-list .tobago-select-field .btn-group + .tobago-filter {
+  margin-left: 0.25rem;
+}
+tobago-select-many-list .tobago-select-field .btn-group {
+  margin-right: 0.25rem;
+}
 
 tobago-select-many-checkbox {
   display: block;
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 319272fc7e..57f8717e1c 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 7b1fdbd859..c71a7fba81 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 7522dce224..adb0268b18 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 856d647111..1d773cc742 100644
--- a/tobago-theme/tobago-theme-scarborough/src/main/css/tobago.css
+++ b/tobago-theme/tobago-theme-scarborough/src/main/css/tobago.css
@@ -12012,6 +12012,120 @@ tobago-select-one-choice select:disabled {
   color: rgba(33, 37, 41, 0.5);
 }
 
+tobago-select-one-list {
+  display: block;
+}
+tobago-select-one-list.tobago-label-container .dropdown, tobago-select-one-list.tobago-label-container .list-group {
+  flex: 1 0 0;
+}
+tobago-select-one-list.tobago-focus .dropdown .tobago-select-field {
+  color: #212529;
+  background-color: #fff;
+  border-color: #86b7fe;
+  outline: 0;
+  box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
+}
+tobago-select-one-list.tobago-focus .dropdown .tobago-select-field.border-danger {
+  box-shadow: 0 0 0 0.25rem rgba(220, 53, 69, 0.25);
+}
+tobago-select-one-list.tobago-focus .dropdown .tobago-select-field.border-warning {
+  box-shadow: 0 0 0 0.25rem rgba(255, 193, 7, 0.25);
+}
+tobago-select-one-list.tobago-focus .dropdown .tobago-select-field.border-info {
+  box-shadow: 0 0 0 0.25rem rgba(13, 202, 240, 0.25);
+}
+tobago-select-one-list.tobago-focus .list-group {
+  --bs-list-group-color: #212529;
+  --bs-list-group-bg: #fff;
+  --bs-list-group-border-color: #86b7fe;
+  box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
+}
+tobago-select-one-list.tobago-focus .list-group.border-danger {
+  box-shadow: 0 0 0 0.25rem rgba(220, 53, 69, 0.25);
+}
+tobago-select-one-list.tobago-focus .list-group.border-warning {
+  box-shadow: 0 0 0 0.25rem rgba(255, 193, 7, 0.25);
+}
+tobago-select-one-list.tobago-focus .list-group.border-info {
+  box-shadow: 0 0 0 0.25rem rgba(13, 202, 240, 0.25);
+}
+tobago-select-one-list.tobago-disabled .tobago-select-field {
+  color: rgba(33, 37, 41, 0.5);
+  background-color: #e9ecef;
+}
+tobago-select-one-list .list-group {
+  height: inherit;
+  max-height: inherit;
+  transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
+}
+@media (prefers-reduced-motion: reduce) {
+  tobago-select-one-list .list-group {
+    transition: none;
+  }
+}
+tobago-select-one-list .list-group.border-danger .list-group-item, tobago-select-one-list .list-group.border-warning .list-group-item, tobago-select-one-list .list-group.border-info .list-group-item {
+  border-color: inherit;
+}
+tobago-select-one-list .list-group .list-group-item.tobago-select-field {
+  border-bottom-color: rgba(0, 0, 0, 0.125);
+}
+tobago-select-one-list .tobago-select-field {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+}
+tobago-select-one-list .tobago-select-field.dropdown-toggle::after {
+  content: none;
+}
+tobago-select-one-list .tobago-select-field.list-group-item.form-control {
+  border-bottom-left-radius: 0;
+  border-bottom-right-radius: 0;
+  padding: 0.375rem 2.25rem 0.375rem 0.75rem;
+}
+tobago-select-one-list .tobago-select-field .tobago-filter {
+  margin: 0;
+  border: 0;
+  border-radius: 0;
+  padding: 0;
+  flex: 1 0 0;
+  min-width: 8rem;
+  background-color: transparent;
+}
+tobago-select-one-list .tobago-select-field .tobago-filter:focus {
+  box-shadow: none;
+}
+tobago-select-one-list .tobago-select-field .tobago-filter:-moz-read-only {
+  width: 0;
+  min-width: 0;
+}
+tobago-select-one-list .tobago-select-field .tobago-filter:read-only {
+  width: 0;
+  min-width: 0;
+}
+tobago-select-one-list .tobago-options.list-group-item {
+  padding: 0;
+  overflow-y: auto;
+}
+tobago-select-one-list .tobago-options .table {
+  margin-bottom: 0;
+}
+tobago-select-one-list .tobago-options .table tr {
+  cursor: pointer;
+}
+tobago-select-one-list .tobago-options .table tr.tobago-disabled {
+  color: rgba(33, 37, 41, 0.5);
+  background-color: #e9ecef;
+  cursor: initial;
+  pointer-events: none;
+}
+tobago-select-one-list .tobago-options .table tr.tobago-preselect {
+  --bs-table-accent-bg: var(--bs-table-hover-bg);
+  color: var(--bs-table-hover-color);
+}
+tobago-select-one-list .tobago-options .table tr:last-of-type td {
+  border-bottom-width: 0;
+}
+
 tobago-select-one-listbox {
   display: block;
 }
@@ -12107,12 +12221,6 @@ tobago-select-many-list .tobago-select-field.list-group-item.form-control {
   border-bottom-right-radius: 0;
   padding: 0.375rem 2.25rem 0.375rem 0.75rem;
 }
-tobago-select-many-list .tobago-select-field .btn-group + .tobago-filter {
-  margin-left: 0.25rem;
-}
-tobago-select-many-list .tobago-select-field .btn-group {
-  margin-right: 0.25rem;
-}
 tobago-select-many-list .tobago-select-field .tobago-filter {
   margin: 0;
   border: 0;
@@ -12156,6 +12264,12 @@ tobago-select-many-list .tobago-options .table tr.tobago-preselect {
 tobago-select-many-list .tobago-options .table tr:last-of-type td {
   border-bottom-width: 0;
 }
+tobago-select-many-list .tobago-select-field .btn-group + .tobago-filter {
+  margin-left: 0.25rem;
+}
+tobago-select-many-list .tobago-select-field .btn-group {
+  margin-right: 0.25rem;
+}
 
 tobago-select-many-checkbox {
   display: block;
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 f70b2ef1a8..d593f7f6d1 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 7f9453b69f..94dcbb3df9 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 458cd11f75..a21183acfc 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 9a6cfa0217..a5bfc82f99 100644
--- a/tobago-theme/tobago-theme-speyside/src/main/css/tobago.css
+++ b/tobago-theme/tobago-theme-speyside/src/main/css/tobago.css
@@ -11733,6 +11733,120 @@ tobago-select-one-choice select:disabled {
   color: rgba(33, 37, 41, 0.5);
 }
 
+tobago-select-one-list {
+  display: block;
+}
+tobago-select-one-list.tobago-label-container .dropdown, tobago-select-one-list.tobago-label-container .list-group {
+  flex: 1 0 0;
+}
+tobago-select-one-list.tobago-focus .dropdown .tobago-select-field {
+  color: #212529;
+  background-color: white;
+  border-color: #8cab91;
+  outline: 0;
+  box-shadow: 0 0 0 0.25rem rgba(24, 87, 34, 0.25);
+}
+tobago-select-one-list.tobago-focus .dropdown .tobago-select-field.border-danger {
+  box-shadow: 0 0 0 0.25rem rgba(211, 0, 64, 0.25);
+}
+tobago-select-one-list.tobago-focus .dropdown .tobago-select-field.border-warning {
+  box-shadow: 0 0 0 0.25rem rgba(240, 173, 78, 0.25);
+}
+tobago-select-one-list.tobago-focus .dropdown .tobago-select-field.border-info {
+  box-shadow: 0 0 0 0.25rem rgba(91, 192, 222, 0.25);
+}
+tobago-select-one-list.tobago-focus .list-group {
+  --bs-list-group-color: #212529;
+  --bs-list-group-bg: white;
+  --bs-list-group-border-color: #8cab91;
+  box-shadow: 0 0 0 0.25rem rgba(24, 87, 34, 0.25);
+}
+tobago-select-one-list.tobago-focus .list-group.border-danger {
+  box-shadow: 0 0 0 0.25rem rgba(211, 0, 64, 0.25);
+}
+tobago-select-one-list.tobago-focus .list-group.border-warning {
+  box-shadow: 0 0 0 0.25rem rgba(240, 173, 78, 0.25);
+}
+tobago-select-one-list.tobago-focus .list-group.border-info {
+  box-shadow: 0 0 0 0.25rem rgba(91, 192, 222, 0.25);
+}
+tobago-select-one-list.tobago-disabled .tobago-select-field {
+  color: rgba(33, 37, 41, 0.5);
+  background-color: #e3e4e5;
+}
+tobago-select-one-list .list-group {
+  height: inherit;
+  max-height: inherit;
+  transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
+}
+@media (prefers-reduced-motion: reduce) {
+  tobago-select-one-list .list-group {
+    transition: none;
+  }
+}
+tobago-select-one-list .list-group.border-danger .list-group-item, tobago-select-one-list .list-group.border-warning .list-group-item, tobago-select-one-list .list-group.border-info .list-group-item {
+  border-color: inherit;
+}
+tobago-select-one-list .list-group .list-group-item.tobago-select-field {
+  border-bottom-color: rgba(0, 0, 0, 0.125);
+}
+tobago-select-one-list .tobago-select-field {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+}
+tobago-select-one-list .tobago-select-field.dropdown-toggle::after {
+  content: none;
+}
+tobago-select-one-list .tobago-select-field.list-group-item.form-control {
+  border-bottom-left-radius: 0;
+  border-bottom-right-radius: 0;
+  padding: 0.375rem 2.25rem 0.375rem 0.75rem;
+}
+tobago-select-one-list .tobago-select-field .tobago-filter {
+  margin: 0;
+  border: 0;
+  border-radius: 0;
+  padding: 0;
+  flex: 1 0 0;
+  min-width: 8rem;
+  background-color: transparent;
+}
+tobago-select-one-list .tobago-select-field .tobago-filter:focus {
+  box-shadow: none;
+}
+tobago-select-one-list .tobago-select-field .tobago-filter:-moz-read-only {
+  width: 0;
+  min-width: 0;
+}
+tobago-select-one-list .tobago-select-field .tobago-filter:read-only {
+  width: 0;
+  min-width: 0;
+}
+tobago-select-one-list .tobago-options.list-group-item {
+  padding: 0;
+  overflow-y: auto;
+}
+tobago-select-one-list .tobago-options .table {
+  margin-bottom: 0;
+}
+tobago-select-one-list .tobago-options .table tr {
+  cursor: pointer;
+}
+tobago-select-one-list .tobago-options .table tr.tobago-disabled {
+  color: rgba(33, 37, 41, 0.5);
+  background-color: #e3e4e5;
+  cursor: initial;
+  pointer-events: none;
+}
+tobago-select-one-list .tobago-options .table tr.tobago-preselect {
+  --bs-table-accent-bg: var(--bs-table-hover-bg);
+  color: var(--bs-table-hover-color);
+}
+tobago-select-one-list .tobago-options .table tr:last-of-type td {
+  border-bottom-width: 0;
+}
+
 tobago-select-one-listbox {
   display: block;
 }
@@ -11828,12 +11942,6 @@ tobago-select-many-list .tobago-select-field.list-group-item.form-control {
   border-bottom-right-radius: 0;
   padding: 0.375rem 2.25rem 0.375rem 0.75rem;
 }
-tobago-select-many-list .tobago-select-field .btn-group + .tobago-filter {
-  margin-left: 0.25rem;
-}
-tobago-select-many-list .tobago-select-field .btn-group {
-  margin-right: 0.25rem;
-}
 tobago-select-many-list .tobago-select-field .tobago-filter {
   margin: 0;
   border: 0;
@@ -11877,6 +11985,12 @@ tobago-select-many-list .tobago-options .table tr.tobago-preselect {
 tobago-select-many-list .tobago-options .table tr:last-of-type td {
   border-bottom-width: 0;
 }
+tobago-select-many-list .tobago-select-field .btn-group + .tobago-filter {
+  margin-left: 0.25rem;
+}
+tobago-select-many-list .tobago-select-field .btn-group {
+  margin-right: 0.25rem;
+}
 
 tobago-select-many-checkbox {
   display: block;
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 1def48c9e1..e4d5257115 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 1e1fae4fc9..d4b65bcb5a 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 79c37b1056..028376efb9 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 cf287b9219..67558f7fb0 100644
--- a/tobago-theme/tobago-theme-standard/src/main/css/tobago.css
+++ b/tobago-theme/tobago-theme-standard/src/main/css/tobago.css
@@ -11995,6 +11995,120 @@ tobago-select-one-choice select:disabled {
   color: rgba(33, 37, 41, 0.5);
 }
 
+tobago-select-one-list {
+  display: block;
+}
+tobago-select-one-list.tobago-label-container .dropdown, tobago-select-one-list.tobago-label-container .list-group {
+  flex: 1 0 0;
+}
+tobago-select-one-list.tobago-focus .dropdown .tobago-select-field {
+  color: #212529;
+  background-color: #fff;
+  border-color: #86b7fe;
+  outline: 0;
+  box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
+}
+tobago-select-one-list.tobago-focus .dropdown .tobago-select-field.border-danger {
+  box-shadow: 0 0 0 0.25rem rgba(220, 53, 69, 0.25);
+}
+tobago-select-one-list.tobago-focus .dropdown .tobago-select-field.border-warning {
+  box-shadow: 0 0 0 0.25rem rgba(255, 193, 7, 0.25);
+}
+tobago-select-one-list.tobago-focus .dropdown .tobago-select-field.border-info {
+  box-shadow: 0 0 0 0.25rem rgba(13, 202, 240, 0.25);
+}
+tobago-select-one-list.tobago-focus .list-group {
+  --bs-list-group-color: #212529;
+  --bs-list-group-bg: #fff;
+  --bs-list-group-border-color: #86b7fe;
+  box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
+}
+tobago-select-one-list.tobago-focus .list-group.border-danger {
+  box-shadow: 0 0 0 0.25rem rgba(220, 53, 69, 0.25);
+}
+tobago-select-one-list.tobago-focus .list-group.border-warning {
+  box-shadow: 0 0 0 0.25rem rgba(255, 193, 7, 0.25);
+}
+tobago-select-one-list.tobago-focus .list-group.border-info {
+  box-shadow: 0 0 0 0.25rem rgba(13, 202, 240, 0.25);
+}
+tobago-select-one-list.tobago-disabled .tobago-select-field {
+  color: rgba(33, 37, 41, 0.5);
+  background-color: #e9ecef;
+}
+tobago-select-one-list .list-group {
+  height: inherit;
+  max-height: inherit;
+  transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
+}
+@media (prefers-reduced-motion: reduce) {
+  tobago-select-one-list .list-group {
+    transition: none;
+  }
+}
+tobago-select-one-list .list-group.border-danger .list-group-item, tobago-select-one-list .list-group.border-warning .list-group-item, tobago-select-one-list .list-group.border-info .list-group-item {
+  border-color: inherit;
+}
+tobago-select-one-list .list-group .list-group-item.tobago-select-field {
+  border-bottom-color: rgba(0, 0, 0, 0.125);
+}
+tobago-select-one-list .tobago-select-field {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+}
+tobago-select-one-list .tobago-select-field.dropdown-toggle::after {
+  content: none;
+}
+tobago-select-one-list .tobago-select-field.list-group-item.form-control {
+  border-bottom-left-radius: 0;
+  border-bottom-right-radius: 0;
+  padding: 0.375rem 2.25rem 0.375rem 0.75rem;
+}
+tobago-select-one-list .tobago-select-field .tobago-filter {
+  margin: 0;
+  border: 0;
+  border-radius: 0;
+  padding: 0;
+  flex: 1 0 0;
+  min-width: 8rem;
+  background-color: transparent;
+}
+tobago-select-one-list .tobago-select-field .tobago-filter:focus {
+  box-shadow: none;
+}
+tobago-select-one-list .tobago-select-field .tobago-filter:-moz-read-only {
+  width: 0;
+  min-width: 0;
+}
+tobago-select-one-list .tobago-select-field .tobago-filter:read-only {
+  width: 0;
+  min-width: 0;
+}
+tobago-select-one-list .tobago-options.list-group-item {
+  padding: 0;
+  overflow-y: auto;
+}
+tobago-select-one-list .tobago-options .table {
+  margin-bottom: 0;
+}
+tobago-select-one-list .tobago-options .table tr {
+  cursor: pointer;
+}
+tobago-select-one-list .tobago-options .table tr.tobago-disabled {
+  color: rgba(33, 37, 41, 0.5);
+  background-color: #e9ecef;
+  cursor: initial;
+  pointer-events: none;
+}
+tobago-select-one-list .tobago-options .table tr.tobago-preselect {
+  --bs-table-accent-bg: var(--bs-table-hover-bg);
+  color: var(--bs-table-hover-color);
+}
+tobago-select-one-list .tobago-options .table tr:last-of-type td {
+  border-bottom-width: 0;
+}
+
 tobago-select-one-listbox {
   display: block;
 }
@@ -12090,12 +12204,6 @@ tobago-select-many-list .tobago-select-field.list-group-item.form-control {
   border-bottom-right-radius: 0;
   padding: 0.375rem 2.25rem 0.375rem 0.75rem;
 }
-tobago-select-many-list .tobago-select-field .btn-group + .tobago-filter {
-  margin-left: 0.25rem;
-}
-tobago-select-many-list .tobago-select-field .btn-group {
-  margin-right: 0.25rem;
-}
 tobago-select-many-list .tobago-select-field .tobago-filter {
   margin: 0;
   border: 0;
@@ -12139,6 +12247,12 @@ tobago-select-many-list .tobago-options .table tr.tobago-preselect {
 tobago-select-many-list .tobago-options .table tr:last-of-type td {
   border-bottom-width: 0;
 }
+tobago-select-many-list .tobago-select-field .btn-group + .tobago-filter {
+  margin-left: 0.25rem;
+}
+tobago-select-many-list .tobago-select-field .btn-group {
+  margin-right: 0.25rem;
+}
 
 tobago-select-many-checkbox {
   display: block;
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 103d110d9c..1b11f6d38c 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 f3d828a005..6d9612113e 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 f8dec43bb8..9787bdff9a 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
diff --git a/tobago-theme/tobago-theme-standard/src/main/js/tobago.js b/tobago-theme/tobago-theme-standard/src/main/js/tobago.js
index 371f674c3e..e81006be2a 100644
--- a/tobago-theme/tobago-theme-standard/src/main/js/tobago.js
+++ b/tobago-theme/tobago-theme-standard/src/main/js/tobago.js
@@ -1,8 +1,8 @@
-!function(e){"function"==typeof define&&define.amd?define(e):e()}((function(){"use strict";class e extends HTMLElement{constructor(){super(),this.CssClass={SHOW:"show",COLLAPSE:"collapse",COLLAPSING:"collapsing"},this.toggleButton.addEventListener("click",this.toggleCollapse.bind(this))}connectedCallback(){this.expanded="true"===this.toggleButton.ariaExpanded}toggleCollapse(e){window.clearTimeout(this.timeout),this.expanded?(this.expanded=!1,this.navbarContent.style.height=`${this.navbar [...]
+!function(e){"function"==typeof define&&define.amd?define(e):e()}((function(){"use strict";class e extends HTMLElement{constructor(){super(),this.CssClass={SHOW:"show",COLLAPSE:"collapse",COLLAPSING:"collapsing"},this.toggleButton.addEventListener("click",this.toggleCollapse.bind(this))}connectedCallback(){this.expanded="true"===this.toggleButton.ariaExpanded}toggleCollapse(e){window.clearTimeout(this.timeout),this.expanded?(this.expanded=!1,this.navbarContent.style.height=`${this.navbar [...]
 /*!
       * Bootstrap v5.2.3 (https://getbootstrap.com/)
       * Copyright 2011-2022 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
       * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
       */
-const De="transitionend",Me=e=>{let t=e.getAttribute("data-bs-target");if(!t||"#"===t){let s=e.getAttribute("href");if(!s||!s.includes("#")&&!s.startsWith("."))return null;s.includes("#")&&!s.startsWith("#")&&(s=`#${s.split("#")[1]}`),t=s&&"#"!==s?s.trim():null}return t},Pe=e=>{const t=Me(e);return t&&document.querySelector(t)?t:null},Be=e=>{const t=Me(e);return t?document.querySelector(t):null},qe=e=>{e.dispatchEvent(new Event(De))},He=e=>!(!e||"object"!=typeof e)&&(void 0!==e.jquery&&( [...]
+const De="transitionend",Me=e=>{let t=e.getAttribute("data-bs-target");if(!t||"#"===t){let s=e.getAttribute("href");if(!s||!s.includes("#")&&!s.startsWith("."))return null;s.includes("#")&&!s.startsWith("#")&&(s=`#${s.split("#")[1]}`),t=s&&"#"!==s?s.trim():null}return t},Pe=e=>{const t=Me(e);return t&&document.querySelector(t)?t:null},Be=e=>{const t=Me(e);return t?document.querySelector(t):null},qe=e=>{e.dispatchEvent(new Event(De))},He=e=>!(!e||"object"!=typeof e)&&(void 0!==e.jquery&&( [...]
 //# sourceMappingURL=tobago.js.map
diff --git a/tobago-theme/tobago-theme-standard/src/main/js/tobago.js.map b/tobago-theme/tobago-theme-standard/src/main/js/tobago.js.map
index 21a367d2c4..30b517c72e 100644
--- a/tobago-theme/tobago-theme-standard/src/main/js/tobago.js.map
+++ b/tobago-theme/tobago-theme-standard/src/main/js/tobago.js.map
@@ -1 +1 @@
-{"version":3,"file":"tobago.js","sources":["../ts/tobago-bar.ts","../../../../node_modules/@popperjs/core/lib/enums.js","../../../../node_modules/@popperjs/core/lib/dom-utils/getNodeName.js","../../../../node_modules/@popperjs/core/lib/dom-utils/getWindow.js","../../../../node_modules/@popperjs/core/lib/dom-utils/instanceOf.js","../../../../node_modules/@popperjs/core/lib/modifiers/applyStyles.js","../../../../node_modules/@popperjs/core/lib/utils/getBasePlacement.js","../../../../node_m [...]
\ No newline at end of file
+{"version":3,"file":"tobago.js","sources":["../ts/tobago-bar.ts","../../../../node_modules/@popperjs/core/lib/enums.js","../../../../node_modules/@popperjs/core/lib/dom-utils/getNodeName.js","../../../../node_modules/@popperjs/core/lib/dom-utils/getWindow.js","../../../../node_modules/@popperjs/core/lib/dom-utils/instanceOf.js","../../../../node_modules/@popperjs/core/lib/modifiers/applyStyles.js","../../../../node_modules/@popperjs/core/lib/utils/getBasePlacement.js","../../../../node_m [...]
\ No newline at end of file


[myfaces-tobago] 02/03: fix(selectManyList): jakarta namespace

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 a08f4573abf2fe9cd4bf14d4d68334c5793455c9
Author: Henning Noeth <hn...@apache.org>
AuthorDate: Fri Feb 10 21:30:28 2023 +0100

    fix(selectManyList): jakarta namespace
---
 .../tobago/internal/taglib/component/SelectManyListTagDeclaration.java  | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

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 411a1dd432..cde9c52e8d 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
@@ -62,7 +62,7 @@ import org.apache.myfaces.tobago.internal.taglib.declaration.IsVisual;
     uiComponentFacesClass = "jakarta.faces.component.UISelectMany",
     componentFamily = UISelectMany.COMPONENT_FAMILY,
     rendererType = RendererTypes.SELECT_MANY_LIST,
-    allowedChildComponenents = {"javax.faces.SelectItem", "javax.faces.SelectItems"},
+    allowedChildComponenents = {"jakarta.faces.SelectItem", "jakarta.faces.SelectItems"},
     behaviors = {
         @Behavior(
             name = ClientBehaviors.CHANGE,