Menu

Change language

GitHub repo

Announcement — Split Banner

blockmarketing

Full-width announcement band split between a labelled message column and an action column, sized for release notes and maintenance notices rather than promotions.

Installation

$npx uipkge-ng@latest add announcement-banner-split
Manifest:https://uipkge.dev/r/angular/announcement-banner-split.jsonInstalls to:src/app/components/blocks/announcement-banner-split/

Variants

Loading interactive previews…

npm dependencies

Files installed (2)

  • src/app/components/blocks/announcement-banner-split/announcement-banner-split.component.ts3.5 kB
    // Full-width announcement band split between a labelled message column and an
    // action column, sized for release notes and maintenance notices. Port of the
    // Vue/React block 1:1. `tone` flips the icon, badge, copy and actions together.
    import { ChangeDetectionStrategy, Component, Input } from '@angular/core'
    import { ArrowRight, CircleAlert, Info, LucideAngularModule } from 'lucide-angular'
    import { cn } from '@/lib/utils'
    import { UiBadgeComponent } from '@/ui/badge/badge.component'
    import { UiButtonComponent } from '@/ui/button/button.component'
    import { UiSeparatorComponent } from '@/ui/separator/separator.component'
    
    export type AnnouncementBannerSplitTone = 'neutral' | 'attention'
    
    @Component({
      changeDetection: ChangeDetectionStrategy.Eager,
      selector: 'ui-announcement-banner-split, [ui-announcement-banner-split]',
      standalone: true,
      // The block renders its own <section>: keep this wrapper out of the layout.
      host: { '[attr.class]': '"contents"' },
      imports: [LucideAngularModule, UiBadgeComponent, UiButtonComponent, UiSeparatorComponent],
      template: `
        <section data-slot="announcement-banner-split" [class]="rootClass">
          <div class="mx-auto flex max-w-6xl flex-col gap-4 px-6 py-4 sm:flex-row sm:items-center sm:gap-8">
            <!-- Message column carries the classification; the action column stays
                 the same width whatever the message length, so a stack of these
                 banners aligns down the page. -->
            <div class="flex min-w-0 flex-1 items-start gap-3">
              @if (tone === 'attention') {
                <lucide-icon [img]="CircleAlert" class="text-destructive mt-0.5 size-4 shrink-0" aria-hidden="true" />
              } @else {
                <lucide-icon [img]="Info" class="text-muted-foreground mt-0.5 size-4 shrink-0" aria-hidden="true" />
              }
              <div class="min-w-0">
                <div class="flex flex-wrap items-center gap-2">
                  <span ui-badge [variant]="tone === 'attention' ? 'outline' : 'secondary'">
                    {{ tone === 'attention' ? 'Scheduled maintenance' : 'Release 2.4.0' }}
                  </span>
                  <span class="text-muted-foreground font-mono text-xs">Aug 14, 2026 · 02:00–04:00 UTC</span>
                </div>
                <p class="mt-1.5 text-sm leading-relaxed">
                  @if (tone === 'attention') {
                    Query serving stays online. Scheduled materialisation pauses for the window and resumes automatically.
                  } @else {
                    Command palette, table virtualisation past 10k rows, and AA-contrast sidebar badges in dark mode.
                  }
                </p>
              </div>
            </div>
    
            <ui-separator orientation="vertical" class="hidden h-10 sm:block" />
    
            <div class="flex shrink-0 items-center gap-2">
              <button ui-button variant="outline" size="sm">
                {{ tone === 'attention' ? 'Status page' : 'Full changelog' }}
                <lucide-icon [img]="ArrowRight" [class]="'ml-1.5 size-3.5'" aria-hidden="true" />
              </button>
              <button ui-button variant="ghost" size="sm">Subscribe</button>
            </div>
          </div>
        </section>
      `,
    })
    export class UiAnnouncementBannerSplitComponent {
      @Input() tone: AnnouncementBannerSplitTone = 'neutral'
      @Input('class') className?: string
    
      protected readonly CircleAlert = CircleAlert
      protected readonly Info = Info
      protected readonly ArrowRight = ArrowRight
    
      get rootClass(): string {
        return cn(
          'border-b',
          this.tone === 'attention' ? 'border-border bg-muted' : 'border-border bg-card',
          this.className,
        )
      }
    }
    
  • src/app/components/blocks/announcement-banner-split/index.ts0.1 kB

Raw manifest:https://uipkge.dev/r/angular/announcement-banner-split.json