Skip to content

Виджеты

Экран — это дерево виджетов в JSON. Поле type выбирает виджет, остальные поля — его параметры. Доступны все стандартные виджеты Stac и нативные виджеты дизайн-системы Mirea Ninja (app*).

Неизвестный type не роняет экран — он просто не рисуется. Перед отправкой жми «Предпросмотр» в форме публикации: дерево отрисуется тут же. При деплое через HTTP API сервер дополнительно вернёт список незнакомых type/actionType — опечатки видно сразу.

Виджеты дизайн-системы

Эти виджеты наследуют тему, типографику и токены приложения: тёмная и светлая темы подхватываются сами, апп выглядит как остальной интерфейс Mirea Ninja.

appButton

json
{
  "type": "appButton",
  "label": "Записаться",
  "variant": "primary",
  "size": "medium",
  "expanded": true,
  "onPressed": { "actionType": "showToast", "message": "Готово!" }
}
  • variant: primary | secondary | outline | ghost | danger
  • size: small | medium | large
  • expanded: растянуть на всю ширину

appCard

Плоская карточка-поверхность со скруглением, опционально кликабельная.

json
{
  "type": "appCard",
  "padding": 16,
  "onTap": { "actionType": "openPage", "path": "/details" },
  "child": { "type": "text", "data": "Содержимое карточки" }
}

appChip

Чип-фильтр в форме пилюли.

json
{ "type": "appChip", "label": "Все", "selected": true,
  "small": false, "color": "#7C5CFF", "onTap": { "actionType": "..." } }

appListRow

Строка списка: эмодзи-аватар, заголовок, сабтайтл и trailing-виджет. Складывай в appCard или column; у первой строки ставь isFirst: true, чтобы убрать верхний разделитель.

json
{
  "type": "appListRow",
  "title": "Физика",
  "subtitle": "ауд. А-401 · 10:40",
  "emoji": "📚",
  "emojiColor": "#2F7AFF",
  "isFirst": true,
  "trailing": { "type": "appMetaPill", "text": "скоро" },
  "onTap": { "actionType": "..." }
}

appServiceTile

Квадратная плитка-лаунчер 56×56 с эмодзи. solid: true — заливка цветом, false — тонировка. Раскладывай в wrap или row как сетку сервисов.

json
{ "type": "appServiceTile", "emoji": "🧮", "label": "GPA",
  "color": "#1FB872", "solid": true,
  "onTap": { "actionType": "openPage", "path": "/calc" } }

appMetaPill

Мета-пилюля для аудитории, времени, статуса.

json
{ "type": "appMetaPill", "text": "А-401", "strong": true }

appSmartChip

Чип «эмодзи + подпись + цветное значение» — компактная сводка (время в пути, остаток, счёт).

json
{ "type": "appSmartChip", "emoji": "🍲", "label": "Столовая",
  "value": "~8 мин", "tone": "#FFB020" }
  • tone (#RRGGBB) красит значение; по умолчанию — акцент.

appSectionTitle

Заголовок секции с опциональной ссылкой-действием справа.

json
{
  "type": "appSectionTitle",
  "title": "Топ недели",
  "subtitle": "по числу запусков",
  "action": "Все",
  "onActionTap": { "actionType": "openPage", "path": "/top" }
}

appEmptyState

Заглушка «пусто»: крупное эмодзи, заголовок, описание и вложенный виджет (например, кнопка).

json
{
  "type": "appEmptyState",
  "emoji": "🌴",
  "title": "Пока пусто",
  "subtitle": "Добавь первую запись",
  "child": { "type": "appButton", "label": "Добавить" }
}

appErrorState

json
{ "type": "appErrorState", "title": "Не загрузилось",
  "message": "Попробуй ещё раз", "primaryLabel": "Повторить",
  "onPrimary": { "actionType": "reload" } }

appLineIcon и appIconButton

Фирменный набор линейных иконок по имени из дизайн-системы: user, lock, search, home, calendar, map, grid, bell, settings, chevronR/L/D, plus, minus, filter, more, book, pin, heart, star, message, share, clock, check, shield, people, bolt, qr, mic, pencil, view, hide, close, mail, arrowRight и другие.

json
{ "type": "appLineIcon", "icon": "star", "size": 22, "color": "#FBBF24" }
json
{ "type": "appIconButton", "icon": "share",
  "variant": "secondary", "tooltip": "Поделиться",
  "onPressed": { "actionType": "share", "text": "..." } }

appTag и appLiveBadge

json
{ "type": "appTag", "label": "Live", "tone": "live", "withDot": true }

Тоны: accent | live | warn | danger | info | pink | mute | solid.

json
{ "type": "appLiveBadge", "label": "Сейчас" }

appAvatar и appAvatarStack

json
{ "type": "appAvatar", "name": "Иван Петров", "size": 36 }
json
{ "type": "appAvatarStack", "names": ["Иван", "Мария", "Олег"], "size": 32 }

appProgressRing

json
{ "type": "appProgressRing", "value": 0.72, "size": 64,
  "label": "72%", "sublabel": "готово", "color": "#34D399" }

appToggle

Плоский переключатель-пилюля. По сути серверный: на onChange пошли экшен, который вернёт дерево с уже перевёрнутым value (через reload, openPage или networkRequest). Для мгновенного локального переключения без перезагрузки используй setState.

json
{ "type": "appToggle", "value": true,
  "onChange": { "actionType": "setState", "key": "push", "value": false } }

appSegmentedControl

Сегменты в стиле iOS. Каждая опция несёт свой экшен — экран серверный, поэтому переключение обычно перерисовывает контент через openPage, networkRequest или setState.

json
{ "type": "appSegmentedControl", "selectedIndex": 0, "options": [
  { "label": "Сегодня", "onSelected": { "actionType": "openPage", "path": "/today" } },
  { "label": "Неделя", "onSelected": { "actionType": "openPage", "path": "/week" } }
]}

appStateScope

Граница локального реактивного состояния. Внутри читаются плейсхолдеры {{state.<key>}}, а экшен setState меняет их на лету — без перезагрузки экрана. Полное описание — на странице Состояние и хранилище.

json
{ "type": "appStateScope", "initial": { "count": 0 },
  "child": { "type": "text", "data": "Счёт: {{state.count}}" } }

Виджеты Stac

Полный каталог стандартных виджетов с параметрами — в документации Stac. Самые популярные:

ГруппаТипы
Каркасscaffold, appBar, safeArea, tabBar, tabBarView
Раскладкаcolumn, row, stack, padding, center, expanded, sizedBox, wrap, spacer
СпискиlistView, gridView, singleChildScrollView, listTile, refreshIndicator
Контентtext, image, icon, card, divider, chip, badge, circleAvatar
Вводform, textFormField, checkBox, radioGroup, slider, dropdownMenu
Логикаconditional, networkWidget, dynamicView, setValue

Картинки грузятся напрямую

Виджет image тянет URL без прокси. Используй стабильный https-хостинг и не клади в картинки ничего чувствительного.

Работает на Stac