Newsletter — Inline Band
blockmarketingSlim full-width signup band with an inline field, submit button, subscriber count as proof, and a status line that reserves its own row so confirming never shifts the layout.
Installation
$pnpm dlx uipkge-ng@latest add newsletter-inline-band$npx uipkge-ng@latest add newsletter-inline-band$yarn dlx uipkge-ng@latest add newsletter-inline-band$bunx uipkge-ng@latest add newsletter-inline-bandManifest:
https://uipkge.dev/r/angular/newsletter-inline-band.jsonInstalls to:src/app/components/blocks/newsletter-inline-band/Variants
Loading interactive previews…
Loading interactive previews…
npm dependencies
Files installed (2)
src/app/components/blocks/newsletter-inline-band/newsletter-inline-band.component.ts3.2 kB
// Slim full-width signup band with an inline field, submit button, and a status line // that reserves its own row so confirming never shifts the layout. Port of the React block 1:1. import { ChangeDetectionStrategy, Component, Input, signal } from '@angular/core' import { Check, LucideAngularModule, Mail } from 'lucide-angular' import { UiBadgeComponent } from '@/ui/badge/badge.component' import { UiButtonComponent } from '@/ui/button/button.component' import { UiInputComponent } from '@/ui/input/input.component' @Component({ changeDetection: ChangeDetectionStrategy.Eager, selector: 'ui-newsletter-inline-band, [ui-newsletter-inline-band]', standalone: true, // The block renders its own root <section>: keep the host out of layout. host: { '[attr.class]': '"contents"' }, imports: [LucideAngularModule, UiBadgeComponent, UiButtonComponent, UiInputComponent], template: ` <section data-slot="newsletter-inline-band" class="border-border bg-muted/40 border-y"> <div class="mx-auto flex max-w-6xl flex-col gap-6 px-6 py-10 lg:flex-row lg:items-center lg:gap-12"> <div class="min-w-0 lg:flex-1"> <div class="flex items-center gap-2"> <lucide-icon [img]="Mail" class="text-muted-foreground size-4" aria-hidden="true" /> <span ui-badge variant="secondary">Monthly</span> </div> <p class="mt-2.5 text-lg leading-snug font-medium text-balance"> Engineering notes on metric modelling, access control, and warehouse cost. </p> <p class="text-muted-foreground mt-1.5 text-sm"> Read by 8,400 data and finance engineers. One email a month, no product announcements. </p> </div> <form class="lg:w-[26rem] lg:shrink-0" (submit)="subscribe($event)"> <div class="flex gap-2"> <ui-input [value]="email()" (valueChange)="email.set($event)" type="email" required placeholder="you@company.com" autoComplete="email" aria-label="Email address" /> <button ui-button type="submit" class="shrink-0">Subscribe</button> </div> <!-- Status row is reserved from first paint, so confirming does not nudge the band's height and shift the page under the cursor. --> <p class="mt-2 min-h-5 text-xs" aria-live="polite"> @if (submitted()) { <span class="text-success inline-flex items-center gap-1.5"> <lucide-icon [img]="Check" class="size-3" aria-hidden="true" /> Check your inbox to confirm. </span> } @else { <span class="text-muted-foreground">Unsubscribe in one click. We never share the list.</span> } </p> </form> </div> </section> `, }) export class UiNewsletterInlineBandComponent { protected readonly Check = Check protected readonly Mail = Mail @Input('class') className?: string readonly email = signal('') readonly submitted = signal(false) subscribe(event: Event): void { event.preventDefault() if (!this.email().trim()) return this.submitted.set(true) } }src/app/components/blocks/newsletter-inline-band/index.ts0.1 kB
export { UiNewsletterInlineBandComponent } from './newsletter-inline-band.component'
Raw manifest:https://uipkge.dev/r/angular/newsletter-inline-band.json