{
  "name": "button",
  "type": "registry:ui",
  "framework": "vue",
  "dependencies": [],
  "registryDependencies": [
    "theme",
    "control-types"
  ],
  "files": [
    {
      "path": "packages/components/button/vue/Button.vue",
      "target": "components/ui/button/Button.vue",
      "content": "<script setup lang=\"ts\">\n// ------- IMPORTS -------\n\nimport { useTemplateRef } from 'vue'\nimport type { ButtonProps } from './types'\n\n// ------- COMPONENT API -------\n\nconst props = withDefaults(defineProps<ButtonProps>(), {\n  variant: 'default',\n  size: 'md',\n  type: 'button',\n})\n\ndefineSlots<{ default(): unknown; prefix?(): unknown; suffix?(): unknown }>()\n\n// ------- CONSTANTS -------\n\nconst variants = {\n  default: 'bg-primary text-primary-foreground hover:bg-primary-hover',\n  secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary-hover',\n  outline: 'border border-border bg-background text-foreground hover:bg-secondary',\n  ghost: 'text-foreground hover:bg-secondary',\n  destructive: 'bg-destructive text-destructive-foreground hover:bg-destructive-hover',\n}\n\nconst sizes = { sm: 'h-8 px-3 text-xs', md: 'h-10 px-4 text-sm', lg: 'h-12 px-6 text-base' }\n\n// ------- STATE -------\n\nconst element = useTemplateRef<HTMLButtonElement>('element')\n\n// ------- EXPOSED API -------\n\ndefineExpose({ element, focus: () => element.value?.focus() })\n</script>\n<template>\n  <button\n    ref=\"element\"\n    :type=\"type\"\n    :disabled=\"disabled || loading\"\n    :aria-busy=\"loading || undefined\"\n    class=\"ui-motion cursor-pointer relative inline-flex shrink-0 items-center justify-center rounded-ui font-medium focus:z-10 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed\"\n    :class=\"[variants[props.variant], sizes[props.size], { 'opacity-50': disabled && !loading }]\"\n  >\n    <span\n      class=\"ui-motion ui-button-content inline-flex min-w-0 items-center justify-center gap-2\"\n      :class=\"{ 'opacity-0': loading }\"\n    >\n      <span v-if=\"$slots.prefix\" class=\"inline-flex shrink-0 items-center\"\n        ><slot name=\"prefix\" /></span\n      >\n      <slot />\n      <span v-if=\"$slots.suffix\" class=\"inline-flex shrink-0 items-center\"\n        ><slot name=\"suffix\" /></span\n      >\n    </span>\n    <Transition name=\"ui-loading\">\n      <span\n        v-if=\"loading\"\n        aria-hidden=\"true\"\n        class=\"ui-button-loader pointer-events-none absolute flex size-4 items-center justify-center\"\n      >\n        <span\n          class=\"size-4 animate-spin rounded-full border-2 border-current border-r-transparent motion-reduce:animate-none\"\n        />\n      </span>\n    </Transition>\n  </button>\n</template>\n"
    },
    {
      "path": "packages/components/button/types.ts",
      "target": "components/ui/button/types.ts",
      "content": "// ------- IMPORTS -------\n\nimport type { ControlSize } from '../shared/types/index'\n\n// ------- TYPES -------\n\nexport interface ButtonProps {\n  variant?: 'default' | 'secondary' | 'outline' | 'ghost' | 'destructive'\n  size?: ControlSize\n  disabled?: boolean\n  loading?: boolean\n  type?: 'button' | 'submit' | 'reset'\n}\n"
    }
  ]
}