diff --git a/domino-ui/src/main/java/org/dominokit/domino/ui/menu/AbstractMenuItem.java b/domino-ui/src/main/java/org/dominokit/domino/ui/menu/AbstractMenuItem.java index b6b40a267..f0f2de8ca 100644 --- a/domino-ui/src/main/java/org/dominokit/domino/ui/menu/AbstractMenuItem.java +++ b/domino-ui/src/main/java/org/dominokit/domino/ui/menu/AbstractMenuItem.java @@ -602,6 +602,12 @@ public > T setSearchFilter(MenuSearchFilter search return (T) this; } + /** + * Check if the menu item text starts with a specific string + * + * @param character the text to check against. + * @return boolean, true if the menu item starts with the text, false otherwise. + */ public boolean startsWith(String character) { return false; } diff --git a/domino-ui/src/main/java/org/dominokit/domino/ui/menu/CustomMenuItem.java b/domino-ui/src/main/java/org/dominokit/domino/ui/menu/CustomMenuItem.java index e624643ee..7ab925b34 100644 --- a/domino-ui/src/main/java/org/dominokit/domino/ui/menu/CustomMenuItem.java +++ b/domino-ui/src/main/java/org/dominokit/domino/ui/menu/CustomMenuItem.java @@ -18,6 +18,9 @@ import static java.util.Objects.isNull; import static java.util.Objects.nonNull; +import org.dominokit.domino.ui.elements.AnchorElement; +import org.dominokit.domino.ui.utils.ChildHandler; + /** * A custom menu item that extends the {@link AbstractMenuItem} with the capability to apply custom * search filters to menu items. @@ -46,6 +49,18 @@ public CustomMenuItem() { this.searchFilter = (token, caseSensitive) -> false; } + /** + * Applies a custom child handler to the link element of this menu item + * + * @param handler The child handler to apply. + * @return This menu item instance. + */ + public CustomMenuItem withClickableElement( + ChildHandler, AnchorElement> handler) { + handler.apply(this, linkElement); + return this; + } + /** * Invoked during a search operation. Displays the menu item if the token is found using the * provided {@link MenuSearchFilter}. diff --git a/domino-ui/src/main/java/org/dominokit/domino/ui/menu/MenuItem.java b/domino-ui/src/main/java/org/dominokit/domino/ui/menu/MenuItem.java index 41734ffd2..b4469d30c 100644 --- a/domino-ui/src/main/java/org/dominokit/domino/ui/menu/MenuItem.java +++ b/domino-ui/src/main/java/org/dominokit/domino/ui/menu/MenuItem.java @@ -22,8 +22,10 @@ import java.util.Arrays; import java.util.Optional; import java.util.stream.Collectors; +import org.dominokit.domino.ui.elements.AnchorElement; import org.dominokit.domino.ui.elements.SmallElement; import org.dominokit.domino.ui.elements.SpanElement; +import org.dominokit.domino.ui.utils.ChildHandler; /** * Represents a menu item that can be added to a menu. Each menu item can have a text and an @@ -71,6 +73,17 @@ public MenuItem(String text) { this.searchFilter = this::containsToken; } + /** + * Applies a custom child handler to the link element of this menu item + * + * @param handler The child handler to apply. + * @return This menu item instance. + */ + public MenuItem withClickableElement(ChildHandler, AnchorElement> handler) { + handler.apply(this, linkElement); + return this; + } + /** * Constructs a menu item with the specified text and description. * diff --git a/domino-ui/src/main/java/org/dominokit/domino/ui/menu/MenuItemsGroup.java b/domino-ui/src/main/java/org/dominokit/domino/ui/menu/MenuItemsGroup.java index 7fe6a24e4..9f5c647fd 100644 --- a/domino-ui/src/main/java/org/dominokit/domino/ui/menu/MenuItemsGroup.java +++ b/domino-ui/src/main/java/org/dominokit/domino/ui/menu/MenuItemsGroup.java @@ -20,6 +20,7 @@ import java.util.ArrayList; import java.util.List; +import org.dominokit.domino.ui.elements.AnchorElement; import org.dominokit.domino.ui.elements.DivElement; import org.dominokit.domino.ui.elements.UListElement; import org.dominokit.domino.ui.layout.NavBar; @@ -62,7 +63,9 @@ public MenuItemsGroup(Menu menu) { linkElement.removeCss(dui_menu_item_anchor); linkElement.addCss(dui_menu_group_header); root.appendChild(groupElement = div().addCss(dui_flex, dui_flex_col)); - groupHeader = LazyChild.of(NavBar.create().addCss(dui_order_first), bodyElement); + groupHeader = + LazyChild.of( + NavBar.create().addCss(dui_menu_group_header_nav).addCss(dui_order_first), bodyElement); itemsListElement = LazyChild.of(ul().addCss(dui_menu_items_list, dui_order_last), groupElement); } @@ -129,6 +132,18 @@ public MenuItemsGroup withItemsMenu(ChildHandler, UListElem return this; } + /** + * Applies a custom child handler to the link element of this menu item + * + * @param handler The child handler to apply. + * @return This menu item instance. + */ + public MenuItemsGroup withClickableElement( + ChildHandler, AnchorElement> handler) { + handler.apply(this, linkElement); + return this; + } + /** * Invoked during a search operation across all the menu items in this group. * diff --git a/domino-ui/src/main/java/org/dominokit/domino/ui/menu/MenuStyles.java b/domino-ui/src/main/java/org/dominokit/domino/ui/menu/MenuStyles.java index 927331d65..0861fd416 100644 --- a/domino-ui/src/main/java/org/dominokit/domino/ui/menu/MenuStyles.java +++ b/domino-ui/src/main/java/org/dominokit/domino/ui/menu/MenuStyles.java @@ -44,6 +44,7 @@ public interface MenuStyles { CssClass dui_menu_item_hint = () -> "dui-menu-item-hint"; CssClass dui_menu_group = () -> "dui-menu-group"; CssClass dui_menu_group_header = () -> "dui-menu-group-header"; + CssClass dui_menu_group_header_nav = () -> "dui-menu-group-header-nav"; CssClass dui_menu_drop = () -> "dui-menu-drop"; CssClass dui_menu_item_prefix = () -> "dui-menu-item-prefix"; diff --git a/domino-ui/src/main/java/org/dominokit/domino/ui/menu/direction/BottomLeftDropDirection.java b/domino-ui/src/main/java/org/dominokit/domino/ui/menu/direction/BottomLeftDropDirection.java index 2daf358e2..7bf7aab13 100644 --- a/domino-ui/src/main/java/org/dominokit/domino/ui/menu/direction/BottomLeftDropDirection.java +++ b/domino-ui/src/main/java/org/dominokit/domino/ui/menu/direction/BottomLeftDropDirection.java @@ -48,14 +48,11 @@ public void position(Element source, Element target) { delta = newRect.width - availableSpace; } - Style.of(source) - .style - .setProperty( - "left", - px.of( - (targetRect.left - (newRect.left - targetRect.left)) - - (sourceRect.width - targetRect.width) - + delta)); + double left = + (targetRect.left - (newRect.left - targetRect.left)) + - (sourceRect.width - targetRect.width) + + delta; + Style.of(source).style.setProperty("left", px.of(Math.max(left, 0))); } /** {@inheritDoc} */ diff --git a/domino-ui/src/main/java/org/dominokit/domino/ui/menu/direction/BottomMiddleDropDirection.java b/domino-ui/src/main/java/org/dominokit/domino/ui/menu/direction/BottomMiddleDropDirection.java index 6a643fb96..4adebef9f 100644 --- a/domino-ui/src/main/java/org/dominokit/domino/ui/menu/direction/BottomMiddleDropDirection.java +++ b/domino-ui/src/main/java/org/dominokit/domino/ui/menu/direction/BottomMiddleDropDirection.java @@ -49,24 +49,22 @@ public void position(Element source, Element target) { int innerWidth = window.innerWidth; double delta = 0; - double availableSpace = innerWidth - newTargetRect.right - window.pageXOffset; + double availableSpace = + innerWidth - newTargetRect.right + (newTargetRect.width / 2) - window.pageXOffset; if (availableSpace < (newRect.width / 2)) { - delta = (newRect.width / 2) - availableSpace; + delta = (newRect.width / 2) - (newTargetRect.width / 2) - availableSpace; } elements.elementOf(source).setCssProperty("--dui-menu-drop-pin-offset", delta + "px"); + double left = + newTargetRect.left + - (newRect.width / 2) + + (newTargetRect.width / 2) + + window.pageXOffset + - Math.abs(delta) + - elements.body().element().getBoundingClientRect().left; - Style.of(source) - .style - .setProperty( - "left", - px.of( - newTargetRect.left - - (newRect.width / 2) - + (newTargetRect.width / 2) - + window.pageXOffset - - delta - - elements.body().element().getBoundingClientRect().left)); + Style.of(source).style.setProperty("left", px.of(Math.max(left, 0))); } /** {@inheritDoc} */ diff --git a/domino-ui/src/main/java/org/dominokit/domino/ui/menu/direction/BottomRightDropDirection.java b/domino-ui/src/main/java/org/dominokit/domino/ui/menu/direction/BottomRightDropDirection.java index 0741804c9..79ed4ebad 100644 --- a/domino-ui/src/main/java/org/dominokit/domino/ui/menu/direction/BottomRightDropDirection.java +++ b/domino-ui/src/main/java/org/dominokit/domino/ui/menu/direction/BottomRightDropDirection.java @@ -47,12 +47,8 @@ public void position(Element source, Element target) { dui_dd_bottom_right.apply(source); elements.elementOf(source).setCssProperty("--dui-menu-drop-min-width", targetRect.width + "px"); DOMRect newRect = source.getBoundingClientRect(); - Style.of(source) - .style - .setProperty( - "left", - px.of( - (targetRect.left - (newRect.left - targetRect.left)) + window.pageXOffset - delta)); + double left = (targetRect.left - (newRect.left - targetRect.left)) + window.pageXOffset - delta; + Style.of(source).style.setProperty("left", px.of(Math.max(left, 0))); } /** {@inheritDoc} */ diff --git a/domino-ui/src/main/java/org/dominokit/domino/ui/menu/direction/LeftDownDropDirection.java b/domino-ui/src/main/java/org/dominokit/domino/ui/menu/direction/LeftDownDropDirection.java index 82b9465c8..1c9a15e66 100644 --- a/domino-ui/src/main/java/org/dominokit/domino/ui/menu/direction/LeftDownDropDirection.java +++ b/domino-ui/src/main/java/org/dominokit/domino/ui/menu/direction/LeftDownDropDirection.java @@ -51,18 +51,15 @@ public void position(Element source, Element target) { elements.elementOf(source).setCssProperty("--dui-menu-drop-min-width", targetRect.width + "px"); DOMRect newRect = source.getBoundingClientRect(); - Style.of(source) - .style - .setProperty( - "left", - px.of( - targetRect.left - - (newRect.left - targetRect.left) - + window.pageXOffset - - sourceRect.width - - (source.hasAttribute("dui-position-x-offset") - ? Double.parseDouble(source.getAttribute("dui-position-x-offset")) - : 0))); + double left = + targetRect.left + - (newRect.left - targetRect.left) + + window.pageXOffset + - sourceRect.width + - (source.hasAttribute("dui-position-x-offset") + ? Double.parseDouble(source.getAttribute("dui-position-x-offset")) + : 0); + Style.of(source).style.setProperty("left", px.of(Math.max(left, 0))); } /** {@inheritDoc} */ diff --git a/domino-ui/src/main/java/org/dominokit/domino/ui/menu/direction/LeftMiddleDropDirection.java b/domino-ui/src/main/java/org/dominokit/domino/ui/menu/direction/LeftMiddleDropDirection.java index 5b32693d7..399d5e5bc 100644 --- a/domino-ui/src/main/java/org/dominokit/domino/ui/menu/direction/LeftMiddleDropDirection.java +++ b/domino-ui/src/main/java/org/dominokit/domino/ui/menu/direction/LeftMiddleDropDirection.java @@ -45,15 +45,9 @@ public void position(Element source, Element target) { delta = ((sourceRect.height / 2) - availableUpSpace); } - Style.of(source) - .style - .setProperty( - "top", - px.of( - targetRect.top - + window.pageYOffset - - ((sourceRect.height - targetRect.height) / 2) - + delta)); + double left = + targetRect.top + window.pageYOffset - ((sourceRect.height - targetRect.height) / 2) + delta; + Style.of(source).style.setProperty("top", px.of(Math.max(left, 0))); Style.of(source).style.setProperty("left", px.of(targetRect.left)); diff --git a/domino-ui/src/main/java/org/dominokit/domino/ui/menu/direction/LeftUpDropDirection.java b/domino-ui/src/main/java/org/dominokit/domino/ui/menu/direction/LeftUpDropDirection.java index ead0d1eaf..3ae18d7ba 100644 --- a/domino-ui/src/main/java/org/dominokit/domino/ui/menu/direction/LeftUpDropDirection.java +++ b/domino-ui/src/main/java/org/dominokit/domino/ui/menu/direction/LeftUpDropDirection.java @@ -51,18 +51,15 @@ public void position(Element source, Element target) { elements.elementOf(source).setCssProperty("--dui-menu-drop-min-width", targetRect.width + "px"); DOMRect newRect = source.getBoundingClientRect(); - Style.of(source) - .style - .setProperty( - "left", - px.of( - targetRect.left - - (newRect.left - targetRect.left) - + window.pageXOffset - - sourceRect.width - - (source.hasAttribute("dui-position-x-offset") - ? Double.parseDouble(source.getAttribute("dui-position-x-offset")) - : 0))); + double left = + targetRect.left + - (newRect.left - targetRect.left) + + window.pageXOffset + - sourceRect.width + - (source.hasAttribute("dui-position-x-offset") + ? Double.parseDouble(source.getAttribute("dui-position-x-offset")) + : 0); + Style.of(source).style.setProperty("left", px.of(Math.max(left, 0))); } /** {@inheritDoc} */ diff --git a/domino-ui/src/main/java/org/dominokit/domino/ui/menu/direction/RightDownDropDirection.java b/domino-ui/src/main/java/org/dominokit/domino/ui/menu/direction/RightDownDropDirection.java index 06671924d..3bc29ec54 100644 --- a/domino-ui/src/main/java/org/dominokit/domino/ui/menu/direction/RightDownDropDirection.java +++ b/domino-ui/src/main/java/org/dominokit/domino/ui/menu/direction/RightDownDropDirection.java @@ -52,17 +52,14 @@ public void position(Element source, Element target) { elements.elementOf(source).setCssProperty("--dui-menu-drop-min-width", targetRect.width + "px"); DOMRect newRect = source.getBoundingClientRect(); - Style.of(source) - .style - .setProperty( - "left", - px.of( - (targetRect.left - (newRect.left - targetRect.left)) - + window.pageXOffset - + targetRect.width - + (source.hasAttribute("dui-position-x-offset") - ? Double.parseDouble(source.getAttribute("dui-position-x-offset")) - : 0))); + double left = + (targetRect.left - (newRect.left - targetRect.left)) + + window.pageXOffset + + targetRect.width + + (source.hasAttribute("dui-position-x-offset") + ? Double.parseDouble(source.getAttribute("dui-position-x-offset")) + : 0); + Style.of(source).style.setProperty("left", px.of(Math.max(left, 0))); } /** {@inheritDoc} */ diff --git a/domino-ui/src/main/java/org/dominokit/domino/ui/menu/direction/RightMiddleDropDirection.java b/domino-ui/src/main/java/org/dominokit/domino/ui/menu/direction/RightMiddleDropDirection.java index 2a47e9898..85c02ecd2 100644 --- a/domino-ui/src/main/java/org/dominokit/domino/ui/menu/direction/RightMiddleDropDirection.java +++ b/domino-ui/src/main/java/org/dominokit/domino/ui/menu/direction/RightMiddleDropDirection.java @@ -64,17 +64,14 @@ public void position(Element source, Element target) { elements.elementOf(source).setCssProperty("--dui-menu-drop-min-width", targetRect.width + "px"); DOMRect newRect = source.getBoundingClientRect(); - Style.of(source) - .style - .setProperty( - "left", - px.of( - (targetRect.left - (newRect.left - targetRect.left)) - + window.pageXOffset - + targetRect.width - + (source.hasAttribute("dui-position-x-offset") - ? Double.parseDouble(source.getAttribute("dui-position-x-offset")) - : 0))); + double left = + (targetRect.left - (newRect.left - targetRect.left)) + + window.pageXOffset + + targetRect.width + + (source.hasAttribute("dui-position-x-offset") + ? Double.parseDouble(source.getAttribute("dui-position-x-offset")) + : 0); + Style.of(source).style.setProperty("left", px.of(Math.max(left, 0))); } /** {@inheritDoc} */ diff --git a/domino-ui/src/main/java/org/dominokit/domino/ui/menu/direction/RightUpDropDirection.java b/domino-ui/src/main/java/org/dominokit/domino/ui/menu/direction/RightUpDropDirection.java index 652097227..d2ef386ff 100644 --- a/domino-ui/src/main/java/org/dominokit/domino/ui/menu/direction/RightUpDropDirection.java +++ b/domino-ui/src/main/java/org/dominokit/domino/ui/menu/direction/RightUpDropDirection.java @@ -59,17 +59,14 @@ public void position(Element source, Element target) { .setCssProperty("--dui-dd-position-delta", ((targetRect.top - sourceRect.top)) + "px"); elements.elementOf(source).setCssProperty("--dui-menu-drop-min-width", targetRect.width + "px"); DOMRect newRect = source.getBoundingClientRect(); - Style.of(source) - .style - .setProperty( - "left", - px.of( - (targetRect.left - (newRect.left - targetRect.left)) - + window.pageXOffset - + targetRect.width - + (source.hasAttribute("dui-position-x-offset") - ? Double.parseDouble(source.getAttribute("dui-position-x-offset")) - : 0))); + double left = + (targetRect.left - (newRect.left - targetRect.left)) + + window.pageXOffset + + targetRect.width + + (source.hasAttribute("dui-position-x-offset") + ? Double.parseDouble(source.getAttribute("dui-position-x-offset")) + : 0); + Style.of(source).style.setProperty("left", px.of(Math.max(left, 0))); } /** {@inheritDoc} */ diff --git a/domino-ui/src/main/java/org/dominokit/domino/ui/menu/direction/TopLeftDropDirection.java b/domino-ui/src/main/java/org/dominokit/domino/ui/menu/direction/TopLeftDropDirection.java index 0d3c511ad..be8eee7b3 100644 --- a/domino-ui/src/main/java/org/dominokit/domino/ui/menu/direction/TopLeftDropDirection.java +++ b/domino-ui/src/main/java/org/dominokit/domino/ui/menu/direction/TopLeftDropDirection.java @@ -50,14 +50,11 @@ public void position(Element source, Element target) { elements.elementOf(source).setCssProperty("--dui-menu-drop-min-width", targetRect.width + "px"); DOMRect newRect = source.getBoundingClientRect(); - Style.of(source) - .style - .setProperty( - "left", - px.of( - (targetRect.left - (newRect.left - targetRect.left)) - - (sourceRect.width - targetRect.width) - + delta)); + double left = + (targetRect.left - (newRect.left - targetRect.left)) + - (sourceRect.width - targetRect.width) + + delta; + Style.of(source).style.setProperty("left", px.of(Math.max(left, 0))); } /** {@inheritDoc} */ diff --git a/domino-ui/src/main/java/org/dominokit/domino/ui/menu/direction/TopMiddleDropDirection.java b/domino-ui/src/main/java/org/dominokit/domino/ui/menu/direction/TopMiddleDropDirection.java index ee5154e18..eed771caf 100644 --- a/domino-ui/src/main/java/org/dominokit/domino/ui/menu/direction/TopMiddleDropDirection.java +++ b/domino-ui/src/main/java/org/dominokit/domino/ui/menu/direction/TopMiddleDropDirection.java @@ -49,23 +49,21 @@ public void position(Element source, Element target) { DOMRect newTargetRect = target.getBoundingClientRect(); double delta = 0; - double availableSpace = innerWidth - newTargetRect.right - window.pageXOffset; + double availableSpace = + innerWidth - newTargetRect.right + (newTargetRect.width / 2) - window.pageXOffset; if (availableSpace < (newRect.width / 2)) { - delta = (newRect.width / 2) - availableSpace; + delta = (newRect.width / 2) - (newTargetRect.width / 2) - availableSpace; } elements.elementOf(source).setCssProperty("--dui-menu-drop-pin-offset", delta + "px"); - Style.of(source) - .style - .setProperty( - "left", - px.of( - newTargetRect.left - - (newRect.width / 2) - + (newTargetRect.width / 2) - + window.pageXOffset - - delta - - elements.body().element().getBoundingClientRect().left)); + double left = + newTargetRect.left + - (newRect.width / 2) + + (newTargetRect.width / 2) + + window.pageXOffset + - Math.abs(delta) + - elements.body().element().getBoundingClientRect().left; + Style.of(source).style.setProperty("left", px.of(Math.max(left, 0))); } /** {@inheritDoc} */ diff --git a/domino-ui/src/main/java/org/dominokit/domino/ui/menu/direction/TopRightDropDirection.java b/domino-ui/src/main/java/org/dominokit/domino/ui/menu/direction/TopRightDropDirection.java index 9183cdf46..79306dab2 100644 --- a/domino-ui/src/main/java/org/dominokit/domino/ui/menu/direction/TopRightDropDirection.java +++ b/domino-ui/src/main/java/org/dominokit/domino/ui/menu/direction/TopRightDropDirection.java @@ -49,12 +49,8 @@ public void position(Element source, Element target) { dui_dd_top_right.apply(source); elements.elementOf(source).setCssProperty("--dui-menu-drop-min-width", targetRect.width + "px"); DOMRect newRect = source.getBoundingClientRect(); - Style.of(source) - .style - .setProperty( - "left", - px.of( - (targetRect.left - (newRect.left - targetRect.left)) + window.pageXOffset - delta)); + double left = (targetRect.left - (newRect.left - targetRect.left)) + window.pageXOffset - delta; + Style.of(source).style.setProperty("left", px.of(Math.max(left, 0))); } /** {@inheritDoc} */ diff --git a/domino-ui/src/main/resources/org/dominokit/domino/ui/public/css/domino-ui/dui-components/domino-ui-menu.css b/domino-ui/src/main/resources/org/dominokit/domino/ui/public/css/domino-ui/dui-components/domino-ui-menu.css index 02735fe01..a0184db50 100644 --- a/domino-ui/src/main/resources/org/dominokit/domino/ui/public/css/domino-ui/dui-components/domino-ui-menu.css +++ b/domino-ui/src/main/resources/org/dominokit/domino/ui/public/css/domino-ui/dui-components/domino-ui-menu.css @@ -271,6 +271,12 @@ a.dui-menu-group-header:focus, a.dui-menu-group-header { text-decoration: none; outline: none; + display: inherit; +} + +.dui-menu-group-header-nav { + border: none; + --dui-menu-header-border-width: 0; } .dui-menu-items-list .li:last-child {