Menu

Change language

GitHub repo

Hero Typing Command Center

blockhero

Interactive CLI command center hero with animated execution simulator, output logs, and quick workflow presets.

Installation

$npx uipkge-ng@latest add hero-typing-command-center
Manifest:https://uipkge.dev/r/angular/hero-typing-command-center.jsonInstalls to:src/app/components/blocks/hero-typing-command-center/

Variants

Loading interactive previews…

Schema

Type aliases exported from this item's source. Use these to shape the data you pass in.

HeroTypingCommandAction
interface HeroTypingCommandAction {
  id: string
  title: string
  category: 'Components' | 'Themes' | 'Git' | 'Workflows'
  shortcut: string[]
  icon: LucideIconData
  description: string
  status: string
}

npm dependencies

Includes

Files installed (2)

  • src/app/components/blocks/hero-typing-command-center/hero-typing-command-center.component.ts10 kB
    // Keyboard command-palette hero: searchable action list with category badges,
    // shortcut kbd hints, hover selection and an executed-action status footer.
    // Port of the React block 1:1.
    import { ChangeDetectionStrategy, Component, Input, computed, signal } from '@angular/core'
    import {
      Check,
      Command,
      CornerDownLeft,
      FileCode,
      FolderGit2,
      Layers,
      LucideAngularModule,
      Palette,
      Search,
      Zap,
      type LucideIconData,
    } from 'lucide-angular'
    import { cn } from '@/lib/utils'
    import { UiBadgeComponent } from '@/ui/badge/badge.component'
    import { UiCardComponent, UiCardContentComponent } from '@/ui/card/card.component'
    
    export interface HeroTypingCommandAction {
      id: string
      title: string
      category: 'Components' | 'Themes' | 'Git' | 'Workflows'
      shortcut: string[]
      icon: LucideIconData
      description: string
      status: string
    }
    
    const actions: HeroTypingCommandAction[] = [
      {
        id: 'add-pdp',
        title: 'Insert Product Detail Page',
        category: 'Components',
        shortcut: ['⌘', 'I', 'P'],
        icon: Layers,
        description: 'Adds flagship unbundled PDP with gallery, reviews & buy box',
        status: 'Ready to inject',
      },
      {
        id: 'toggle-dark',
        title: 'Toggle High-Contrast Dark Theme',
        category: 'Themes',
        shortcut: ['⌘', 'T'],
        icon: Palette,
        description: 'Switches active OKLCH tokens to studio obsidian mode',
        status: 'Instant update',
      },
      {
        id: 'git-branch',
        title: 'Checkout Release Branch: v2.4.0',
        category: 'Git',
        shortcut: ['⌘', 'G', 'B'],
        icon: FolderGit2,
        description: 'Switches workspace to staging pipeline branch',
        status: 'Clean working tree',
      },
      {
        id: 'sync-registry',
        title: 'Synchronize Dual-Framework ASTs',
        category: 'Workflows',
        shortcut: ['⌘', 'S', 'Y'],
        icon: FileCode,
        description: 'Generates parity manifests between Vue 3.5 and React 19',
        status: 'Verified 100% parity',
      },
      {
        id: 'run-audit',
        title: 'Trigger Automated Craft Audit',
        category: 'Workflows',
        shortcut: ['⌘', 'A', 'U'],
        icon: Zap,
        description: 'Validates semantic scales, AA contrast and eliminates design slop',
        status: 'Zero regressions',
      },
    ]
    
    @Component({
      changeDetection: ChangeDetectionStrategy.Eager,
      selector: 'ui-hero-typing-command-center, [ui-hero-typing-command-center]',
      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: [LucideAngularModule, UiBadgeComponent, UiCardComponent, UiCardContentComponent],
      template: `
        <section data-slot="hero-typing-command-center" [class]="rootClass">
          <div class="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
            <div class="grid grid-cols-1 gap-12 lg:grid-cols-12 lg:items-center">
              <!-- Left: Headline & Key Advantages (5 Cols) -->
              <div class="space-y-6 lg:col-span-5">
                <div
                  class="border-border/80 bg-secondary/60 text-foreground inline-flex items-center gap-2 rounded-full border px-3.5 py-1 text-xs font-medium shadow-2xs"
                >
                  <lucide-icon [img]="Command" class="text-primary size-3.5" />
                  <span>Keyboard Ergonomics &bull; Zero Latency</span>
                </div>
    
                <h1 class="text-foreground text-3xl font-bold tracking-tight sm:text-4xl lg:text-5xl">
                  {{ title }}
                </h1>
    
                <p class="text-muted-foreground text-base sm:text-lg">
                  {{ description }}
                </p>
    
                <!-- Hotkey Highlights Grid -->
                <div class="border-border bg-muted/20 grid grid-cols-2 gap-3 rounded-xl border p-4 text-xs">
                  <div class="space-y-1">
                    <div class="text-muted-foreground font-medium">Global Trigger</div>
                    <div class="flex items-center gap-1 font-mono">
                      <kbd class="border-border bg-card rounded border px-1.5 py-0.5 shadow-2xs">⌘</kbd>
                      <kbd class="border-border bg-card rounded border px-1.5 py-0.5 shadow-2xs">K</kbd>
                    </div>
                  </div>
                  <div class="space-y-1">
                    <div class="text-muted-foreground font-medium">Quick Insert</div>
                    <div class="flex items-center gap-1 font-mono">
                      <kbd class="border-border bg-card rounded border px-1.5 py-0.5 shadow-2xs">⌘</kbd>
                      <kbd class="border-border bg-card rounded border px-1.5 py-0.5 shadow-2xs">I</kbd>
                    </div>
                  </div>
                </div>
              </div>
    
              <!-- Right: Interactive Command Palette Hub (7 Cols) -->
              <div class="lg:col-span-7">
                <div ui-card class="border-border bg-card shadow-lg">
                  <!-- Search Header -->
                  <div class="border-border flex items-center gap-3 border-b px-4 py-3">
                    <lucide-icon [img]="Search" class="text-muted-foreground size-4 shrink-0" />
                    <input
                      type="text"
                      placeholder="Type a command or search actions (e.g., 'insert', 'git', 'theme')..."
                      aria-label="Search commands"
                      class="placeholder:text-muted-foreground text-foreground flex-1 bg-transparent text-sm outline-none"
                      [value]="searchQuery()"
                      (input)="searchQuery.set($any($event.target).value)"
                    />
                    <div class="text-muted-foreground flex items-center gap-1 font-mono text-xs">
                      <kbd class="border-border bg-muted rounded border px-1.5 py-0.5 text-xs">ESC</kbd>
                    </div>
                  </div>
    
                  <!-- Command List -->
                  <div ui-card-content class="space-y-1 p-2">
                    @for (action of filteredActions(); track action.id; let idx = $index) {
                      <button
                        type="button"
                        [class]="actionClass(idx)"
                        (mouseenter)="selectedIndex.set(idx)"
                        (click)="execute(action)"
                      >
                        <div class="flex min-w-0 items-center gap-3">
                          <div
                            class="border-border bg-background flex size-8 shrink-0 items-center justify-center rounded-md border shadow-2xs"
                          >
                            <lucide-icon [img]="action.icon" class="text-primary size-4" />
                          </div>
                          <div class="min-w-0 space-y-0.5">
                            <div class="flex items-center gap-2">
                              <span class="truncate text-xs font-semibold">{{ action.title }}</span>
                              <span ui-badge variant="outline" class="h-4.5 px-1.5 text-xs">{{ action.category }}</span>
                            </div>
                            <p class="text-muted-foreground truncate text-xs">{{ action.description }}</p>
                          </div>
                        </div>
    
                        <!-- Shortcut Badge Group -->
                        <div class="ml-3 flex shrink-0 items-center gap-1 font-mono text-xs">
                          @for (key of action.shortcut; track key) {
                            <kbd class="border-border bg-background rounded border px-1.5 py-0.5 text-xs shadow-2xs">
                              {{ key }}
                            </kbd>
                          }
                        </div>
                      </button>
                    }
                  </div>
    
                  <!-- Status Footer -->
                  <div class="border-border bg-muted/30 flex items-center justify-between border-t px-4 py-2.5 text-xs">
                    <div class="text-muted-foreground flex items-center gap-2">
                      <lucide-icon [img]="CornerDownLeft" class="size-3.5" />
                      <span>Press <strong>Enter</strong> to run</span>
                    </div>
                    @if (executedAction()) {
                      <div class="text-success flex items-center gap-1.5 font-semibold">
                        <lucide-icon [img]="Check" class="size-3.5" />
                        <span>Executed: {{ executedAction()!.title }}</span>
                      </div>
                    } @else {
                      <div class="text-muted-foreground font-mono text-xs">
                        {{ filteredActions().length }} actions available
                      </div>
                    }
                  </div>
                </div>
              </div>
            </div>
          </div>
        </section>
      `,
    })
    export class UiHeroTypingCommandCenterComponent {
      protected readonly Check = Check
      protected readonly Command = Command
      protected readonly CornerDownLeft = CornerDownLeft
      protected readonly Search = Search
    
      @Input() title = 'Execute workflows at the speed of thought with keyboard command palette.'
      @Input() description =
        'Instant component insertion, theme switching, git branches, and automated deployment pipelines driven by zero-latency hotkeys.'
      @Input('class') className?: string
    
      readonly searchQuery = signal('')
      readonly selectedIndex = signal(0)
      readonly executedAction = signal<HeroTypingCommandAction | null>(null)
    
      private executeTimer: ReturnType<typeof setTimeout> | undefined
    
      readonly filteredActions = computed(() => {
        const q = this.searchQuery().trim().toLowerCase()
        if (!q) return actions
        return actions.filter(
          (a) =>
            a.title.toLowerCase().includes(q) ||
            a.category.toLowerCase().includes(q) ||
            a.description.toLowerCase().includes(q),
        )
      })
    
      get rootClass(): string {
        return cn('bg-background relative overflow-hidden py-16 sm:py-24 lg:py-28', this.className)
      }
    
      actionClass(idx: number): string {
        return cn(
          'group flex w-full items-center justify-between rounded-lg px-3 py-2.5 text-left transition-colors focus-visible:ring-2 focus-visible:ring-ring focus-visible:outline-none',
          this.selectedIndex() === idx
            ? 'border-primary/30 bg-accent text-accent-foreground border'
            : 'hover:bg-muted/50 text-foreground border border-transparent',
        )
      }
    
      execute(action: HeroTypingCommandAction): void {
        this.executedAction.set(action)
        clearTimeout(this.executeTimer)
        this.executeTimer = setTimeout(() => this.executedAction.set(null), 2500)
      }
    }
    
  • src/app/components/blocks/hero-typing-command-center/index.ts0.1 kB

Raw manifest:https://uipkge.dev/r/angular/hero-typing-command-center.json