> Markdown version of [Extending Components](https://vaadin.com/docs/v24/flow/create-ui/creating-components/extending-component). Section index: [llms.txt](https://vaadin.com/docs/v24/flow/llms.txt)

# Extending Components

You can create a new component by extending any existing component. For most components, there is a client-side component and a corresponding server-side component:

- **Client-side component**: Contains the HTML, CSS, and JavaScript, and defines a set of properties that determine the component’s behavior on the client side.

- **Server-side component**: Contains Java code that allows client-side properties to be changed, and manages the component’s behavior on the server side.

You can extend a component on either the server side or the client side. These are alternative approaches that are mutually exclusive.

This section demonstrates the two different approaches to achieving the **same changes** to the prebuilt text field component.

## <a id="extending-a-component-using-the-server-side-approach"></a>Extending a Component Using the Server-side Approach

Extending a server-side component is useful when you want to add new functionality (as opposed to visual aspects) to an existing component. You might use this approach, for example, when automatically processing data, when adding default validators, or when combining multiple simple components into a field that manages complex data.

> **Tip: Consider using a Web Component**
>
> If your component contains a lot of logic that could conveniently be done on the client side, consider implementing it as a Web Component and creating a wrapper for it. This approach may offer a better user experience and result in less load on the server.

This example creates a `NumericField` component by extending the `TextField` component. The new component contains a default number that the user can change using **+** and **-** controls.

[Image: Number Field server side extension]

**Example**: Creating a `NumericField` component by extending the `TextField` component.

```java
@CssImport(value = "./styles/numeric-field-styles.css")
public class NumericField extends TextField {

    private Button substractBtn;
    private Button addBtn;

    private static final int DEFAULT_VALUE = 0;
    private static final int DEFAULT_INCREMENT = 1;

    private int numericValue;
    private int incrementValue;
    private int decrementValue;

    public NumericField() {
        this(DEFAULT_VALUE, DEFAULT_INCREMENT,
                -DEFAULT_INCREMENT);
    }

    public NumericField(int value, int incrementValue,
                        int decrementValue) {
        setNumericValue(value);
        this.incrementValue = incrementValue;
        this.decrementValue = decrementValue;

        setPattern("-?[0-9]*");
        setPreventInvalidInput(true);

        addChangeListener(event -> {
            String text = event.getSource().getValue();
            if (StringUtils.isNumeric(text)) {
                setNumericValue(Integer.parseInt(text));
            } else {
                setNumericValue(DEFAULT_VALUE);
            }
        });

        substractBtn = new Button("-", event -> {
            setNumericValue(numericValue +
                    decrementValue);
        });

        addBtn = new Button("+", event -> {
            setNumericValue(numericValue +
                    incrementValue);
        });

        addClassName("numeric");
        styleBtns();

        addToPrefix(substractBtn);
        addToSuffix(addBtn);
    }

    private void styleBtns() {
        substractBtn.addThemeName("icon");
        addBtn.addThemeName("icon");
    }

    public void setNumericValue(int value) {
        numericValue = value;
        setValue(value + "");
    }

    // getters and setters
}
```

As an alternative, you can extend the `Composite` class, which has a minimal API. This hides methods available in the more extensive API that’s exposed when your custom component extends an implementation of `Component`.

> **Note: Accessing, updating and querying elements**
>
> The `Element` API contains methods to update and query various parts of the element, such as the attributes. Every component has a `getElement()` method that allows you to access it. See [Creating a Component Using Multiple Elements](https://vaadin.com/docs/v24/flow/create-ui/creating-components/many-elements.md) for more.

Import additional styles for the component using the `@CssImport` annotation. Note that CSS selectors (based on the `numeric` class name applied to the component) must be used to scope the styles to this component.

**Example**: Creating `numeric-field-styles.css` to customize the appearance of the custom `vaadin-text-field` component.

`styles/numeric-field-styles.css`

```css
vaadin-text-field.numeric::part(input-field) {
    background-color: var(--lumo-base-color);
    border: 1px solid var(--lumo-contrast-30pct);
    box-sizing: border-box;
}

vaadin-text-field.numeric::part(value) {
    text-align: center;
}
```

<!-- vale Vaadin.ProductName = NO -->See [Styling Vaadin Components](https://vaadin.com/docs/v24/styling/styling-components.md) for more information.<!-- vale Vaadin.ProductName = YES -->

## <a id="extending-a-component-using-the-client-side-approach"></a>Extending a Component Using the Client-side Approach

Vaadin client-side components are based on [Polymer 3](https://polymer-library.polymer-project.org/3.0/docs/about_30), which supports extending existing components. You can use the `extends` property to extend existing Polymer elements.

A template can be inherited from another Polymer element in five ways:

1. Inheriting a base class template without modifying it.

2. Overriding a base class template in a child class.

3. Modifying a copy of a superclass template.

4. Extending a base class template in a child class.

5. Providing template-extension points in a base class for content from a child class.

### <a id="extending-by-modifying-a-copy-of-a-superclass-template"></a>Extending by Modifying a Copy of a Superclass Template

This example demonstrates how to create a new component by modifying a copy of a superclass template. You build a `NumberField` by extending `TextField`. The new component contains a default number that the user can change using **+** and **-** controls.

[Image: Number Field client side extension]

It’s important to remember that when a component template is extended, the properties and methods of the parent template become available to the child template.

> **Note: A child component uses the parent component’s template**
>
> By default, a child component uses the template of the parent component, unless the child component provides its own template by overriding the static getter method `template()`. The parent’s template is accessed using `super.template()`.

Next, specify the element from which the child component inherits. In this case, specify that `NumberField` inherits from `TextField`, including its properties and methods:

```javascript
import { html } from
   '@polymer/polymer/lib/utils/html-tag.js';
import { TextField } from '@vaadin/text-field';

let memoizedTemplate;

class NumberField extends TextField {

    static get template() {
        if (!memoizedTemplate) {
            const superTemplate = super.template
                    .cloneNode(true);
            const inputField = superTemplate.content
                .querySelector('[part="input-field"]');
            const prefixSlot = superTemplate.content
            .querySelector('[name="prefix"]');
            const decreaseButton = html`<div
                part="decrease-button"
                on-click="_decreaseValue"></div>`;
            const increaseButton = html`<div
                part="increase-button"
                on-click="_increaseValue"></div>`;
            inputField.insertBefore(
                decreaseButton.content, prefixSlot);
            inputField.appendChild(
                increaseButton.content);
            memoizedTemplate = html`<style>
                 [part="decrease-button"]::before {
                   content: "−";
                 }

                 [part="increase-button"]::before {
                   content: "+";
                 }
               </style>
               ${superTemplate}`;
        }
        return memoizedTemplate;
    }

    static get is() {
        return 'vaadin-number-field';
    }

    static get properties() {
        return {
            decrementValue: {
              type: Number,
              value: -1,
              reflectToAttribute: true,
              observer: '_decrementChanged'
            },
            incrementValue: {
              type: Number,
              value: 1,
              reflectToAttribute: true,
              observer: '_incrementChanged'
            }

            // Note: the value is stored in the
            // TF's value property.
        };
    }

    _decreaseValue() {
        this.__add(this.decrementValue);
    }

    _increaseValue() {
        this.__add(this.incrementValue);
    }

    __add(value) {
        this.value = parseInt(this.value, 10) + value;
        this.dispatchEvent(
            new CustomEvent('change', {bubbles: true}));
    }

    _valueChanged(newVal, oldVal) {
        this.value = this.focusElement.value;
        super._valueChanged(this.value, oldVal);
    }

    /* ... */
}
```

To modify the template, override the `template()` static getter. The expression `${super.template}` inserts the base class template into the newly constructed template. The newly constructed template is memoized for further invocations of `template()`.

See [Inherit a template from another Polymer element](https://polymer-library.polymer-project.org/3.0/docs/devguide/dom-template#inherit) in the Polymer documentation for more.

`42913850-FAD3-4184-9B69-02F29B1A14CE`
