All Projects → hal → elemento

hal / elemento

Licence: Apache-2.0 license
Builder API and other goodies for Elemental2

Programming Languages

java
68154 projects - #9 most used programming language
shell
77523 projects
sed
78 projects

Projects that are alternatives of or similar to elemento

Domino Ui
Domino-ui
Stars: ✭ 138 (+53.33%)
Mutual labels:  builder, gwt
grapesjs-plugin-forms
Set of form components and blocks for the GrapesJS editor
Stars: ✭ 39 (-56.67%)
Mutual labels:  builder
domino-mvp
domino-mvp
Stars: ✭ 25 (-72.22%)
Mutual labels:  gwt
patterns
Good practices to create code in Java, open to other languages. ⚡
Stars: ✭ 14 (-84.44%)
Mutual labels:  builder
damb
An advanced module builder for Dolibarr ERP/CRM
Stars: ✭ 14 (-84.44%)
Mutual labels:  builder
react-json-logic
Build and evaluate JsonLogic with React components
Stars: ✭ 21 (-76.67%)
Mutual labels:  builder
elastic-composer
Client-side Elasticsearch query generator and executor. Filter fields, find search suggestions, and paginate query results for your indicies using a simple, reactive, and high-level API
Stars: ✭ 14 (-84.44%)
Mutual labels:  builder
ECSEntityBuilder
Unity ECS Entity Builder/Wrapper
Stars: ✭ 39 (-56.67%)
Mutual labels:  builder
o2d3m
Wavefront OBJ to Doom3 map converter.
Stars: ✭ 15 (-83.33%)
Mutual labels:  builder
AdvancedSQL
The best Java query builder/SQL connector.
Stars: ✭ 23 (-74.44%)
Mutual labels:  builder
designable
🧩 Make everything designable 🧩
Stars: ✭ 2,156 (+2295.56%)
Mutual labels:  builder
ocibuilder
A tool to build OCI compliant images
Stars: ✭ 63 (-30%)
Mutual labels:  builder
dotnet-design-patterns-samples
The samples of .NET design patterns
Stars: ✭ 25 (-72.22%)
Mutual labels:  builder
sphinx-markdown-builder
sphinx builder that outputs markdown files.
Stars: ✭ 135 (+50%)
Mutual labels:  builder
gwt-boot-awesome-lili
Collection of JavaScript Libraries with JsInterop Interfaces and Others - GWT Awesome Library List (Gwit a LiLi)
Stars: ✭ 29 (-67.78%)
Mutual labels:  gwt
atom-perl6-editor-tools
A collection of useful Perl 6 editor tools
Stars: ✭ 19 (-78.89%)
Mutual labels:  builder
gwt-material-addins
Custom Components for gwt-material.
Stars: ✭ 35 (-61.11%)
Mutual labels:  gwt
Scripts-Sploits
A number of scripts POC's and problems solved as pentests move along.
Stars: ✭ 37 (-58.89%)
Mutual labels:  builder
keypirinha-theme-builder
A tool to create themes for Keypirinha launcher
Stars: ✭ 25 (-72.22%)
Mutual labels:  builder
Amazon-Product-Advertising-API-URL-Builder
Build Amazon Product Advertising API request URLs without having to read the documentation or study the used hashing algorithms.
Stars: ✭ 27 (-70%)
Mutual labels:  builder

Verify Codebase Maven Central GWT3/J2CL compatible Chat on Gitter

Elemento

Elemento simplifies working with GWT Elemental2. In a nutshell Elemento brings the following features to the table:

  • Type safe builders, event handlers and CSS selectors
  • Helper methods to manipulate the DOM tree
  • Ready to be used with current and future GWT releases and J2CL
  • Minimal dependencies
    • Elemental2 1.1.0 (elemental2-core, elemental2-dom and elemental2-webstorage)
    • GWT project (org.gwtproject.event:gwt-event and org.gwtproject.safehtml:gwt-safehtml) or
    • GWT.com (com.google.gwt:gwt-user)

TOC

Get Started

Elemento is available in Maven Central. To use it add the following dependency to your POM:

<dependency>
    <groupId>org.jboss.elemento</groupId>
    <artifactId>elemento-core</artifactId>
    <version>1.0.10</version>
</dependency>

In your GWT module inherit from org.jboss.elemento.Core:

<module>
    <inherits name="org.jboss.elemento.Core"/>
</module>

Builder API

When working with GWT Elemental it is often awkward and cumbersome to create an hierarchy of elements. Even simple structures like

<section class="main">
    <input class="toggle-all" type="checkbox">
    <label for="toggle-all">Mark all as complete</label>
    <ul class="todo-list">
        <li>
            <div class="view">
                <input class="toggle" type="checkbox" checked>
                <label>Taste Elemento</label>
                <button class="destroy"></button>
            </div>
            <input class="edit">
        </li>
    </ul>
