Тост

Тост — единственный компонент здесь, который не может быть статическим: он появляется в ответ на событие. Страница рисует пустую область через toasts(), а toast() из sitelo/ui/client в неё добавляет.

Эта область — вежливая live-регион, поэтому всё добавленное объявляется, не перехватывая фокус.

Подключение

Положите область куда угодно в body — она фиксированного позиционирования, так что место не важно:

import { toasts } from 'sitelo/ui'

body(
  // …страница…
  toasts(),
)

Это единственная часть рантайма, которую за вас ничто на странице не запускает, — а значит, единственная, до которой вы дотягиваетесь сами: прямо из атрибута события, без единого байта в бандле:

button({ onclick: "import('/su/toast.js').then(m=>m.toast('Сохранено.',{color:'success'}))" }, 'Сохранить')

Или из вашего собственного модуля, если он и так уже работает:

import { toast } from 'sitelo/ui/client'

toast('Сохранено.', { color: 'success' })

Попробуйте

Эта страница рисует область toasts(), а кнопки ниже сами подтягивают рантайм, поэтому действительно порождают тосты — справа внизу. Пока вы не нажмёте, не загружается ничего.

stack({ direction: 'row', gap: 'sm', wrap: true },
  button({
    variant: 'soft',
    color: 'success',
    onclick: "import('/su/toast.js').then(m=>m.toast('Сохранено.',{color:'success'}))",
  }, 'Success'),
  button({
    variant: 'soft',
    color: 'warning',
    onclick: "import('/su/toast.js').then(m=>m.toast('У двух страниц нет meta description.',{color:'warning'}))",
  }, 'Warning'),
  button({
    variant: 'soft',
    color: 'danger',
    onclick: "import('/su/toast.js').then(m=>m.toast('Сборка упала. Посмотрите отчёт по ссылкам.',{color:'danger'}))",
  }, 'Danger'),
  button({
    variant: 'soft',
    color: 'neutral',
    onclick: "import('/su/toast.js').then(m=>m.toast('Этот останется, пока вы его не закроете.',{color:'neutral',duration:0}))",
  }, 'До закрытия'),
)

Опции

duration — сколько тост держится, в миллисекундах; 0 оставляет его до тех пор, пока кто-нибудь не закроет. У каждого тоста есть кнопка закрытия, подключённая к тому же обработчику, что и у уведомления.

toast('Сохранено.', { color: 'success' })
toast('Всё ещё работаю…', { color: 'neutral', duration: 0 })
toast('Развёрнуто за 1,7 с', { color: 'success', duration: 8000 })

Что он рисует

Тост — это alert() внутри области тостов: та же разметка, те же цвета, та же кнопка закрытия. Учить нечего, оформлять дополнительно тоже.

Сохранено.
stack({ gap: 'sm', style: 'width: 100%; max-width: 24rem' },
  alert({ color: 'success', dismissible: true }, 'Сохранено.'),
  alert({ color: 'danger', dismissible: true }, 'Сборка упала. Посмотрите отчёт по ссылкам.'),
)

Когда его использовать

Тост подтверждает то, что читатель только что сделал. Для всего, на что нужно отреагировать или что нужно внимательно прочесть, это неподходящее место: он исчезает, его легко не заметить, а на статическом сайте большинство сообщений живут прямо в странице в виде alert().

Пропсы

toasts() собственных пропсов не принимает. toast() из sitelo/ui/client:

АргументТипПо умолчаниюОписание
messagestring—Текст. Ставится как textContent, поэтому никогда не разбирается как разметка.
color'primary' | 'neutral' | 'success' | 'warning' | 'danger''neutral'Какую палитру взять.
durationnumber4000Миллисекунд до исчезновения. 0 оставляет его висеть.

Возвращает добавленный элемент или null, если на странице нет области toasts().