{"$schema":"https://ui.shadcn.com/schema/registry-item.json","author":"Eduardo Calvo <educlopez93@gmail.com>","css":{},"dependencies":["motion"],"description":"A ClipCornersButton component for SmoothUI.","devDependencies":[],"files":[{"content":"\"use client\";\n\nimport SmoothButton from \"@/components/smoothui/smooth-button\";\nimport { motion, useReducedMotion } from \"motion/react\";\nimport { useEffect, useState } from \"react\";\n\nexport interface ClipCornersButtonProps {\n  children: React.ReactNode;\n  className?: string;\n  onClick?: () => void;\n}\n\nexport function ClipCornersButton({\n  children,\n  className = \"\",\n  onClick,\n}: ClipCornersButtonProps) {\n  const [isHovered, setIsHovered] = useState(false);\n  const shouldReduceMotion = useReducedMotion();\n  const [isHoverDevice, setIsHoverDevice] = useState(false);\n\n  // Distance triangles move on hover\n  const move = -4;\n\n  useEffect(() => {\n    const mediaQuery = window.matchMedia(\"(hover: hover) and (pointer: fine)\");\n    setIsHoverDevice(mediaQuery.matches);\n\n    const handleChange = (e: MediaQueryListEvent) => {\n      setIsHoverDevice(e.matches);\n    };\n\n    mediaQuery.addEventListener(\"change\", handleChange);\n    return () => mediaQuery.removeEventListener(\"change\", handleChange);\n  }, []);\n\n  return (\n    <SmoothButton\n      className={`relative overflow-hidden rounded-none border-none bg-foreground px-8 py-4 font-mono text-2xl text-background hover:bg-foreground/90 ${className}`}\n      onClick={onClick}\n      onMouseEnter={() => {\n        if (isHoverDevice) {\n          setIsHovered(true);\n        }\n      }}\n      onMouseLeave={() => setIsHovered(false)}\n      style={{ borderRadius: 8 }}\n      type=\"button\"\n    >\n      {/* Top-left triangle */}\n      <motion.div\n        animate={\n          shouldReduceMotion || !isHoverDevice\n            ? {}\n            : {\n                x: isHovered ? -move : 0,\n                y: isHovered ? -move : 0,\n              }\n        }\n        className=\"absolute top-1.5 left-1.5\"\n        initial={false}\n        style={{ height: 8, width: 8 }}\n        transition={\n          shouldReduceMotion\n            ? { duration: 0 }\n            : {\n                damping: 24,\n                duration: 0.2,\n                stiffness: 400,\n                type: \"spring\" as const,\n              }\n        }\n      >\n        <svg\n          aria-label=\"Top-left triangle\"\n          className=\"fill-background\"\n          height=\"8\"\n          width=\"8\"\n        >\n          <title>Top-left triangle</title>\n          <polygon fill=\"currentColor\" points=\"0,0 8,0 0,8\" />\n        </svg>\n      </motion.div>\n      {/* Top-right triangle */}\n      <motion.div\n        animate={\n          shouldReduceMotion || !isHoverDevice\n            ? {}\n            : {\n                x: isHovered ? move : 0,\n                y: isHovered ? -move : 0,\n              }\n        }\n        className=\"absolute top-1.5 right-1.5\"\n        initial={false}\n        style={{ height: 8, width: 8 }}\n        transition={\n          shouldReduceMotion\n            ? { duration: 0 }\n            : {\n                damping: 24,\n                duration: 0.2,\n                stiffness: 400,\n                type: \"spring\" as const,\n              }\n        }\n      >\n        <svg\n          aria-label=\"Top-right triangle\"\n          className=\"fill-background\"\n          height=\"8\"\n          width=\"8\"\n        >\n          <title>Top-right triangle</title>\n          <polygon fill=\"currentColor\" points=\"8,0 8,8 0,0\" />\n        </svg>\n      </motion.div>\n      {/* Bottom-left triangle */}\n      <motion.div\n        animate={\n          shouldReduceMotion || !isHoverDevice\n            ? {}\n            : {\n                x: isHovered ? -move : 0,\n                y: isHovered ? move : 0,\n              }\n        }\n        className=\"absolute bottom-1.5 left-1.5\"\n        initial={false}\n        style={{ height: 8, width: 8 }}\n        transition={\n          shouldReduceMotion\n            ? { duration: 0 }\n            : {\n                damping: 24,\n                duration: 0.2,\n                stiffness: 400,\n                type: \"spring\" as const,\n              }\n        }\n      >\n        <svg\n          aria-label=\"Bottom-left triangle\"\n          className=\"fill-background\"\n          height=\"8\"\n          width=\"8\"\n        >\n          <title>Bottom-left triangle</title>\n          <polygon fill=\"currentColor\" points=\"0,8 8,8 0,0\" />\n        </svg>\n      </motion.div>\n      {/* Bottom-right triangle */}\n      <motion.div\n        animate={\n          shouldReduceMotion || !isHoverDevice\n            ? {}\n            : {\n                x: isHovered ? move : 0,\n                y: isHovered ? move : 0,\n              }\n        }\n        className=\"absolute right-1.5 bottom-1.5\"\n        initial={false}\n        style={{ height: 8, width: 8 }}\n        transition={\n          shouldReduceMotion\n            ? { duration: 0 }\n            : {\n                damping: 24,\n                duration: 0.2,\n                stiffness: 400,\n                type: \"spring\" as const,\n              }\n        }\n      >\n        <svg\n          aria-label=\"Bottom-right triangle\"\n          className=\"fill-background\"\n          height=\"8\"\n          width=\"8\"\n        >\n          <title>Bottom-right triangle</title>\n          <polygon fill=\"currentColor\" points=\"8,8 0,8 8,0\" />\n        </svg>\n      </motion.div>\n      <span className=\"relative z-10 flex w-full select-none items-center justify-center\">\n        {children}\n      </span>\n    </SmoothButton>\n  );\n}\n\nexport default ClipCornersButton;\n","path":"index.tsx","target":"components/smoothui/clip-corners-button/index.tsx","type":"registry:ui"}],"name":"clip-corners-button","registryDependencies":["https://smoothui.dev/r/smooth-button.json"],"title":"Clip Corners Button","type":"registry:ui"}