{
  "$schema": "https://uipkge.dev/schema/registry-item.json",
  "name": "error-500",
  "title": "500 Server Error",
  "type": "registry:block",
  "description": "Full-page 500 with an isometric crashed-server illustration, HTTP code, headline, and Try again + Back to home + Contact support. Prop-driven: pass title, description, image, action labels, hrefs, and layout (`page` | `contained`). Pass `image=\"\"` to hide the art.",
  "categories": [
    "layout",
    "feedback"
  ],
  "deprecated": true,
  "replacedBy": "error-page",
  "files": [
    {
      "path": "packages/elements-lit/src/blocks/error-500/error-500.ts",
      "content": "import { LitElement, css, html, nothing } from 'lit'\nimport { LifeBuoy, RefreshCcw } from 'lucide'\nimport { cn } from '../../lib/utils'\nimport { tailwind } from '../../lib/styles'\nimport { ThemeController } from '../../lib/theme'\nimport { icon } from '../../lib/icon'\n// Side-effect import: registers <uip-button> for standalone use (consumers\n// who install only this block still get a working button).\nimport '../../components/button/button'\n\nconst falseConverter = { fromAttribute: (v: string | null) => v !== null && v !== 'false' }\n\n/**\n * <uip-error-500> — the registry Error500 block as a web component.\n *\n * Class strings are React's Error500 verbatim. `heading` is React's `title`\n * (`title` is taken by HTMLElement). `onPrimary` / `onSecondary` /\n * `onTertiary` become `primary` / `secondary` / `tertiary` CustomEvents\n * (bubbles, composed).\n *\n * Deviation: React's `image === undefined` HTTP-panel branch is unreachable\n * (the default param fills `image` first), so it is not ported: omit `image`\n * for the default art, pass `image=\"\"` to hide it.\n */\nexport class UipError500 extends LitElement {\n  static shadowRootOptions = { ...LitElement.shadowRootOptions, delegatesFocus: true }\n  // :host display can't be a utility class (the host has no template of its own).\n  static styles = [tailwind, css`:host { display: block; }`]\n\n  static properties = {\n    code: {},\n    heading: {},\n    description: {},\n    image: {},\n    imageAlt: { attribute: 'image-alt' },\n    primaryLabel: { attribute: 'primary-label' },\n    secondaryLabel: { attribute: 'secondary-label' },\n    tertiaryLabel: { attribute: 'tertiary-label' },\n    primaryHref: { attribute: 'primary-href' },\n    secondaryHref: { attribute: 'secondary-href' },\n    tertiaryHref: { attribute: 'tertiary-href' },\n    showPrimary: { type: Boolean, attribute: 'show-primary', converter: falseConverter },\n    showSecondary: { type: Boolean, attribute: 'show-secondary', converter: falseConverter },\n    showTertiary: { type: Boolean, attribute: 'show-tertiary', converter: falseConverter },\n    primaryDisabled: { type: Boolean, attribute: 'primary-disabled' },\n    secondaryDisabled: { type: Boolean, attribute: 'secondary-disabled' },\n    tertiaryDisabled: { type: Boolean, attribute: 'tertiary-disabled' },\n    layout: { reflect: true },\n  }\n\n  code?: string\n  heading?: string\n  description?: string\n  image = '/illustrations/error-500.jpg'\n  imageAlt = ''\n  primaryLabel?: string\n  secondaryLabel?: string\n  tertiaryLabel?: string\n  primaryHref?: string\n  secondaryHref?: string\n  tertiaryHref?: string\n  showPrimary = true\n  showSecondary = true\n  showTertiary = true\n  primaryDisabled = false\n  secondaryDisabled = false\n  tertiaryDisabled = false\n  layout: 'page' | 'contained' = 'page'\n\n  constructor() {\n    super()\n    new ThemeController(this)\n  }\n\n  connectedCallback() {\n    super.connectedCallback()\n    this.setAttribute('data-uipkge', '')\n    this.setAttribute('data-slot', 'error-500')\n    this.setAttribute('data-layout', this.layout)\n  }\n\n  willUpdate() {\n    this.setAttribute('data-layout', this.layout)\n  }\n\n  private emit(name: 'primary' | 'secondary' | 'tertiary') {\n    this.dispatchEvent(new CustomEvent(name, { bubbles: true, composed: true }))\n  }\n\n  render() {\n    const codeText = this.code ?? '500'\n    const titleText = this.heading ?? 'Something went wrong'\n    const descriptionText =\n      this.description ??\n      'We hit an unexpected error on our side. Try again in a moment — if it keeps happening, our team is on it.'\n    const primaryText = this.primaryLabel ?? 'Try again'\n    const secondaryText = this.secondaryLabel ?? 'Back to home'\n    const tertiaryText = this.tertiaryLabel ?? 'Contact support'\n    return html`\n      <section\n        data-slot=\"error-500\"\n        data-layout=${this.layout}\n        class=${cn(\n          'bg-background relative flex items-center overflow-hidden px-6 py-16',\n          this.layout === 'page' ? 'min-h-svh' : 'min-h-[28rem]',\n        )}\n      >\n        <div class=\"mx-auto grid w-full max-w-5xl items-center gap-10 lg:grid-cols-2 lg:gap-16\">\n          <div>\n            ${codeText\n              ? html`<p class=\"text-muted-foreground text-sm font-medium\">HTTP ${codeText}</p>\n                  <p class=\"mt-3 text-6xl font-semibold tracking-tighter sm:text-7xl\">${codeText}</p>`\n              : nothing}\n            <h1 class=\"mt-3 text-2xl font-semibold tracking-tight sm:text-3xl\">${titleText}</h1>\n            ${descriptionText\n              ? html`<p class=\"text-muted-foreground mt-4 max-w-md text-base\">${descriptionText}</p>`\n              : nothing}\n            ${this.showPrimary || this.showSecondary || this.showTertiary\n              ? html`<div class=\"mt-8 flex flex-wrap items-center gap-3\">\n                  ${this.showPrimary\n                    ? html`<uip-button\n                        size=\"lg\"\n                        ?disabled=${this.primaryDisabled}\n                        href=${this.primaryHref ?? nothing}\n                        @click=${() => this.emit('primary')}\n                      >\n                        ${icon(RefreshCcw, 'refresh-ccw')} ${primaryText}\n                      </uip-button>`\n                    : nothing}\n                  ${this.showSecondary\n                    ? html`<uip-button\n                        size=\"lg\"\n                        variant=\"outline\"\n                        ?disabled=${this.secondaryDisabled}\n                        href=${this.secondaryHref ?? nothing}\n                        @click=${() => this.emit('secondary')}\n                      >\n                        ${secondaryText}\n                      </uip-button>`\n                    : nothing}\n                  ${this.showTertiary\n                    ? html`<uip-button\n                        size=\"lg\"\n                        variant=\"ghost\"\n                        ?disabled=${this.tertiaryDisabled}\n                        href=${this.tertiaryHref ?? nothing}\n                        @click=${() => this.emit('tertiary')}\n                      >\n                        ${tertiaryText} ${icon(LifeBuoy, 'life-buoy')}\n                      </uip-button>`\n                    : nothing}\n                </div>`\n              : nothing}\n          </div>\n          ${this.image\n            ? html`<div class=\"border-border bg-muted overflow-hidden rounded-xl border\">\n                <img src=${this.image} alt=${this.imageAlt} class=\"aspect-[4/3] w-full object-cover\" />\n              </div>`\n            : nothing}\n        </div>\n      </section>\n    `\n  }\n}\n\ncustomElements.get('uip-error-500') || customElements.define('uip-error-500', UipError500)\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    'uip-error-500': UipError500\n  }\n}\n",
      "type": "registry:file",
      "target": "src/uip/blocks/error-500/error-500.ts"
    }
  ],
  "dependencies": [
    "lit",
    "lucide"
  ],
  "registryDependencies": [
    "https://uipkge.dev/r/lit/button.json",
    "https://uipkge.dev/r/lit/lit-core.json"
  ]
}
