Skip to content

Commit

Permalink
fix #334 Select popup positioning when resizing window
Browse files Browse the repository at this point in the history
  • Loading branch information
vegegoku committed Dec 23, 2024
1 parent aebac16 commit 077b291
Show file tree
Hide file tree
Showing 15 changed files with 213 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,12 @@ public interface ZIndexConfig extends ComponentConfig {
/**
* Use this method to define the default initial start z-index
*
* <p>Defaults to : {@code 8388635}
* <p>Defaults to : {@code 10}
*
* @return integer z-index
*/
default int getInitialZIndex() {
return 8388635;
return 10;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ public class AbstractDialog<T extends AbstractDialog<T>>
public AbstractDialog() {
element =
div()
.setZIndexLayer(ZIndexLayer.Z_LAYER_3)
.addCss(dui_modal_box, dui_hidden)
.appendChild(
modalElement =
Expand Down Expand Up @@ -696,6 +697,11 @@ public T setDefaultFocusElement(IsElement<?> defaultFocusElement) {
return (T) this;
}

@Override
public void resetZIndexLayer() {
// Dialogs should never rest their base layer.;
}

/**
* Checks if the dialog is currently open.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,14 @@

import java.util.ArrayList;
import java.util.Deque;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import org.dominokit.domino.ui.config.HasComponentConfig;
import org.dominokit.domino.ui.config.ZIndexConfig;
import org.dominokit.domino.ui.utils.HasZIndexLayer;
import org.dominokit.domino.ui.utils.IsPopup;

/**
Expand All @@ -48,19 +51,26 @@ public class DefaultZIndexManager implements ZIndexManager, HasComponentConfig<Z
private static Deque<IsPopup<?>> modals = new LinkedList<>();

private final List<ZIndexListener> listeners = new ArrayList<>();
private Map<HasZIndexLayer.ZIndexLayer, Integer> counters = new HashMap<>();

/**
* Calculates and returns the next z-index value.
*
* @return the next z-index value
*/
@Override
public Integer getNextZIndex() {
if (isNull(currentZIndex)) {
this.currentZIndex = getConfig().getInitialZIndex();
public Integer getNextZIndex(HasZIndexLayer<?> element) {
HasZIndexLayer.ZIndexLayer layer = element.getZIndexLayer();

if (isNull(layer)) {
layer = HasZIndexLayer.ZIndexLayer.Z_LAYER_1;
}
if (!counters.containsKey(layer)) {
counters.put(layer, layer.getzIndexOffset() + getConfig().getInitialZIndex());
}
currentZIndex += getConfig().getzIndexIncrement();
return currentZIndex;
int nextZIndex = counters.get(layer) + getConfig().getzIndexIncrement();
counters.put(layer, nextZIndex);
return nextZIndex;
}

/**
Expand All @@ -72,16 +82,17 @@ public Integer getNextZIndex() {
@Override
public void onPopupOpen(IsPopup<?> popup) {
if (popup.isModal()) {
Integer nextZIndex = getNextZIndex();
Integer nextZIndex = getNextZIndex(popup);
ModalBackDrop.INSTANCE.setZIndex(nextZIndex);
if (!ModalBackDrop.INSTANCE.isAttached()) {
elements.body().appendChild(ModalBackDrop.INSTANCE);
}
modals.push(popup);
}

Integer next = getNextZIndex();
Integer next = getNextZIndex(popup);
popup.setZIndex(next);
popup.setZIndexLayer(popup.getZIndexLayer());
listeners.forEach(
listener -> listener.onZIndexChange(new ZIndexListener.ZIndexInfo(popup, modals)));
}
Expand All @@ -96,16 +107,18 @@ public void onPopupClose(IsPopup<?> popup) {
if (popup.isModal()) {
modals.remove(popup);
if (!modals.isEmpty()) {
Integer backdropZIndex = getNextZIndex();
Integer backdropZIndex = getNextZIndex(popup);
ModalBackDrop.INSTANCE.setZIndex(backdropZIndex);
Integer modalZIndex = getNextZIndex();
Integer modalZIndex = getNextZIndex(popup);
modals.peek().setZIndex(modalZIndex);
listeners.forEach(
listener ->
listener.onZIndexChange(new ZIndexListener.ZIndexInfo(modals.peek(), modals)));
} else {
ModalBackDrop.INSTANCE.remove();
}
} else {
popup.resetZIndexLayer();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public class ModalBackDrop extends BaseDominoElement<HTMLDivElement, ModalBackDr

/** Private constructor to ensure singleton pattern. */
private ModalBackDrop() {
element = div();
element = div().setZIndexLayer(ZIndexLayer.Z_LAYER_3);
element.addCss(dui_dialog_backdrop);
element
.addEventListener(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import java.util.Deque;
import java.util.Optional;
import org.dominokit.domino.ui.utils.HasZIndexLayer;
import org.dominokit.domino.ui.utils.IsPopup;

/**
Expand All @@ -37,7 +38,7 @@ public interface ZIndexManager {
*
* @return the next z-index
*/
Integer getNextZIndex();
Integer getNextZIndex(HasZIndexLayer<?> element);

/**
* Notifies the manager that a popup has been opened.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,18 +103,26 @@ public AppLayout() {
body =
section()
.addCss(dui_body)
.appendChild(content = section().addCss(dui_content)));
.appendChild(
content =
section()
.addCss(dui_content)
.setZIndexLayer(ZIndexLayer.Z_LAYER_1)));
header =
LazyChild.of(header().addCss(dui_header), body)
LazyChild.of(header().addCss(dui_header).setZIndexLayer(ZIndexLayer.Z_LAYER_2), body)
.whenInitialized(() -> layout.addCss(dui_has_header));
navBar = LazyChild.of(NavBar.create(), header);
footer =
LazyChild.of(section().addCss(dui_footer), body)
LazyChild.of(section().addCss(dui_footer).setZIndexLayer(ZIndexLayer.Z_LAYER_2), body)
.whenInitialized(() -> layout.addCss(dui_has_footer));
leftDrawerToggle = initLeftDrawerToggle(leftToggleIcon);
leftDrawer =
LazyChild.of(
section().addCss(dui_left_drawer).addClickListener(Event::stopPropagation), layout)
section()
.addCss(dui_left_drawer)
.setZIndexLayer(ZIndexLayer.Z_LAYER_2)
.addClickListener(Event::stopPropagation),
layout)
.whenInitialized(leftDrawerToggle::get);
leftDrawer.whenInitialized(
() -> {
Expand All @@ -140,7 +148,11 @@ public AppLayout() {
rightDrawerToggle = initRightDrawerToggle(rightToggleIcon);
rightDrawer =
LazyChild.of(
section().addCss(dui_right_drawer).addClickListener(Event::stopPropagation), layout)
section()
.addCss(dui_right_drawer)
.setZIndexLayer(ZIndexLayer.Z_LAYER_2)
.addClickListener(Event::stopPropagation),
layout)
.whenInitialized(rightDrawerToggle::get);

rightDrawer.whenInitialized(
Expand Down
67 changes: 63 additions & 4 deletions domino-ui/src/main/java/org/dominokit/domino/ui/menu/Menu.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,36 @@
package org.dominokit.domino.ui.menu;

import static elemental2.dom.DomGlobal.document;
import static elemental2.dom.DomGlobal.window;
import static java.util.Objects.isNull;
import static java.util.Objects.nonNull;
import static org.dominokit.domino.ui.utils.Domino.*;
import static org.dominokit.domino.ui.utils.Domino.a;
import static org.dominokit.domino.ui.utils.Domino.div;
import static org.dominokit.domino.ui.utils.Domino.dui_order_first;
import static org.dominokit.domino.ui.utils.Domino.dui_order_last;
import static org.dominokit.domino.ui.utils.Domino.elementOf;
import static org.dominokit.domino.ui.utils.Domino.li;
import static org.dominokit.domino.ui.utils.Domino.ul;
import static org.dominokit.domino.ui.utils.PopupsCloser.DOMINO_UI_AUTO_CLOSABLE;

import elemental2.dom.*;
import elemental2.dom.DomGlobal;
import elemental2.dom.Element;
import elemental2.dom.Event;
import elemental2.dom.EventListener;
import java.util.*;
import elemental2.dom.HTMLDivElement;
import elemental2.dom.HTMLElement;
import elemental2.dom.HTMLLIElement;
import elemental2.dom.KeyboardEvent;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import jsinterop.base.Js;
import org.dominokit.domino.ui.IsElement;
import org.dominokit.domino.ui.config.HasComponentConfig;
Expand All @@ -45,7 +67,19 @@
import org.dominokit.domino.ui.search.SearchBox;
import org.dominokit.domino.ui.style.BooleanCssClass;
import org.dominokit.domino.ui.style.Elevation;
import org.dominokit.domino.ui.utils.*;
import org.dominokit.domino.ui.utils.AppendStrategy;
import org.dominokit.domino.ui.utils.BaseDominoElement;
import org.dominokit.domino.ui.utils.ChildHandler;
import org.dominokit.domino.ui.utils.DominoElement;
import org.dominokit.domino.ui.utils.DominoUIConfig;
import org.dominokit.domino.ui.utils.HasSelectionListeners;
import org.dominokit.domino.ui.utils.IsPopup;
import org.dominokit.domino.ui.utils.KeyboardNavigation;
import org.dominokit.domino.ui.utils.LazyChild;
import org.dominokit.domino.ui.utils.PopupsCloser;
import org.dominokit.domino.ui.utils.PrefixAddOn;
import org.dominokit.domino.ui.utils.Separator;
import org.dominokit.domino.ui.utils.SubheaderAddon;

/**
* Represents a UI Menu component that supports different configurations, items, and behaviors.
Expand Down Expand Up @@ -164,6 +198,7 @@ public class Menu<V> extends BaseDominoElement<HTMLDivElement, Menu<V>>
private boolean closeOnBlur = DominoUIConfig.CONFIG.isClosePopupOnBlur();
private OpenMenuCondition<V> openMenuCondition = (menu) -> true;
private List<MediaQuery.MediaQueryListenerRecord> mediaQueryRecords = new ArrayList<>();
private EventListener windowResizeListener;

/**
* Factory method to create a new Menu instance.
Expand All @@ -184,6 +219,20 @@ public Menu() {
backArrowContainer = div().addCss(dui_order_first, dui_menu_back_icon);
init(this);

windowResizeListener = evt -> position();
nowAndWhenAttached(
() -> {
if (isDropDown()) {
window.addEventListener("resize", windowResizeListener);
}
});
onDetached(
(target, mutationRecord) -> {
if (isDropDown()) {
window.removeEventListener("resize", windowResizeListener);
}
});

EventListener addMissingEventListener =
evt -> {
evt.preventDefault();
Expand Down Expand Up @@ -1974,6 +2023,16 @@ public Menu<V> setPreserveSelectionStyles(boolean preserveSelectionStyles) {
return this;
}

@Override
public ZIndexLayer getZIndexLayer() {
if (isDropDown()) {
return getTarget()
.map(t -> t.getTargetElement().getZIndexLayer())
.orElse(ZIndexLayer.Z_LAYER_1);
}
return super.getZIndexLayer();
}

/** Represents a handler for a group of menu items. */
@FunctionalInterface
public interface MenuItemsGroupHandler<V, I extends AbstractMenuItem<V>> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,12 @@ public SpanElement getTextElement() {
return textElement;
}

@Override
public ZIndexLayer getZIndexLayer() {
ZIndexLayer layer = menu.getZIndexLayer();
return layer;
}

/**
* Searches for a given token in the text and description of the menu item.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,12 @@ public T setCloseOnBlur(boolean closeOnBlur) {
return (T) this;
}

@Override
public ZIndexLayer getZIndexLayer() {
ZIndexLayer layer = elementOf(targetElement).getZIndexLayer();
return layer;
}

/**
* Gets the DOM element representing the popover.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ public static Search create(boolean autoSearch) {
*/
public Search open() {
expand();
setZIndex(config().getUIConfig().getZindexManager().getNextZIndex());
setZIndex(config().getUIConfig().getZindexManager().getNextZIndex(this));
searchInput.element().focus();
return this;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import static org.dominokit.domino.ui.utils.Domino.dui_hidden;
import static org.dominokit.domino.ui.utils.Domino.elementOf;
import static org.dominokit.domino.ui.utils.Domino.text;
import static org.dominokit.domino.ui.utils.HasZIndexLayer.ZIndexLayer.Z_LAYER_1;

import elemental2.core.JsArray;
import elemental2.dom.AddEventListenerOptions;
Expand Down Expand Up @@ -107,7 +108,8 @@ public abstract class BaseDominoElement<E extends Element, T extends IsElement<E
HasKeyboardEvents<T>,
HasCollapseListeners<T>,
HasAttributes<T>,
HasMeta<T> {
HasMeta<T>,
HasZIndexLayer<T> {

static {
DominoThemeManager.INSTANCE.applyUserThemes();
Expand Down Expand Up @@ -332,6 +334,28 @@ public T setZIndex(int zindex) {
return (T) this;
}

@Override
public ZIndexLayer getZIndexLayer() {
if (this.hasAttribute(DUI_Z_INDEX_LAYER)) {
return ZIndexLayer.valueOf(getAttribute(DUI_Z_INDEX_LAYER));
}
if (isNull(parent())) {
return Z_LAYER_1;
}
return parent().getZIndexLayer();
}

@Override
public T setZIndexLayer(ZIndexLayer layer) {
setAttribute(DUI_Z_INDEX_LAYER, layer.name());
return (T) this;
}

@Override
public void resetZIndexLayer() {
removeAttribute(DUI_Z_INDEX_LAYER);
}

/**
* Sets the "tabindex" attribute of the DOM element.
*
Expand Down Expand Up @@ -2200,7 +2224,10 @@ public Node lastChild() {
*/
@Editor.Ignore
public DominoElement<HTMLElement> parent() {
return elementOf(Js.<HTMLElement>uncheckedCast(element().parentElement));
if (nonNull(element().parentElement)) {
return elementOf(Js.<HTMLElement>uncheckedCast(element().parentElement));
}
return null;
}

/**
Expand Down
Loading

0 comments on commit 077b291

Please sign in to comment.