Menu

Change language

GitHub repo

Logo Cloud — Grayscale Hover

blockmarketing

Customer logo wall rendered in muted monochrome that resolves to full contrast on hover, with a headline count and a segment line beneath.

Installation

$npx uipkge-ng@latest add logo-cloud-grayscale
Manifest:https://uipkge.dev/r/angular/logo-cloud-grayscale.jsonInstalls to:src/app/components/blocks/logo-cloud-grayscale/

Variants

Loading interactive previews…

Files installed (2)

  • src/app/components/blocks/logo-cloud-grayscale/logo-cloud-grayscale.component.ts2.8 kB
    // Customer logo wall rendered in muted monochrome that resolves to full contrast
    // on hover, with a headline count and a segment line beneath. Port of the
    // Vue/React block 1:1 — swap the wordmarks for logo files; the hover treatment
    // carries over.
    import { ChangeDetectionStrategy, Component, Input } from '@angular/core'
    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'
    
    const customers: string[] = [
      'Northwind',
      'Halden',
      'Verity',
      'Calder',
      'Ridgeway',
      'Ashford',
      'Brightmoor',
      'Kesteven',
      'Marlowe',
      'Thornbury',
      'Wexley',
      'Alderton',
    ]
    
    @Component({
      changeDetection: ChangeDetectionStrategy.Eager,
      selector: 'ui-logo-cloud-grayscale, [ui-logo-cloud-grayscale]',
      standalone: true,
      // React renders the root <section> itself: the host stays out of layout and `class` goes to the root.
      host: { '[attr.class]': '"contents"' },
      imports: [UiBadgeComponent, UiButtonComponent, UiSeparatorComponent],
      template: `
        <section data-slot="logo-cloud-grayscale" [class]="rootClass">
          <div class="mx-auto max-w-6xl px-6 py-16">
            <div class="text-center">
              <span ui-badge variant="secondary">Customers</span>
              <p class="mt-4 text-lg font-medium">Running the close at 240 companies</p>
              <p class="text-muted-foreground mt-1.5 text-sm">
                Freight, healthcare, retail, and manufacturing · median 1,100 staff
              </p>
            </div>
    
            <!-- Muted by default, full contrast on hover: the wall reads as texture
                 until someone looks for a specific name. -->
            <ul class="mt-10 grid grid-cols-2 gap-x-8 gap-y-6 sm:grid-cols-3 lg:grid-cols-6">
              @for (customer of allCustomers; track customer) {
                <li class="flex items-center justify-center">
                  <span
                    class="text-muted-foreground/60 hover:text-foreground cursor-default text-sm font-semibold tracking-[0.18em] uppercase transition-colors"
                  >
                    {{ customer }}
                  </span>
                </li>
              }
            </ul>
    
            <ui-separator class="my-10" />
    
            <div class="flex flex-wrap items-center justify-center gap-4 text-center">
              <p class="text-muted-foreground text-sm">Six of the ten largest UK freight forwarders.</p>
              <button ui-button variant="link" class="h-auto p-0 text-sm">Read their stories</button>
            </div>
          </div>
        </section>
      `,
    })
    export class UiLogoCloudGrayscaleComponent {
      protected readonly allCustomers = customers
    
      @Input('class') className?: string
    
      get rootClass(): string {
        return cn('bg-background', this.className)
      }
    }
    
  • src/app/components/blocks/logo-cloud-grayscale/index.ts0.1 kB

Raw manifest:https://uipkge.dev/r/angular/logo-cloud-grayscale.json