From 14987ebc7b193fd0107158c521532829d20be268 Mon Sep 17 00:00:00 2001 From: Gustavo <1001.29587789.ucla@gmail.com> Date: Fri, 16 May 2025 17:51:36 -0400 Subject: [PATCH] button: add type prop and auto-disable on click --- package-lock.json | 4 +-- src/components/Button.tsx | 33 +++++++++++++++---- .../validations/checkoutShippingInfoSchema.ts | 20 +++++++++++ 3 files changed, 49 insertions(+), 8 deletions(-) create mode 100644 src/lib/validations/checkoutShippingInfoSchema.ts diff --git a/package-lock.json b/package-lock.json index abd50b1..5e63970 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ecommerce", - "version": "0.3.1", + "version": "0.4.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ecommerce", - "version": "0.3.1", + "version": "0.4.0", "dependencies": { "@headlessui/react": "^2.2.0", "@heroicons/react": "^2.2.0", diff --git a/src/components/Button.tsx b/src/components/Button.tsx index 82c6827..ecc324c 100644 --- a/src/components/Button.tsx +++ b/src/components/Button.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useState } from 'react'; import { PlusCircleIcon } from '@heroicons/react/24/outline'; import '../styles/globals.css'; import { Colors } from '../styles/styles'; @@ -16,6 +16,7 @@ type ButtonProps = { className?: string; variant?: 'submit' | 'white' | 'light' | 'icon' | 'gray'; textColor?: string; + type?: 'submit' | 'reset' | 'button' | undefined; }; const Button: React.FC = ({ @@ -31,7 +32,26 @@ const Button: React.FC = ({ className = '', variant = 'submit', textColor = 'white', + type = undefined, }) => { + const [internalDisabled, setInternalDisabled] = useState(false); + + const handleClick = () => { + if (disabled || internalDisabled) return; + + setInternalDisabled(true); + + const result = onClick?.(); + + if (result && typeof result === 'object' && 'then' in result) { + (result as Promise).finally(() => setInternalDisabled(false)); + } else { + setInternalDisabled(false); + } + }; + + const isDisabled = disabled || internalDisabled; + const baseStyles = `font-medium transition duration-200 rounded-md shadow-sm border-transparent px-${paddingX} py-${paddingY} text-${textSize}`; const variantStyles = @@ -47,10 +67,11 @@ const Button: React.FC = ({ return (