Skip to content
Navigation

Notice

Persistent, inline messaging that stays on the surface — information, progress, confirmation, warning or error. Transient feedback is a toast; something the user must act on before continuing is a dialog.

Added 14 October 2026

React

Codecomponents/react/notice-demo.tsx
import {Button, Notice, NoticeAction, NoticeDescription, NoticeTitle} from '@stroeer-labs/design-library/react';
import {CircleAlert, CircleCheck, Info, Megaphone, TriangleAlert} from 'lucide-react';

// Section order is mirrored in ../angular/notice-demo.ts — the two panes sit side by side on the site,
// which is what makes a parity break visible instead of inferred.
export function NoticeDemo() {
    return (
        <div className="grid w-full max-w-xl items-start gap-6">
            <div className="space-y-2">
                <p className="text-xs font-medium text-muted-foreground">Five tones — the tone is the tint, the border and the icon, never the text</p>
                <div className="grid gap-3">
                    <Notice>
                        <Megaphone />
                        <NoticeTitle>Declare what the advertising is about</NoticeTitle>
                        <NoticeDescription>You will see which sites accept the declared content.</NoticeDescription>
                    </Notice>
                    <Notice variant="info">
                        <Info />
                        <NoticeTitle>The plan saves automatically</NoticeTitle>
                        <NoticeDescription>Every line item edit is written through immediately.</NoticeDescription>
                    </Notice>
                    <Notice variant="success">
                        <CircleCheck />
                        <NoticeTitle>All 412 targeted sites accept the declared advertising</NoticeTitle>
                        <NoticeDescription>The compliance check finished with no blocks.</NoticeDescription>
                    </Notice>
                    <Notice variant="warning">
                        <TriangleAlert />
                        <NoticeTitle>Not saved — no hour selected</NoticeTitle>
                        <NoticeDescription>A line item must deliver in at least one hour, so this selection cannot be saved.</NoticeDescription>
                    </Notice>
                    <Notice variant="destructive">
                        <CircleAlert />
                        <NoticeTitle>The plan total is unavailable — no price came back.</NoticeTitle>
                        <NoticeDescription>Recalculate the plan, or adjust the line item budget.</NoticeDescription>
                    </Notice>
                </div>
            </div>

            <div className="space-y-2">
                <p className="text-xs font-medium text-muted-foreground">
                    <code className="font-mono">size="sm"</code> — for a notice inside a dense form section
                </p>
                <div className="grid gap-3">
                    <Notice size="sm" variant="info">
                        <Info />
                        <NoticeTitle>The plan saves automatically</NoticeTitle>
                        <NoticeDescription>Every line item edit is written through immediately.</NoticeDescription>
                    </Notice>
                    <Notice size="sm" variant="warning">
                        <TriangleAlert />
                        <NoticeTitle>Not saved — no hour selected</NoticeTitle>
                        <NoticeDescription>A line item must deliver in at least one hour, so this selection cannot be saved.</NoticeDescription>
                    </Notice>
                    <Notice size="sm" variant="destructive">
                        <CircleAlert />
                        <NoticeTitle>The plan total is unavailable — no price came back.</NoticeTitle>
                        <NoticeDescription>Recalculate the plan, or adjust the line item budget.</NoticeDescription>
                    </Notice>
                </div>
            </div>

            <div className="space-y-2">
                <p className="text-xs font-medium text-muted-foreground">One-liners — omit the description and the layout centres on a single row</p>
                <div className="grid gap-3">
                    <Notice variant="success">
                        <CircleCheck />
                        <NoticeTitle>All 412 targeted sites accept the declared advertising</NoticeTitle>
                    </Notice>
                    <Notice size="sm" variant="info">
                        <Info />
                        <NoticeTitle>The plan saves automatically</NoticeTitle>
                    </Notice>
                    <Notice size="sm">
                        <NoticeTitle>No icon, single row</NoticeTitle>
                    </Notice>
                </div>
            </div>

            <div className="space-y-2">
                <p className="text-xs font-medium text-muted-foreground">
                    Action slot — <code className="font-mono">size="sm"</code> takes a <code className="font-mono">size="xs"</code> button
                </p>
                <div className="grid gap-3">
                    <Notice variant="warning">
                        <TriangleAlert />
                        <NoticeTitle>Sites removed</NoticeTitle>
                        <NoticeDescription>3 sites are not available on this network, so they were removed.</NoticeDescription>
                        <NoticeAction>
                            <Button variant="ghost" size="sm">
                                Dismiss
                            </Button>
                        </NoticeAction>
                    </Notice>
                    <Notice size="sm" variant="warning">
                        <TriangleAlert />
                        <NoticeTitle>Sites removed</NoticeTitle>
                        <NoticeAction>
                            <Button variant="ghost" size="xs">
                                Dismiss
                            </Button>
                        </NoticeAction>
                    </Notice>
                </div>
            </div>

            <div className="space-y-2">
                <p className="text-xs font-medium text-muted-foreground">Rich description — lists, paragraphs and links are styled by the slot</p>
                <Notice variant="destructive">
                    <CircleAlert />
                    <NoticeTitle>Unable to process your payment.</NoticeTitle>
                    <NoticeDescription>
                        <p>Please verify your billing information and try again.</p>
                        <ul className="list-inside list-disc text-sm">
                            <li>Check your card details</li>
                            <li>Ensure sufficient funds</li>
                            <li>Verify billing address</li>
                        </ul>
                    </NoticeDescription>
                </Notice>
            </div>
        </div>
    );
}

