diff --git a/pom.xml b/pom.xml
index a73152a..fc5c9a0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
co.cfly
jsf-components
jar
- 6.0.10
+ 6.0.11-SNAPSHOT
JSF Components
diff --git a/src/main/java/co/cfly/faces/components/PopoverContainerComponent.java b/src/main/java/co/cfly/faces/components/PopoverContainerComponent.java
new file mode 100644
index 0000000..461cb97
--- /dev/null
+++ b/src/main/java/co/cfly/faces/components/PopoverContainerComponent.java
@@ -0,0 +1,75 @@
+package co.cfly.faces.components;
+
+import java.io.IOException;
+
+import co.cfly.faces.utils.RendererTools;
+import jakarta.faces.component.FacesComponent;
+import jakarta.faces.component.UIComponent;
+import jakarta.faces.context.FacesContext;
+import jakarta.faces.context.ResponseWriter;
+
+@FacesComponent(value = "co.cfly.faces.components.PopoverContainerComponent", namespace = Families.NAMESPACE)
+public class PopoverContainerComponent extends ComponentBase {
+
+ @Override
+ public String getFamily() {
+ return Families.OUTPUT_COMPONENT_FAMILY;
+ }
+
+ @Override
+ public boolean getRendersChildren() {
+ return true;
+ }
+
+ @Override
+ public void encodeBegin(FacesContext context) throws IOException {
+ final ResponseWriter writer = context.getResponseWriter();
+ writer.startElement("span", this);
+ writeId(context);
+
+ String styleClass = (String) getAttributes().getOrDefault("styleClass", "");
+ String styleClassValue = RendererTools.spaceSeperateStrings("inline-edit popover-source", styleClass);
+ writeAttribute("class", styleClassValue, context);
+
+ writeAttributeIfExists("style", "style", context);
+ writeStandardAttributes(context);
+
+ // Popover attributes for JS initialization
+ writeAttribute("data-bs-dual-toggle", "popover", context);
+ writeAttributeIfExistsOrDefault("title", "data-bs-title", "test title", context);
+ writeAttribute("data-bs-placement", "bottom", context);
+ writeAttribute("data-bs-html", "true", context);
+ writeAttribute("data-bs-delay", "{\"show\":500,\"hide\":5000}", context);
+ writeAttribute("data-bs-container", "false", context);
+
+ // Write label text
+ String label = (String) getAttributes().getOrDefault("label", "test label");
+ writer.writeText(label, "label");
+
+ // Render children in a hidden template for popover content
+ writer.startElement("template", this);
+ writer.writeAttribute("id", getClientId(context) + "_popoverContent", null);
+ for (UIComponent child : getChildren()) {
+ child.encodeAll(context);
+ }
+ writer.endElement("template");
+
+ // Reference the template in the popover content attribute
+ writeAttribute("data-bs-content", "document.getElementById('" + getClientId(context) + "_popoverContent').innerHTML", context);
+ }
+
+ @Override
+ public void encodeChildren(FacesContext context) {
+ // Since Children are rendered manually in the encodeBegin we don't want to render them twice
+ }
+
+
+ @Override
+ public void encodeEnd(FacesContext context) throws IOException {
+ final boolean editable = getAttribute("editable", true);
+ final ResponseWriter writer = context.getResponseWriter();
+ if (editable) {
+ writer.endElement("span");
+ }
+ }
+}
diff --git a/src/main/resources/META-INF/faces.taglib.xml b/src/main/resources/META-INF/faces.taglib.xml
index d84afbd..0467c16 100644
--- a/src/main/resources/META-INF/faces.taglib.xml
+++ b/src/main/resources/META-INF/faces.taglib.xml
@@ -585,4 +585,28 @@
boolean
+
+ popoverContainer
+
+ co.cfly.faces.components.PopoverContainerComponent
+
+
+ CSS Style
+ style
+ java.lang.String
+
+
+ CSS Style Classes
+ styleClass
+ java.lang.String
+
+
+ label
+ java.lang.String
+
+
+ title
+ java.lang.String
+
+