{
  "$schema": "https://uipkge.dev/schema/registry-item.json",
  "name": "quick-actions",
  "title": "Quick Actions",
  "type": "registry:block",
  "description": "Vertical list of clickable shortcuts in a SectionCard. Spell rows out inline with QuickActionItem — swap the anchor for your router Link when you need SPA routing.",
  "categories": [
    "layout",
    "dashboard"
  ],
  "files": [
    {
      "path": "packages/elements-lit/src/blocks/quick-actions/quick-actions.ts",
      "content": "import { LitElement, css, html, nothing } from 'lit'\nimport { ArrowUpRight, type IconNode } from 'lucide'\nimport * as icons from 'lucide'\nimport { tailwind } from '../../lib/styles'\nimport { ThemeController } from '../../lib/theme'\nimport { icon } from '../../lib/icon'\n// Side-effect imports: register the composed elements for standalone use\n// (consumers who install only this block still get working primitives).\nimport '../../components/icon-box/icon-box'\nimport '../../components/section-card/section-card'\n\nfunction toPascal(kebab: string) {\n  return kebab\n    .split('-')\n    .map((p) => (p ? `${p[0] ?? ''}`.toUpperCase() + p.slice(1) : ''))\n    .join('')\n}\n\n/**\n * <uip-quick-actions> — the registry QuickActions block as a web component.\n *\n * Class strings are React's QuickActions / QuickActionItem verbatim.\n * `title` is `heading` (`title` is taken by HTMLElement); rows are\n * <uip-quick-action-item> light-DOM children (React's `children`), spaced by\n * the block's own `flex flex-col gap-2` wrapper (React's `contentClassName`).\n * Swap the anchor for your router link when you need SPA routing — you own\n * this file.\n */\nexport class UipQuickActions 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    heading: {},\n    description: {},\n  }\n\n  heading = 'Quick Actions'\n  description?: string\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', 'quick-actions')\n  }\n\n  render() {\n    return html`\n      <uip-section-card heading=${this.heading} description=${this.description ?? nothing}>\n        <div class=\"flex flex-col gap-2\"><slot></slot></div>\n      </uip-section-card>\n    `\n  }\n}\n\n/**\n * <uip-quick-action-item> — one shortcut row (React's QuickActionItem).\n * `label` + `href` render the anchor; the icon is `icon-name` (kebab-case\n * lucide name, e.g. `user-plus`) or the `icon` IconNode property.\n */\nexport class UipQuickActionItem 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    label: {},\n    href: {},\n    icon: { attribute: false },\n    iconName: { attribute: 'icon-name' },\n  }\n\n  label = ''\n  href?: string\n  icon?: IconNode\n  iconName?: string\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', 'quick-action-item')\n  }\n\n  private get resolvedIcon(): IconNode | undefined {\n    if (this.icon) return this.icon\n    if (!this.iconName) return undefined\n    const node = (icons as unknown as Record<string, IconNode>)[toPascal(this.iconName)]\n    return node\n  }\n\n  render() {\n    const node = this.resolvedIcon\n    return html`\n      <a\n        href=${this.href ?? nothing}\n        class=\"hover:border-border hover:bg-muted/50 group flex cursor-pointer items-center gap-3 rounded-lg border border-transparent p-3 transition-colors duration-200\"\n      >\n        ${node ? html`<uip-icon-box .icon=${node} icon-name=${this.iconName ?? 'icon'}></uip-icon-box>` : nothing}\n        <span class=\"flex-1 text-sm font-medium\">${this.label}</span>\n        ${icon(ArrowUpRight, 'arrow-up-right', 'text-muted-foreground size-4 opacity-0 transition-colors duration-200 group-hover:opacity-100')}\n      </a>\n    `\n  }\n}\n\ncustomElements.get('uip-quick-actions') || customElements.define('uip-quick-actions', UipQuickActions)\ncustomElements.get('uip-quick-action-item') || customElements.define('uip-quick-action-item', UipQuickActionItem)\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    'uip-quick-actions': UipQuickActions\n    'uip-quick-action-item': UipQuickActionItem\n  }\n}\n",
      "type": "registry:file",
      "target": "src/uip/blocks/quick-actions/quick-actions.ts"
    }
  ],
  "dependencies": [
    "lit",
    "lucide"
  ],
  "registryDependencies": [
    "https://uipkge.dev/r/lit/icon-box.json",
    "https://uipkge.dev/r/lit/lit-core.json",
    "https://uipkge.dev/r/lit/section-card.json"
  ]
}