</section>

lead to a vast amount of Document.createElement() and chained Node.appendChild() calls. With Elemento creating the above structure is as easy as

import static org.jboss.elemento.Elements.*;
import static org.jboss.elemento.InputType.checkbox;
import static org.jboss.elemento.InputType.text;

HTMLElement section = section().css("main")
        .add(input(checkbox).id("toggle-all").css("toggle-all"))
        .add(label()
                .apply(l -> l.htmlFor = "toggle-all")
                .textContent("Mark all as complete"))
        .add(ul().css("todo-list")
                .add(li()
                        .add(div().css("view")
                                .add(input(checkbox)
                                        .css("toggle")
                                        .checked(true))
                                .add(label().textContent("Taste Elemento"))
                                .add(button().css("destroy")))
                        .add(input(text).css("edit"))))
        .element();

The class Elements provides convenience methods to create the most common elements. It uses a fluent API to create and append elements on the fly. Take a look at the API documentation for more details.

References

When creating large hierarchies of elements you often need to assign an element somewhere in the tree. Use an inline assignment together with element() to create and assign the element in one go:

import static org.jboss.elemento.Elements.*;

final HTMLElement count;
final HTMLElement footer = footer()
        .add(count = span().css("todo-count").element())
        .element();

Event Handlers

Elemento provides methods to easily register event handlers. There are constants for most of the known event types.

You can either add event handlers when building the element hierarchy:

import static org.jboss.elemento.Elements.*;
import static org.jboss.elemento.EventType.*;
import static org.jboss.elemento.InputType.checkbox;
import static org.jboss.elemento.InputType.text;

HTMLLIElement listItem = li()
        .add(div().css("view")
                .add(input(checkbox)
                        .css("toggle")
                        .on(change, event -> toggle()))
                .add(label()
                        .textContent("Taste Elemento")
                        .on(dblclick, event -> edit()))
                .add(button()
                        .css("destroy")
                        .on(click, event -> destroy())))
        .add(input(text)
                .css("edit")
                .on(keydown, this::keyDown)
                .on(blur, event -> blur()))
        .element();

or register them later using EventType.bind():

import org.gwtproject.event.shared.HandlerRegistration;
import static elemental2.dom.DomGlobal.alert;
import static org.jboss.elemento.EventType.bind;
import static org.jboss.elemento.EventType.click;

HandlerRegistration handler = bind(listItem, click, event -> alert("Clicked"));

The latter approach returns org.gwtproject.event.shared.HandlerRegistration which you can use to remove the handler again.

In order to make it easier to work with keyboard events, Elemento provides an enum with the most common keyboard codes:

import elemental2.dom.KeyboardEvent;
import static org.jboss.elemento.Key.Escape;
import static org.jboss.elemento.Key.Enter;

void keyDown(KeyboardEvent event) {
    if (Escape.match(event)) {
        ...
    } else if (Enter.match(event)) {
        ...
    }
}

Typesafe CSS Selectors

Elemento provides a typesafe selector API. It can be used to express simple CSS selector like .class or #id up to complex selectors like

#main [data-list-item|=foo] a[href^="http://"] > .fas.fa-check, .external[hidden]

This selector can be created with

import org.jboss.elemento.By;
import static org.jboss.elemento.By.AttributeOperator.CONTAINS_TOKEN;
import static org.jboss.elemento.By.AttributeOperator.STARTS_WITH;

By selector = By.group(
        By.id("main")
                .desc(By.data("listItem", CONTAINS_TOKEN, "foo")
                        .desc(By.element("a").and(By.attribute("href", STARTS_WITH, "http://"))
                                .child(By.classname(new String[]{"fas", "fa-check"})))),
        By.classname("external").and(By.attribute("hidden"))
);

The selector can be used to find single or all HTML elements:

import org.jboss.elemento.By;
import static org.jboss.elemento.By.AttributeOperator.STARTS_WITH;
import static org.jboss.elemento.Elements.a;
import static org.jboss.elemento.Elements.body;

By selector = By.element("a").and(By.attribute("href", STARTS_WITH, "http://"));
for (HTMLElement element : body().findAll(selector)) {
    a(element).css("external");
}

Custom Elements

Elemento makes it easy to create custom elements. As for Elemento custom elements are a composite of HTML elements and / or other custom elements. They're ordinary classes which can hold state or register event handlers. The only requirement is to implement IsElement<E extends HTMLElement> and return a root element:

import static org.jboss.elemento.Elements.*;

class TodoItemElement implements IsElement<HTMLElement> {
    
