org.dominokit.domino.ui.dropdown.DropdownAction Maven / Gradle / Ivy
package org.dominokit.domino.ui.dropdown;
import elemental2.core.JsRegExp;
import elemental2.core.JsString;
import elemental2.dom.DomGlobal;
import elemental2.dom.HTMLAnchorElement;
import elemental2.dom.HTMLElement;
import elemental2.dom.HTMLLIElement;
import org.dominokit.domino.ui.icons.BaseIcon;
import org.dominokit.domino.ui.style.Color;
import org.dominokit.domino.ui.utils.*;
import org.gwtproject.safehtml.shared.SafeHtmlBuilder;
import java.util.ArrayList;
import java.util.List;
import static java.util.Objects.nonNull;
import static org.jboss.elemento.Elements.*;
public class DropdownAction extends BaseDominoElement> implements HasSelectionHandler, T>, HasBackground> {
private static final String IGNORE_CASE_FLAG = "ig";
private HTMLLIElement liElement = li().element();
private T value;
private BaseIcon> icon;
private DominoElement content = DominoElement.of(span());
private HTMLAnchorElement aElement;
private List> selectionHandlers = new ArrayList<>();
private List> focusHandlers = new ArrayList<>();
private boolean autoClose = true;
private Color background;
private boolean filteredOut = false;
private boolean excludeFromSearchResults = false;
public static final JsRegExp REPLACER_REGEX = new JsRegExp("[-\\/\\\\^$*+?.()|[\\]{}]", "g");
public DropdownAction(T value, String displayValue) {
this(value, displayValue, null);
}
public DropdownAction(T value, String displayValue, BaseIcon> icon) {
this.value = value;
this.icon = icon;
init();
if (nonNull(icon)) {
aElement.appendChild(icon.element());
}
this.content.setTextContent(displayValue);
aElement.appendChild(this.content.element());
init(this);
}
public DropdownAction(T value, HTMLElement content) {
this.value = value;
this.content.appendChild(content);
init();
aElement.appendChild(this.content.element());
init(this);
}
private void init() {
aElement = a()
.attr("tabindex", "0")
.element();
liElement.appendChild(aElement);
liElement.setAttribute("role", "option");
liElement.addEventListener("click", evt -> {
evt.stopPropagation();
select();
evt.preventDefault();
});
aElement.addEventListener("focus", evt -> {
evt.stopPropagation();
focusHandlers.forEach(focusHandler -> focusHandler.onFocus(this));
});
}
public static DropdownAction create(String content) {
return create(content, content);
}
public static DropdownAction create(T value, String displayValue, BaseIcon> icon) {
return new DropdownAction<>(value, displayValue, icon);
}
public static DropdownAction create(T value, String displayValue) {
return new DropdownAction<>(value, displayValue);
}
public static DropdownAction create(T value, HTMLElement content) {
return new DropdownAction<>(value, content);
}
public DropdownAction focus() {
aElement.focus();
return this;
}
public DropdownAction select() {
selectionHandlers.forEach(handler -> handler.onSelection(getValue()));
return this;
}
@Override
public HTMLLIElement element() {
return liElement;
}
@Override
public DropdownAction addSelectionHandler(SelectionHandler selectionHandler) {
selectionHandlers.add(selectionHandler);
return this;
}
@Override
public DropdownAction removeSelectionHandler(SelectionHandler selectionHandler) {
selectionHandlers.remove(selectionHandler);
return this;
}
public T getValue() {
return value;
}
public HTMLElement getContent() {
return content.element();
}
@Override
public HTMLAnchorElement getClickableElement() {
return aElement;
}
public DropdownAction setDisplayValue(String displayValue) {
this.content.clearElement()
.appendChild(span()
.textContent(displayValue));
return this;
}
public DropdownAction setDisplayValue(BaseIcon> icon, String displayValue) {
this.content.clearElement()
.appendChild(icon)
.appendChild(TextNode.of(displayValue));
return this;
}
public DropdownAction setDisplayValue(HTMLElement content) {
this.content.clearElement()
.appendChild(content);
return this;
}
public DropdownAction addFocusHandler(FocusHandler focusHandler) {
focusHandlers.add(focusHandler);
return this;
}
public boolean isAutoClose() {
return autoClose;
}
public DropdownAction setAutoClose(boolean autoClose) {
this.autoClose = autoClose;
return this;
}
public DropdownAction filter() {
this.hide();
this.setFilteredOut(true);
return this;
}
public DropdownAction deFilter() {
this.show();
this.setFilteredOut(false);
return this;
}
public boolean isFilteredOut() {
return filteredOut;
}
void setFilteredOut(boolean filteredOut) {
this.filteredOut = filteredOut;
}
public boolean isExcludeFromSearchResults() {
return excludeFromSearchResults;
}
public DropdownAction setExcludeFromSearchResults(boolean excludeFromSearchResults) {
this.excludeFromSearchResults = excludeFromSearchResults;
return this;
}
@Override
public DropdownAction setBackground(Color background) {
if (nonNull(background)) {
if (nonNull(this.background)) {
DominoElement.of(getClickableElement())
.removeCss(this.background.getBackground());
if (nonNull(content)) {
DominoElement.of(content).removeCss(this.background.getBackground());
}
}
DominoElement.of(getClickableElement()).addCss(background.getBackground());
if (nonNull(content)) {
DominoElement.of(content).addCss(background.getBackground());
}
this.background = background;
}
return this;
}
public void highlight(String displayValue, Color highlightColor) {
if (nonNull(this.content)) {
String innerHTML = this.content.getTextContent();
String escapedSearchValue = new JsString(displayValue).replace(REPLACER_REGEX, "\\$&");
JsRegExp regExp = new JsRegExp(escapedSearchValue, IGNORE_CASE_FLAG);
innerHTML = new JsString(innerHTML).replace(regExp, (valueToReplace, p1) -> {
if (nonNull(highlightColor)) {
return "" + valueToReplace + "";
}
return "" + valueToReplace + "";
});
innerHtml(this.content.element(), new SafeHtmlBuilder().appendHtmlConstant(innerHTML).toSafeHtml());
}
}
@FunctionalInterface
public interface FocusHandler {
void onFocus(DropdownAction dropdownAction);
}
}