Menu

Change language

GitHub repo

Code — Install Command

blockmarketing

Package-manager tab strip over a single install command with a copy button, a resolved-version line, and a short note on what the command writes to disk.

Installation

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

Variants

Loading interactive previews…

npm dependencies

Files installed (2)

  • src/app/components/blocks/code-install-command/code-install-command.component.ts4.9 kB
    // Package-manager tab strip over a single install command with a copy button, a
    // resolved-version line, and a short note on what the command writes to disk.
    // Port of the React block 1:1.
    import { ChangeDetectionStrategy, Component, computed, DestroyRef, inject, Input, signal } from '@angular/core'
    import { Check, Copy, LucideAngularModule, Terminal } from 'lucide-angular'
    import { cn } from '@/lib/utils'
    import { UiBadgeComponent } from '@/ui/badge/badge.component'
    import { UiButtonComponent } from '@/ui/button/button.component'
    import {
      UiTabsComponent,
      UiTabsContentComponent,
      UiTabsListComponent,
      UiTabsTriggerComponent,
    } from '@/ui/tabs/tabs.component'
    
    @Component({
      changeDetection: ChangeDetectionStrategy.Eager,
      selector: 'ui-code-install-command, [ui-code-install-command]',
      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,
        UiButtonComponent,
        UiTabsComponent,
        UiTabsContentComponent,
        UiTabsListComponent,
        UiTabsTriggerComponent,
      ],
      template: `
        <section data-slot="code-install-command" [class]="rootClass">
          <div class="mx-auto max-w-3xl px-6 py-20">
            <div class="flex flex-wrap items-center gap-3">
              <span ui-badge variant="secondary" class="gap-1.5">
                <lucide-icon [img]="Terminal" class="size-3" aria-hidden="true" />
                Install
              </span>
              <span class="text-muted-foreground font-mono text-xs">resolved {{ pkg }}@{{ version }}</span>
            </div>
    
            <h2 class="mt-4 text-2xl font-semibold tracking-tight">One command, then you own the source</h2>
    
            <ui-tabs defaultValue="npm" class="mt-6">
              <ui-tabs-list variant="segmented" class="flex-nowrap overflow-x-auto">
                @for (manager of managers(); track manager.id) {
                  <button ui-tabs-trigger [value]="manager.id" variant="segmented">
                    {{ manager.id }}
                  </button>
                }
              </ui-tabs-list>
    
              @for (manager of managers(); track manager.id) {
                <ui-tabs-content [value]="manager.id" class="mt-4">
                  <div class="border-border bg-card flex items-stretch overflow-hidden rounded-lg border">
                    <span class="text-primary grid shrink-0 place-items-center px-3 font-mono text-xs select-none">$</span>
                    <code class="bg-muted/25 min-w-0 flex-1 truncate px-3 py-2.5 font-mono text-sm">
                      {{ manager.command }}
                    </code>
                    <button
                      ui-button
                      variant="ghost"
                      class="border-border h-auto shrink-0 rounded-none border-l px-3"
                      [attr.aria-label]="'Copy ' + manager.id + ' command'"
                      (click)="copy(manager.command, manager.id)"
                    >
                      @if (copied() === manager.id) {
                        <lucide-icon [img]="Check" class="text-success size-4" aria-hidden="true" />
                      } @else {
                        <lucide-icon [img]="Copy" class="size-4" aria-hidden="true" />
                      }
                    </button>
                  </div>
                </ui-tabs-content>
              }
            </ui-tabs>
    
            <p class="text-muted-foreground mt-4 text-sm leading-relaxed">
              Writes the component source into
              <code class="bg-muted rounded px-1 py-0.5 font-mono text-xs">components/</code>
              and adds nothing to your lockfile beyond the icon set. Edit it like any other file in your repo.
            </p>
          </div>
        </section>
      `,
    })
    export class UiCodeInstallCommandComponent {
      protected readonly Check = Check
      protected readonly Copy = Copy
      protected readonly Terminal = Terminal
    
      @Input() pkg = '@northwind/metrics'
      @Input() version = '2.4.0'
      @Input('class') className?: string
    
      // One package name, four managers — derived rather than duplicated so a rename
      // cannot leave one tab pointing at the old package.
      readonly managers = computed(() => [
        { id: 'npm', command: `npm install ${this.pkg}` },
        { id: 'pnpm', command: `pnpm add ${this.pkg}` },
        { id: 'yarn', command: `yarn add ${this.pkg}` },
        { id: 'bun', command: `bun add ${this.pkg}` },
      ])
    
      readonly copied = signal('')
      private copyTimer: ReturnType<typeof setTimeout> | undefined
    
      constructor() {
        inject(DestroyRef).onDestroy(() => clearTimeout(this.copyTimer))
      }
    
      get rootClass(): string {
        return cn('bg-background', this.className)
      }
    
      async copy(command: string, id: string): Promise<void> {
        try {
          await navigator.clipboard.writeText(command)
          this.copied.set(id)
          clearTimeout(this.copyTimer)
          this.copyTimer = setTimeout(() => this.copied.set(''), 1600)
        } catch {
          // Clipboard blocked (insecure context or denied permission): leave the
          // command visible so it can still be selected by hand.
        }
      }
    }
    
  • src/app/components/blocks/code-install-command/index.ts0.1 kB

Raw manifest:https://uipkge.dev/r/angular/code-install-command.json