{
  "$schema": "https://uipkge.dev/schema/registry-item.json",
  "name": "contact-us",
  "title": "Contact Us",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-angular/blocks/contact-us/contact-us.component.ts",
      "content": "// Two-column contact section. Left: eyebrow, headline, lede, icon contact rows (email /\n// phone / office) and a live Mapbox map pinned to your office (pass accessToken +\n// location; falls back to a placeholder without a token). Right: a Card-wrapped form\n// (name / email / company / subject Select / message Textarea) that swaps to a success\n// state. Emits \"submit\" with the payload. Port of the React block 1:1.\nimport { ChangeDetectionStrategy, Component, EventEmitter, Input, Output, computed, signal } from '@angular/core'\nimport { CheckCircle2, LucideAngularModule, Mail, MapPin, Phone, Send } from 'lucide-angular'\nimport { cn } from '@/lib/utils'\nimport { UiButtonComponent } from '@/ui/button/button.component'\nimport {\n  UiCardComponent,\n  UiCardContentComponent,\n  UiCardDescriptionComponent,\n  UiCardHeaderComponent,\n  UiCardTitleComponent,\n} from '@/ui/card/card.component'\nimport { UiInputComponent } from '@/ui/input/input.component'\nimport { UiLabelComponent } from '@/ui/label/label.component'\nimport { UiMapComponent, UiMapMarkerComponent } from '@/ui/map/map.component'\nimport {\n  UiSelectComponent,\n  UiSelectContentComponent,\n  UiSelectItemComponent,\n  UiSelectTriggerComponent,\n  UiSelectValueComponent,\n} from '@/ui/select/select.component'\nimport { UiTextareaComponent } from '@/ui/textarea/textarea.component'\n\nexport interface ContactUsPayload {\n  name: string\n  email: string\n  company: string\n  subject: string\n  message: string\n}\n\n@Component({\n  changeDetection: ChangeDetectionStrategy.Eager,\n  selector: 'ui-contact-us, [ui-contact-us]',\n  standalone: true,\n  // React renders the root <section> itself: the host stays out of layout and `class` goes to the root.\n  host: { '[attr.class]': '\"contents\"' },\n  imports: [\n    LucideAngularModule,\n    UiButtonComponent,\n    UiCardComponent,\n    UiCardContentComponent,\n    UiCardDescriptionComponent,\n    UiCardHeaderComponent,\n    UiCardTitleComponent,\n    UiInputComponent,\n    UiLabelComponent,\n    UiMapComponent,\n    UiMapMarkerComponent,\n    UiSelectComponent,\n    UiSelectContentComponent,\n    UiSelectItemComponent,\n    UiSelectTriggerComponent,\n    UiSelectValueComponent,\n    UiTextareaComponent,\n  ],\n  template: `\n    <section data-slot=\"contact-us\" [class]=\"rootClass\">\n      <div class=\"mx-auto max-w-6xl px-6 py-20\">\n        <div class=\"grid gap-10 lg:grid-cols-2 lg:items-start\">\n          <!-- Left: copy + contact rows + map -->\n          <div class=\"space-y-6\">\n            <p class=\"text-primary text-sm font-medium tracking-widest uppercase\">Contact</p>\n            <h2 class=\"text-3xl font-semibold tracking-tight sm:text-4xl\">Talk to our team</h2>\n            <p class=\"text-muted-foreground max-w-md\">\n              Questions about pricing, onboarding, or a custom plan? Send a note and we'll get back within one business\n              day.\n            </p>\n\n            <ul class=\"space-y-3\">\n              <li class=\"flex items-center gap-3\">\n                <span class=\"bg-muted text-foreground flex size-9 items-center justify-center rounded-lg\">\n                  <lucide-icon [img]=\"Mail\" class=\"size-4\" />\n                </span>\n                <span class=\"text-sm\">hello@example.com</span>\n              </li>\n              <li class=\"flex items-center gap-3\">\n                <span class=\"bg-muted text-foreground flex size-9 items-center justify-center rounded-lg\">\n                  <lucide-icon [img]=\"Phone\" class=\"size-4\" />\n                </span>\n                <span class=\"text-sm\">+1 (555) 010-2030</span>\n              </li>\n              <li class=\"flex items-center gap-3\">\n                <span class=\"bg-muted text-foreground flex size-9 items-center justify-center rounded-lg\">\n                  <lucide-icon [img]=\"MapPin\" class=\"size-4\" />\n                </span>\n                <span class=\"text-sm\">{{ locationLabel }}</span>\n              </li>\n            </ul>\n\n            <div class=\"h-56 overflow-hidden rounded-xl border\">\n              @if (accessToken) {\n                <div ui-map [accessToken]=\"accessToken\" [center]=\"location\" [zoom]=\"11\" muted class=\"size-full\">\n                  <ui-map-marker [lngLat]=\"location\" anchor=\"bottom\">\n                    <svg viewBox=\"0 0 24 24\" width=\"26\" height=\"34\" class=\"text-primary drop-shadow\">\n                      <path\n                        d=\"M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7z\"\n                        fill=\"currentColor\"\n                        stroke=\"currentColor\"\n                        stroke-width=\"1.5\"\n                      />\n                      <circle cx=\"12\" cy=\"9\" r=\"2.6\" fill=\"var(--background)\" />\n                    </svg>\n                  </ui-map-marker>\n                </div>\n              } @else {\n                <div class=\"bg-muted text-muted-foreground flex size-full items-center justify-center gap-2 text-sm\">\n                  <lucide-icon [img]=\"MapPin\" class=\"size-4\" /> {{ locationLabel }}\n                </div>\n              }\n            </div>\n          </div>\n\n          <!-- Right: form -->\n          <div ui-card>\n            @if (!sent()) {\n              <div ui-card-header>\n                <h3 ui-card-title>Send a message</h3>\n                <p ui-card-description>We'll route it to the right person.</p>\n              </div>\n              <div ui-card-content class=\"space-y-4\">\n                <div class=\"grid gap-4 sm:grid-cols-2\">\n                  <div class=\"space-y-1.5\">\n                    <label ui-label for=\"cu-name\">Name</label>\n                    <ui-input\n                      id=\"cu-name\"\n                      [value]=\"name()\"\n                      (valueChange)=\"name.set($event)\"\n                      placeholder=\"Jane Cooper\"\n                    />\n                  </div>\n                  <div class=\"space-y-1.5\">\n                    <label ui-label for=\"cu-email\">Email</label>\n                    <ui-input\n                      id=\"cu-email\"\n                      [value]=\"email()\"\n                      (valueChange)=\"email.set($event)\"\n                      type=\"email\"\n                      placeholder=\"jane@company.com\"\n                    />\n                  </div>\n                </div>\n                <div class=\"space-y-1.5\">\n                  <label ui-label for=\"cu-company\">Company</label>\n                  <ui-input\n                    id=\"cu-company\"\n                    [value]=\"company()\"\n                    (valueChange)=\"company.set($event)\"\n                    placeholder=\"Acme Inc.\"\n                  />\n                </div>\n                <div class=\"space-y-1.5\">\n                  <label ui-label>Subject</label>\n                  <ui-select [value]=\"subject()\" (valueChange)=\"subject.set($event)\">\n                    <button ui-select-trigger>\n                      <ui-select-value placeholder=\"Choose a topic\" />\n                    </button>\n                    <ui-select-content>\n                      <ui-select-item value=\"sales\">Sales</ui-select-item>\n                      <ui-select-item value=\"support\">Support</ui-select-item>\n                      <ui-select-item value=\"partnership\">Partnership</ui-select-item>\n                    </ui-select-content>\n                  </ui-select>\n                </div>\n                <div class=\"space-y-1.5\">\n                  <label ui-label for=\"cu-message\">Message</label>\n                  <ui-textarea\n                    id=\"cu-message\"\n                    [value]=\"message()\"\n                    (valueChange)=\"message.set($event)\"\n                    [rows]=\"4\"\n                    placeholder=\"How can we help?\"\n                  />\n                </div>\n                <button ui-button class=\"w-full\" [disabled]=\"!canSubmit()\" (click)=\"send()\">\n                  <lucide-icon [img]=\"Send\" class=\"size-4\" /> Send message\n                </button>\n              </div>\n            } @else {\n              <div ui-card-content class=\"flex flex-col items-center gap-3 py-16 text-center\">\n                <span class=\"bg-success/10 text-success flex size-12 items-center justify-center rounded-full\">\n                  <lucide-icon [img]=\"CheckCircle2\" class=\"size-6\" />\n                </span>\n                <p class=\"text-lg font-semibold\">Message sent</p>\n                <p class=\"text-muted-foreground max-w-xs text-sm\">\n                  Thanks, {{ name() }} — we'll reply to {{ email() }} within one business day.\n                </p>\n                <button ui-button variant=\"outline\" (click)=\"sent.set(false)\">Send another</button>\n              </div>\n            }\n          </div>\n        </div>\n      </div>\n    </section>\n  `,\n})\nexport class UiContactUsComponent {\n  protected readonly CheckCircle2 = CheckCircle2\n  protected readonly Mail = Mail\n  protected readonly MapPin = MapPin\n  protected readonly Phone = Phone\n  protected readonly Send = Send\n\n  /** Mapbox token. Without it the map area shows a styled placeholder. */\n  @Input() accessToken = ''\n  /** Office [lng, lat]. */\n  @Input() location: [number, number] = [-122.4194, 37.7749]\n  @Input() locationLabel = 'San Francisco, CA'\n  @Input('class') className?: string\n  @Output() readonly submit = new EventEmitter<ContactUsPayload>()\n\n  readonly name = signal('')\n  readonly email = signal('')\n  readonly company = signal('')\n  readonly subject = signal('sales')\n  readonly message = signal('')\n  readonly sent = signal(false)\n\n  readonly canSubmit = computed(() => !!this.name() && !!this.email() && !!this.message())\n\n  get rootClass(): string {\n    return cn('bg-background', this.className)\n  }\n\n  send(): ContactUsPayload | null {\n    if (!this.canSubmit()) return null\n    const payload: ContactUsPayload = {\n      name: this.name(),\n      email: this.email(),\n      company: this.company(),\n      subject: this.subject(),\n      message: this.message(),\n    }\n    this.sent.set(true)\n    this.submit.emit(payload)\n    return payload\n  }\n}\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/contact-us/contact-us.component.ts"
    },
    {
      "path": "packages/registry-angular/blocks/contact-us/index.ts",
      "content": "export { UiContactUsComponent, type ContactUsPayload } from './contact-us.component'\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/contact-us/index.ts"
    }
  ],
  "dependencies": [
    "lucide-angular"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/angular/button.json",
    "https://uipkge.dev/r/angular/card.json",
    "https://uipkge.dev/r/angular/input.json",
    "https://uipkge.dev/r/angular/label.json",
    "https://uipkge.dev/r/angular/select.json",
    "https://uipkge.dev/r/angular/textarea.json",
    "https://uipkge.dev/r/angular/map.json"
  ],
  "description": "Two-column contact section. Left: eyebrow, headline, lede, icon contact rows (email / phone / office) and a live Mapbox map pinned to your office (pass access-token + location; falls back to a placeholder without a token). Right: a Card-wrapped form (name / email / company / subject Select / message Textarea) that swaps to a success state. Emits \"submit\" with the payload.",
  "categories": [
    "marketing"
  ]
}