{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "button", "dependencies": [ "@radix-ui/react-slot", "class-variance-authority", "classnames" ], "registryDependencies": [ "https://powui.dev/r/utils.json", "https://powui.dev/r/theme.json" ], "files": [ { "path": "src/components/ui/button.tsx", "content": "\"use client\";\n\nimport * as React from \"react\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\n\nimport { cn } from \"@/lib/utils\";\nimport cx from \"classnames\";\n\nconst ButtonState = {\n Rest: \"rest\",\n Pressed: \"pressed\",\n Raised: \"raised\",\n} as const;\n\ntype ButtonStateType = (typeof ButtonState)[keyof typeof ButtonState];\n\nconst buttonVariants = cva(\n cx(\n \"inline-flex items-center justify-center gap-2 whitespace-nowrap text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40\",\n \"border-3 border-solid border-foreground text-foreground shadow-[-6px_6px_0_var(--foreground)] py-2 px-4\",\n \"transition-[translate,box-shadow] duration-[150ms] ease-[cubic-bezier(.67,1.5,.95,1.24)]\",\n \"cursor-pointer\",\n ),\n {\n variants: {\n variant: {\n default: \"bg-primary text-primary-foreground hover:bg-accent\",\n primary: \"bg-primary text-primary-foreground hover:bg-accent\",\n accent: \"bg-accent text-accent-foreground hover:bg-accent\",\n destructive: \"bg-destructive hover:bg-destructive dark:bg-destructive\",\n outline:\n \"border bg-background hover:bg-accent hover:text-accent-foreground dark:bg-input dark:border-input dark:hover:bg-input\",\n secondary: \"bg-secondary text-secondary-foreground hover:bg-secondary\",\n ghost:\n \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent border-0 shadow-none\",\n link: \"text-primary underline-offset-4 hover:underline\",\n },\n size: {\n default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n sm: \"h-8 gap-1.5 px-3 has-[>svg]:px-2.5\",\n lg: \"h-10 px-6 has-[>svg]:px-4\",\n icon: \"size-9\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n },\n);\n\nfunction Button({\n className,\n variant,\n size,\n asChild = false,\n ref,\n ...props\n}: React.ComponentProps<\"button\"> &\n VariantProps & {\n asChild?: boolean;\n ref?: React.Ref;\n }) {\n const Comp = asChild ? Slot : \"button\";\n\n const elem = React.useRef(null);\n\n const buttonStateToggle = (\n state: ButtonStateType,\n elem: HTMLButtonElement,\n ) => {\n if (!elem) return;\n const primaryColor = getComputedStyle(document.documentElement)\n .getPropertyValue(\"--foreground\")\n .trim();\n if (state === ButtonState.Pressed) {\n elem.style.setProperty(\"translate\", \"-4px 4px\");\n elem.style.setProperty(\"box-shadow\", `-2px 2px 0 ${primaryColor}`);\n } else if (state === ButtonState.Raised) {\n elem.style.setProperty(\"translate\", \"4px -4px\");\n elem.style.setProperty(\"box-shadow\", `-8px 8px 0 ${primaryColor}`);\n } else {\n elem.style.removeProperty(\"translate\");\n elem.style.removeProperty(\"box-shadow\");\n }\n };\n\n const loadRef = (node: HTMLButtonElement) => {\n if (!node) return;\n elem.current = node;\n elem.current.addEventListener(\"mousedown\", () => {\n buttonStateToggle(ButtonState.Pressed, node);\n });\n elem.current.addEventListener(\"mouseup\", () => {\n buttonStateToggle(ButtonState.Raised, node);\n });\n elem.current.addEventListener(\"mouseleave\", () => {\n buttonStateToggle(ButtonState.Rest, node);\n });\n elem.current.addEventListener(\"mouseenter\", () => {\n buttonStateToggle(ButtonState.Raised, node);\n });\n if (ref && typeof ref === \"function\") {\n ref(node);\n } else if (ref && typeof ref === \"object\") {\n ref.current = node;\n }\n };\n\n return (\n \n );\n}\n\nexport { Button, buttonVariants };\n", "type": "registry:ui" } ], "type": "registry:ui" }