Виджеты
Виджет это часть плагина Pano (полоса цели, лучшие поддержавшие, статистика магазина), которую можно вставить на любую веб-страницу как собственный HTML-тег. Он приносит свои данные и свой стиль.
Встраивание
<script type="module" src="https://pano.example.com/api/v1/widgets/loader.js"></script>
<pano-market-goal></pano-market-goal>Загрузчик небольшой. Он спрашивает Pano, какие виджеты существуют, и загружает виджет, когда его тег впервые появляется на странице, в том числе добавленный позже. Неизвестные теги pano-* игнорируются.
Посмотрите, что предлагает ваш Pano:
curl http://localhost:8088/api/v1/widgets/index.jsonТеги выглядят как pano-<короткое имя плагина>-<виджет>. У неактивного плагина виджетов нет, и его теги остаются пустыми.
Стиль
Виджеты находятся в shadow root и берут вид по умолчанию из дизайн-токенов Pano. Стилизуйте их со своей страницы через CSS-переменные, на странице или на одном элементе:
:root { --pano-color-primary: #e33; }
pano-market-goal { --pano-color-primary: #28a; }Палитру задайте на скрипте через data-palette="dark" (по умолчанию light) или на отдельном элементе через data-bs-theme="dark". Язык текста берётся из data-locale скрипта, иначе из сайта.
Для более глубоких изменений каждая часть виджета открыта через part:
pano-market-goal::part(market-goal__bar) { border-radius: 0; }Добавьте атрибут no-shadow, чтобы рисовать виджет в обычной странице: CSS вашей страницы тогда достаёт внутрь.
Атрибуты
Простые настройки виджета (текст, числа, переключатели) это атрибуты в kebab-case; список виджетов в /api/v1/widgets/index.json называет их в attrs. Всё более сложное задаётся как свойство элемента после его создания:
document.querySelector('pano-market-goal').someSetting = 'value';Изменение атрибута обновляет виджет без перезагрузки.
События
События всплывают и пересекают границу shadow:
| Событие | Когда | Детали |
|---|---|---|
pano:ready | Данные загружены, виджет показан | { tag } |
pano:error | Загрузка не удалась | { code } |
pano:toast | Виджет хочет показать сообщение | { key, message, variant, values } |
pano:navigate | Виджет хочет перейти на страницу | { url } |
pano:toast и pano:navigate можно отменить через preventDefault(), чтобы ими занялась ваша страница:
document.addEventListener('pano:navigate', (e) => { e.preventDefault(); router.go(e.detail.url); });Направьте ссылки виджетов на свои страницы через карту URL:
window.PanoWidgets.configure({ urls: { 'market.store': '/shop', 'market.order': '/shop/o/{id}', 'auth.login': '/login' } });Какой адрес использовать
| Ваша страница | Адрес загрузчика | Вход посетителя |
|---|---|---|
| На собственном адресе Pano | https://pano.example.com/api/v1/widgets/loader.js | Куки, работает |
| На разрешённом источнике | Тот же | Куки, работает |
| На любом другом домене | Путь на вашем сайте, пересылающий на Pano, например /pano/api/v1/widgets/loader.js | Через ваш сервер (шаблон так и делает) |
Pano даёт CORS только разрешённым источникам, поэтому страница на чужом домене загружает виджеты через собственный прокси-путь. За префиксом пути загрузчику настройка не нужна: он выводит /api/v1 из своего адреса.
Для публичных (анонимных) виджетов хватит простого правила обратного прокси. Маршрут /pano в стартовом шаблоне пересылает ещё и сессию посетителя.
Для авторов плагинов
Пометьте блочный view как виджет в его метаданных, остальное сделает сборка:
<script module>export const view = { widget: true };</script>