Произвольный макет кнопки

Open in CodeSandbox

Макеты объектов можно создавать с помощью фабрики templateLayoutFactory, используя текстовые шаблоны.

В данном примере создается пользовательский макет кнопки. Макет элемента управления строится на основе его данных, состояния и опций.

Макет автоматически перестраивается при изменении значений полей, состояния или опций, которые используются в его текстовом шаблоне.

<!DOCTYPE html>

<html>
    <head>
        <title>Произвольный макет кнопки</title>
        <meta
            http-equiv="Content-Type"
            content="text/html; charset=utf-8"
        />
        <!--
        Укажите свой API-ключ. Тестовый ключ НЕ БУДЕТ работать на других сайтах.
        Получить ключ можно в Кабинете разработчика: https://developer.tech.yandex.ru/keys/
    -->
        <script
            src="https://api-maps.yandex.ru/2.1/?lang=ru_RU&amp;apikey=<ваш API-ключ>"
            type="text/javascript"
        ></script>
        <script src="button_layout.js" type="text/javascript"></script>
        <style>
            html,
            body,
            #map {
                width: 100%;
                height: 100%;
                padding: 0;
                margin: 0;
            }

            .my-button {
                display: inline-block;
                padding: 3px 5px;
                background: #eee;
                border: 1px solid #bbb;
                border-radius: 3px;
                cursor: pointer;
                -webkit-user-select: none;
                -moz-user-select: none;
                user-select: none;
            }
            .my-button__text {
                font-family: "Arial", sans-serif;
                font-size: 14px;
                color: #333;
                margin-left: 10px;
            }

            .my-button__img {
                padding: 0;
                margin-bottom: -3px;
            }

            .my-button_small .my-button__text {
                display: none;
            }

            .my-button_medium .my-button__img {
                display: none;
            }

            .my-button_large .my-button__text {
                margin-left: 10px;
            }
            .my-button-selected {
                color: #333333;
                background-color: #e6e6e6;
                border: 2px dashed #333;
            }
        </style>
    </head>

    <body>
        <div id="map"></div>
    </body>
</html>
ymaps.ready(init);

function init() {
    var myMap = new ymaps.Map("map", {
            center: [55.650625, 37.62708],
            zoom: 10,
            controls: [],
        }),
        /*
         * Макет кнопки должен отображать поле data.content
         * и изменяться в зависимости от того, нажата ли кнопка или нет.
         * Текущий размер (small, medium, large) рассчитывается исходя из значения опции maxWidth
         * @see https://api.yandex.ru/maps/doc/jsapi/2.1/ref/reference/control.Button.xml#param-parameters
         */
        ButtonLayout = ymaps.templateLayoutFactory.createClass(
            [
                '<div title="{{ data.title }}" class="my-button ',
                '{% if state.size == "small" %}my-button_small{% endif %}',
                '{% if state.size == "medium" %}my-button_medium{% endif %}',
                '{% if state.size == "large" %}my-button_large{% endif %}',
                '{% if state.selected %} my-button-selected{% endif %}">',
                '<img class="my-button__img" src="{{ data.image }}" alt="{{ data.title }}">',
                '<span class="my-button__text">{{ data.content }}</span>',
                "</div>",
            ].join("")
        ),
        button = new ymaps.control.Button({
            data: {
                content: "Жмак-жмак-жмак",
                image: "pen.svg",
                title: "Жмак-жмак-жмак",
            },
            options: {
                layout: ButtonLayout,
                maxWidth: [170, 190, 220],
            },
        });

    myMap.controls.add(button, {
        position: {
            right: 5,
            top: 5,
        },
    });
}