    private final HTMLElement root;
    private final HTMLInputElement toggle;
    private final HTMLElement label;
    private final HTMLInputElement summary;

    TodoItemElement(TodoItem item) {
        this.root = li().data("item", item.id)
                .add(div().css("view")
                        .add(toggle = input(checkbox).css("toggle")
                                .checked(item.completed)
                                .element())
                        .add(label = label().textContent(item.text).element())
                        .add(destroy = button().css("destroy").element()))
                .add(summary = input(text).css("edit").element())
                .element();
        this.root.classList.toggle("completed", item.completed);
    }
    
    @Override
    public HTMLElement element() {
        return root;
    }
    
    // event handlers omitted
}

The builder API has support for IsElement<E extends HTMLElement> which makes it easy to use custom elements when building the element hierarchy:

import static org.jboss.elemento.Elements.ul;

TodoItemRepository repository = ...;
TodoItemElement[] itemElements = repository.items().stream()
        .map(TodoItemElement::new)
        .toArray();
ul().addAll(itemElements).element();

Goodies

Besides the builder API, Elemento comes with a bunch of static helper methods that roughly fall into these categories:

  1. Get notified when an element is attached to and detached from the DOM tree.
  2. Iterate over elements.
  3. Methods to manipulate the DOM tree (add, insert and remove elements).
  4. Methods to manipulate an element.
  5. Methods to generate safe IDs.

See the API documentation of Elements for more details.

Attach / Detach

Implement Attachable to get notified when an element is attached to and detached from the DOM tree. The attachable interface provides a static method to easily register the callbacks to attach(MutationRecord) and detach(MutationRecord):

import elemental2.dom.MutationRecord;
import org.jboss.elemento.Attachable;
import org.jboss.elemento.IsElement;
import static elemental2.dom.DomGlobal.console;
import static org.jboss.elemento.Elements.li;

class TodoItemElement implements IsElement<HTMLElement>, Attachable {
    
    private final HTMLElement root;

    TodoItemElement(TodoItem item) {
        this.root = li().element();
        Attachable.register(root, this);
    }
    
    @Override
    public HTMLElement element() {
        return root;
    }

    @Override
    public void attach(MutationRecord mutationRecord) {
        console.log("Todo item has been attached");
    }

    @Override
    public void detach(MutationRecord mutationRecord) {
        console.log("Todo item has been detached");
    }
}

Elemento uses the MutationObserver API to detect changes in the DOM tree and passes an MutationRecord instance to the attach(MutationRecord) and detach(MutationRecord) methods. This instance contains additional information about the DOM manipulation.

Iterators / Iterables / Streams

Elemento provides several methods to iterate over node lists, child elements or elements returned by a selector. There are methods which return Iterator, Iterable and Stream.

See the API documentation of Elements for more details.

GWT.com

Elemento depends on GWT project dependencies (org.gwtproject.event:gwt-event and org.gwtproject.safehtml:gwt-safehtml). For those still relying on GWT.com (com.google.gwt:gwt-user) there are -gwtcom compatible versions available.

To use it replace

<dependency>
    <groupId>org.jboss.elemento</groupId>
    <artifactId>elemento-core</artifactId>
    <version>1.0.10</version>
</dependency>

with

<dependency>
    <groupId>org.jboss.elemento</groupId>
    <artifactId>elemento-core</artifactId>
    <version>1.0.10-gwtcom</version>
</dependency>

The GWT.com compatible versions differ in the following points:

Dependencies

GWT Project

<dependency>
    <groupId>org.gwtproject.event</groupId>
    <artifactId>gwt-event</artifactId>
</dependency>
<dependency>
    <groupId>org.gwtproject.safehtml</groupId>
    <artifactId>gwt-safehtml</artifactId>
</dependency>

GWT.com

<dependency>
    <groupId>com.google.gwt</groupId>
    <artifactId>gwt-user</artifactId>
</dependency>

GWT Module

GWT Project

<inherits name="org.gwtproject.event.Event"/>
<inherits name="org.gwtproject.safehtml.SafeHtml"/>

GWT.com

<inherits name="com.google.gwt.event.Event"/>
<inherits name="com.google.gwt.safehtml.SafeHtml"/>

Classes

GWT Project

import org.gwtproject.safehtml.shared.SafeHtml;
import org.gwtproject.event.shared.HandlerRegistration;

GWT.com

import com.google.gwt.safehtml.shared.SafeHtml;
import com.google.web.bindery.event.shared.HandlerRegistration;

Samples

Elemento comes with different implementations of the TodoMVC application using different frameworks:

All samples are available online at https://hal.github.io/elemento-samples/

Contributing

If you want to contribute to Elemento, please follow the steps in contribution.

Get Help

If you need help feel free to contact us at Gitter, browse the API documentation or file an issue.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].