All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.vaadin.flow.data.renderer.LitRenderer Maven / Gradle / Ivy

There is a newer version: 24.5.5
Show newest version
/*
 * Copyright 2000-2024 Vaadin Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.vaadin.flow.data.renderer;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.regex.Pattern;

import com.vaadin.flow.component.UI;
import com.vaadin.flow.component.dependency.JsModule;
import com.vaadin.flow.data.provider.DataGenerator;
import com.vaadin.flow.data.provider.DataKeyMapper;
import com.vaadin.flow.dom.Element;
import com.vaadin.flow.function.SerializableBiConsumer;
import com.vaadin.flow.function.SerializableConsumer;
import com.vaadin.flow.function.ValueProvider;
import com.vaadin.flow.internal.JsonSerializer;
import com.vaadin.flow.internal.JsonUtils;
import com.vaadin.flow.internal.UsageStatistics;
import com.vaadin.flow.internal.nodefeature.ReturnChannelMap;
import com.vaadin.flow.internal.nodefeature.ReturnChannelRegistration;
import com.vaadin.flow.shared.Registration;

import elemental.json.JsonArray;

/**
 * LitRenderer is a {@link Renderer} that uses a Lit-based template literal to
 * render given model objects in the components that support the JS renderer
 * functions API. Mainly it's intended for use with {@code Grid},
 * {@code ComboBox} and {@code VirtualList}, but is not limited to these.
 *
 * @author Vaadin Ltd
 * @since 22.0.
 *
 * @param 
 *            the type of the model object used inside the template expression
 *
 * @see #of(String)
 * @see https://lit.dev/docs/templates/overview/
 * @see <vaadin-combo-box>.renderer
 */
@JsModule("./lit-renderer.ts")
public class LitRenderer extends Renderer {

    static {
        UsageStatistics.markAsUsed("flow-components/LitRenderer", null);
    }

    private final String templateExpression;

    private final String DEFAULT_RENDERER_NAME = "renderer";

    private final String propertyNamespace;

    private final Map> valueProviders = new HashMap<>();
    private final Map> clientCallables = new HashMap<>();

    private final String ALPHANUMERIC_REGEX = "^[a-zA-Z0-9]+$";

    private LitRenderer(String templateExpression) {
        this.templateExpression = templateExpression;

        // Generate a unique (in scope of the UI) namespace for the renderer
        // properties.
        int litRendererCount = UI.getCurrent().getElement()
                .getProperty("__litRendererCount", 0);
        UI.getCurrent().getElement().setProperty("__litRendererCount",
                litRendererCount + 1);
        propertyNamespace = "lr_" + litRendererCount + "_";
    }

    /**
     * Creates a new LitRenderer based on the provided template expression. The
     * expression accepts content that is allowed inside JS template literals,
     * and works with the Lit data binding syntax.
     * 

* The template expression has access to: *

    *
  • {@code item} the model item being rendered
  • *
  • {@code index} the index of the current item (when rendering a * list)
  • *
  • {@code item.property} any property of the model item exposed via * {@link #withProperty(String, ValueProvider)}
  • *
  • any function exposed via * {@link #withFunction(String, SerializableConsumer)}
  • *
*

* Examples: * *

     * {@code
     * // Prints the `name` property of a person
     * LitRenderer. of("
Name: ${item.name}
") * .withProperty("name", Person::getName); * * // Prints the index of the item inside a repeating list * LitRenderer.of("${index}"); * } *
* * @param * the type of the input object used inside the template * * @param templateExpression * the template expression used to render items, not * null * @return an initialized LitRenderer * @see LitRenderer#withProperty(String, ValueProvider) * @see LitRenderer#withFunction(String, SerializableConsumer) */ public static LitRenderer of(String templateExpression) { Objects.requireNonNull(templateExpression); return new LitRenderer<>(templateExpression); } /** * @deprecated LitRenderer doesn't support {@code