Angular

Codecomponents/angular/notice-demo.ts
import '@angular/compiler';
import {Component} from '@angular/core';
import {NgIcon, provideIcons} from '@ng-icons/core';
import {lucideCircleAlert, lucideCircleCheck, lucideInfo, lucideMegaphone, lucideTriangleAlert} from '@ng-icons/lucide';
import {HlmButtonImports, HlmNoticeImports} from '@stroeer-labs/design-library/angular';

// Section order is mirrored in ../react/notice-demo.tsx — the two panes sit side by side on the site,
// which is what makes a parity break visible instead of inferred.
@Component({
    selector: 'dl-notice-demo',
    standalone: true,
    imports: [HlmNoticeImports, HlmButtonImports, NgIcon],
    viewProviders: [provideIcons({lucideCircleAlert, lucideCircleCheck, lucideInfo, lucideMegaphone, lucideTriangleAlert})],
    template: `
    <div class="grid w-full max-w-xl items-start gap-6">
      <div class="space-y-2">
        <p class="text-xs font-medium text-muted-foreground">Five tones — the tone is the tint, the border and the icon, never the text</p>
        <div class="grid gap-3">
          <hlm-notice>
            <ng-icon name="lucideMegaphone" />
            <h4 hlmNoticeTitle>Declare what the advertising is about</h4>
            <p hlmNoticeDescription>You will see which sites accept the declared content.</p>
          </hlm-notice>
          <hlm-notice variant="info">
            <ng-icon name="lucideInfo" />
            <h4 hlmNoticeTitle>The plan saves automatically</h4>
            <p hlmNoticeDescription>Every line item edit is written through immediately.</p>
          </hlm-notice>
          <hlm-notice variant="success">
            <ng-icon name="lucideCircleCheck" />
            <h4 hlmNoticeTitle>All 412 targeted sites accept the declared advertising</h4>
            <p hlmNoticeDescription>The compliance check finished with no blocks.</p>
          </hlm-notice>
          <hlm-notice variant="warning">
            <ng-icon name="lucideTriangleAlert" />
            <h4 hlmNoticeTitle>Not saved — no hour selected</h4>
            <p hlmNoticeDescription>A line item must deliver in at least one hour, so this selection cannot be saved.</p>
          </hlm-notice>
          <hlm-notice variant="destructive">
            <ng-icon name="lucideCircleAlert" />
            <h4 hlmNoticeTitle>The plan total is unavailable — no price came back.</h4>
            <p hlmNoticeDescription>Recalculate the plan, or adjust the line item budget.</p>
          </hlm-notice>
        </div>
      </div>

      <div class="space-y-2">
        <p class="text-xs font-medium text-muted-foreground">
          <code class="font-mono">size="sm"</code> — for a notice inside a dense form section
        </p>
        <div class="grid gap-3">
          <hlm-notice size="sm" variant="info">
            <ng-icon name="lucideInfo" />
            <h4 hlmNoticeTitle>The plan saves automatically</h4>
            <p hlmNoticeDescription>Every line item edit is written through immediately.</p>
          </hlm-notice>
          <hlm-notice size="sm" variant="warning">
            <ng-icon name="lucideTriangleAlert" />
            <h4 hlmNoticeTitle>Not saved — no hour selected</h4>
            <p hlmNoticeDescription>A line item must deliver in at least one hour, so this selection cannot be saved.</p>
          </hlm-notice>
          <hlm-notice size="sm" variant="destructive">
            <ng-icon name="lucideCircleAlert" />
            <h4 hlmNoticeTitle>The plan total is unavailable — no price came back.</h4>
            <p hlmNoticeDescription>Recalculate the plan, or adjust the line item budget.</p>
          </hlm-notice>
        </div>
      </div>

      <div class="space-y-2">
        <p class="text-xs font-medium text-muted-foreground">One-liners — omit the description and the layout centres on a single row</p>
        <div class="grid gap-3">
          <hlm-notice variant="success">
            <ng-icon name="lucideCircleCheck" />
            <h4 hlmNoticeTitle>All 412 targeted sites accept the declared advertising</h4>
          </hlm-notice>
          <hlm-notice size="sm" variant="info">
            <ng-icon name="lucideInfo" />
            <h4 hlmNoticeTitle>The plan saves automatically</h4>
          </hlm-notice>
          <hlm-notice size="sm">
            <h4 hlmNoticeTitle>No icon, single row</h4>
          </hlm-notice>
        </div>
      </div>

      <div class="space-y-2">
        <p class="text-xs font-medium text-muted-foreground">
          Action slot — <code class="font-mono">size="sm"</code> takes a <code class="font-mono">size="xs"</code> button
        </p>
        <div class="grid gap-3">
          <hlm-notice variant="warning">
            <ng-icon name="lucideTriangleAlert" />
            <h4 hlmNoticeTitle>Sites removed</h4>
            <p hlmNoticeDescription>3 sites are not available on this network, so they were removed.</p>
            <div hlmNoticeAction>
              <button hlmBtn variant="ghost" size="sm">Dismiss</button>
            </div>
          </hlm-notice>
          <hlm-notice size="sm" variant="warning">
            <ng-icon name="lucideTriangleAlert" />
            <h4 hlmNoticeTitle>Sites removed</h4>
            <div hlmNoticeAction>
              <button hlmBtn variant="ghost" size="xs">Dismiss</button>
            </div>
          </hlm-notice>
        </div>
      </div>

      <div class="space-y-2">
        <p class="text-xs font-medium text-muted-foreground">Rich description — lists, paragraphs and links are styled by the slot</p>
        <hlm-notice variant="destructive">
          <ng-icon name="lucideCircleAlert" />
          <h4 hlmNoticeTitle>Unable to process your payment.</h4>
          <div hlmNoticeDescription>
            <p>Please verify your billing information and try again.</p>
            <ul class="list-inside list-disc text-sm">
              <li>Check your card details</li>
              <li>Ensure sufficient funds</li>
              <li>Verify billing address</li>
            </ul>
          </div>
        </hlm-notice>
      </div>
    </div>
  `,
})
export class NoticeDemoComponent {}