Alert
Status Alert
A service status summary: the dot pulses only when something is wrong, and the time of the last update is always shown.
- alert
- status
- uptime
- incident
Preview
1440pxHost theme
Use it with AI
- 1. Copy the link.
- 2. Write to your agent in your own words and drop the link into the sentence.
- 3. The agent opens the link and installs the component from the registry.
put this in the header: https://vibeui.ru/c/alert-014?lang=en
Publishing is slower than usualОчередь сборки перегружена. Сайты работают, новые публикации занимают до 10 минут.updated 2 minutes agoСтатус сервисов
Show the full instructions
What the link says, spelled out. Use it when your agent cannot open links — paste this text instead.
# Install and place "alert-014" (Status Alert) from VibeUI
## 1. Install first — do not skip, do not recreate
Run this exact command before writing any code:
npx shadcn@latest add https://vibeui.ru/r/alert-014.json
Registry item: https://vibeui.ru/r/alert-014.json
Installs to: components/vibeui/alert-014.tsx (the exact path follows this project's components.json aliases).
npm dependencies: none.
Registry dependencies: none.
Install it from the registry. Do not recreate it from the description,
do not substitute a similar component from another library, and do not
rewrite it to match the project's existing style.
## 2. What it is
A service status summary: the dot pulses only when something is wrong, and the time of the last update is always shown.
A service status summary: a coloured dot, a heading, an explanation, the update time and a link to the status page. Four states — operational, degraded, down, maintenance. Only the abnormal ones pulse. Zero dependencies, one file, its own palette.
## 3. How to use it
import { Alert014 } from "@/components/vibeui/alert-014"
<Alert014
state="degraded"
title="Publishing is slower than usual"
updated="updated 2 minutes ago"
statusHref="https://status.example.com"
/>
Read the installed file for the full prop list.
## 4. Where to place it
This is a small inline component. Put it exactly where the user asked,
inside the existing markup. Do not create a new page, section or
wrapper for it. If a similar control already sits in that spot,
replace it instead of adding a second one.
Placement: ___
(The user fills this line in. If it is still blank, ask where to put it
instead of guessing.)
## 5. Keep exactly as installed
- the local --vibeui-alert-014-* palette — do not swap it for your theme tokens (bg-success, bg-destructive and the like)
- the pulse on abnormal states only: a steady state must not blink on screen for hours
- the timestamp: without it a summary is indistinguishable from a stale page
- role="alert" only on a full outage — degradation should not interrupt reading
- the link to the status page: the detail lives there, not in the alert
- the @container query that moves the timestamp to its own line in a narrow column
- the <style> block inside the component — it holds the palette, the states and the pulse
## 6. You may change
- state: operational, degraded, down, maintenance
- the title and description copy
- updated — when the summary was refreshed
- statusLabel and statusHref — the status page link
- width and outer spacing through className
## 7. Rules
- The component polls nothing: the state and the time come from outside. Refreshing every minute is the caller's job.
- Do not show the operational state permanently: an "all systems go" banner on every page devalues the warnings.
- The description should say what is affected rather than "there are problems": people need to know whether to wait.
- Do not lift the CSS variables into globals.css: the component has to stay a single file.
## 8. Verify
- it renders with no console errors;
- it looks like the preview on the VibeUI page you copied this from;
- if it does not, you changed something listed in section 5 — put it back.For developers
npx shadcn@latest add https://vibeui.ru/r/alert-014.jsonhttps://vibeui.ru/r/alert-014.jsonКомпонент самодостаточен: один файл, без зависимостей, собственная палитра в локальных переменных --vibeui-alert-014-*. Четыре состояния переключаются data-атрибутом и меняют одну переменную цвета. Пульс — псевдоэлемент точки с анимацией масштаба, и он включён только для нештатных состояний: ровное не должно моргать часами. Роль alert выставляется только при полном отказе.
Component source
The same file your agent installs. Here in case you would rather copy it by hand.
import type { ComponentPropsWithoutRef, CSSProperties } from "react"
export type Alert014State = "operational" | "degraded" | "down" | "maintenance"
export type Alert014Props = Omit<
ComponentPropsWithoutRef<"div">,
"title" | "children"
> & {
state?: Alert014State
title?: string
description?: string
/** Когда обновлялась сводка: «обновлено 2 минуты назад». */
updated?: string
statusLabel?: string
statusHref?: string
}
// Идея компонента: состояние сервиса. Точка слева пульсирует только когда
// что-то не так — ровное состояние не должно моргать на экране часами.
// Время последнего обновления обязательно: сводка без отметки времени не
// отличается от зависшей страницы.
const STYLES = `
:where([data-vibeui-block="alert-014"]){
--vibeui-alert-014-fg:oklch(0.24 0.016 265);
--vibeui-alert-014-muted:oklch(0.5 0.014 265);
--vibeui-alert-014-bg:oklch(1 0 0);
--vibeui-alert-014-border:oklch(0.9 0.006 265);
--vibeui-alert-014-state:oklch(0.58 0.15 152);
--vibeui-alert-014-radius:0.75rem;
--vibeui-alert-014-font:ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
container-type:inline-size;
}
[data-vibeui-block="alert-014"]{
/* flex-wrap живёт здесь, а не в @container: контейнерный запрос применяется
к потомкам контейнера, но не к нему самому. На широкой раскладке перенос
ни на что не влияет — всё умещается в строку. */
display:flex;flex-wrap:wrap;align-items:center;gap:0.75rem;
width:100%;box-sizing:border-box;
padding:0.8125rem 1rem;
border:1px solid var(--vibeui-alert-014-border);
border-radius:var(--vibeui-alert-014-radius);
background:var(--vibeui-alert-014-bg);color:var(--vibeui-alert-014-fg);
font-family:var(--vibeui-alert-014-font);
}
[data-vibeui-block="alert-014"][data-state="degraded"]{--vibeui-alert-014-state:oklch(0.68 0.15 70)}
[data-vibeui-block="alert-014"][data-state="down"]{--vibeui-alert-014-state:oklch(0.56 0.19 25)}
[data-vibeui-block="alert-014"][data-state="maintenance"]{--vibeui-alert-014-state:oklch(0.58 0.18 262)}
[data-vibeui-block="alert-014"] [data-part="dot"]{
position:relative;flex:none;width:0.625rem;height:0.625rem;border-radius:9999px;
background:var(--vibeui-alert-014-state);
}
/* Пульс только у нештатных состояний: ровное не моргает часами на экране. */
[data-vibeui-block="alert-014"]:not([data-state="operational"]) [data-part="dot"]::after{
content:"";position:absolute;inset:0;border-radius:inherit;
background:inherit;
animation:vibeui-alert-014-pulse 1.8s ease-out infinite;
}
@keyframes vibeui-alert-014-pulse{
0%{transform:scale(1);opacity:.6}
100%{transform:scale(2.6);opacity:0}
}
[data-vibeui-block="alert-014"] [data-part="text"]{display:flex;flex-direction:column;gap:0.125rem;flex:1 1 auto;min-width:0}
[data-vibeui-block="alert-014"] [data-part="title"]{font-size:0.875rem;font-weight:600;line-height:1.35}
[data-vibeui-block="alert-014"] [data-part="description"]{font-size:0.8125rem;line-height:1.5;color:var(--vibeui-alert-014-muted)}
[data-vibeui-block="alert-014"] [data-part="updated"]{
flex:none;font-size:0.75rem;color:var(--vibeui-alert-014-muted);white-space:nowrap;
}
[data-vibeui-block="alert-014"] [data-part="link"]{
flex:none;color:var(--vibeui-alert-014-state);
font-size:0.8125rem;font-weight:600;text-decoration:none;
border-bottom:1px solid transparent;transition:border-color .16s ease;
}
[data-vibeui-block="alert-014"] [data-part="link"]:hover{border-bottom-color:currentColor}
[data-vibeui-block="alert-014"] [data-part="link"]:focus-visible{outline:2px solid var(--vibeui-alert-014-state);outline-offset:3px}
@container (max-width: 30rem){
/* Текст держит первую строку, отметка времени уходит под него. */
[data-vibeui-block="alert-014"] [data-part="text"]{flex:1 1 60%}
[data-vibeui-block="alert-014"] [data-part="updated"]{order:4;width:100%;padding-left:1.375rem}
}
@media (prefers-reduced-motion:reduce){[data-vibeui-block="alert-014"] *{animation:none!important;transition:none!important}}
`
/**
* Сводка состояния сервиса: точка, отметка времени и ссылка на статус.
* Один файл, ноль зависимостей, собственная палитра.
*/
export function Alert014({
state = "degraded",
title = "Публикация идёт медленнее обычного",
description = "Очередь сборки перегружена. Сайты работают, новые публикации занимают до 10 минут.",
updated = "обновлено 2 минуты назад",
statusLabel = "Статус сервисов",
statusHref = "#status",
className,
style,
...props
}: Alert014Props) {
return (
<>
<style href="vibeui-alert-014" precedence="medium">
{STYLES}
</style>
<div
{...props}
data-vibeui-block="alert-014"
data-state={state}
role={state === "down" ? "alert" : "status"}
className={className}
style={style as CSSProperties}
>
<span data-part="dot" aria-hidden="true" />
<span data-part="text">
<span data-part="title">{title}</span>
{description ? (
<span data-part="description">{description}</span>
) : null}
</span>
{updated ? <span data-part="updated">{updated}</span> : null}
{statusLabel ? (
<a data-part="link" href={statusHref}>
{statusLabel}
</a>
) : null}
</div>
</>
)
}