diff --git a/components/shared/Button/v2/Button.stories.tsx b/components/shared/Button/v2/Button.stories.tsx index 4913d9a6..6ccc3cfc 100644 --- a/components/shared/Button/v2/Button.stories.tsx +++ b/components/shared/Button/v2/Button.stories.tsx @@ -1,13 +1,13 @@ import type { Meta, StoryObj } from "@storybook/react"; -import { Button, ButtonSize, ButtonType } from "./Button"; +import { Button, ButtonSize, ButtonVariant } from "./Button"; import { ReactNode } from "react"; import Icon from "../../Icon"; -const buttonTypeOptions: (ButtonType | undefined)[] = [ +const buttonVariantOptions: (ButtonVariant | undefined)[] = [ undefined, - ButtonType.PRIMARY, - ButtonType.SECONDARY, - ButtonType.HIGHLIGHT, + ButtonVariant.PRIMARY, + ButtonVariant.SECONDARY, + ButtonVariant.HIGHLIGHT, ]; const buttonSizeOptions: (ButtonSize | undefined)[] = [ @@ -38,46 +38,19 @@ const meta: Meta = { children: "Button", }, argTypes: { - component: { - control: { type: "select" }, - options: ["button", "a"], - }, - variant: { - control: { type: "select" }, - options: buttonTypeOptions, - }, - size: { - control: { type: "select" }, - options: buttonSizeOptions, - }, - iconName: { - control: { type: "select" }, - options: buttonIconNameOptions, - description: - "Icon name from `IconV2` component. If `icon` is not `undefinded`, this prop will be ignored.", - }, - icon: { - control: { type: "select" }, - options: buttonIconOptions, - description: - "Custom icons or any prefix component. If `iconName` is not `undefinded`, this prop will be ignored.", - }, - boxFancyClassName: { - control: { type: "text" }, - description: "custom class name for inner div", - defaultValue: "", - }, className: { control: { type: "text" }, description: "custom class name", defaultValue: "", }, + disabled: { + control: { type: "boolean" }, + }, style: { control: { type: "object" }, description: "custom style", defaultValue: {}, }, - ref: { control: { disable: true } }, }, }; @@ -92,7 +65,7 @@ export const Playground: Story = { export const Variant: Story = { render: (args) => ( <> - {buttonTypeOptions.map((variant) => ( + {buttonVariantOptions.map((variant) => ( diff --git a/components/shared/Button/v2/Button.test.tsx b/components/shared/Button/v2/Button.test.tsx index 8d6cc665..7e3c219f 100644 --- a/components/shared/Button/v2/Button.test.tsx +++ b/components/shared/Button/v2/Button.test.tsx @@ -1,7 +1,7 @@ import React from "react"; import { render, screen } from "@testing-library/react"; import "@testing-library/jest-dom"; -import { Button } from "./Button"; +import { Button, ButtonVariant } from "./Button"; describe("ButtonV2", () => { it("should renders button text", () => { @@ -16,7 +16,7 @@ describe("ButtonV2", () => { it("should have correct className", () => { render( - ); diff --git a/components/shared/Button/v2/Button.tsx b/components/shared/Button/v2/Button.tsx index 94fd31dd..a89731df 100644 --- a/components/shared/Button/v2/Button.tsx +++ b/components/shared/Button/v2/Button.tsx @@ -1,17 +1,11 @@ -import React, { - ElementType, - ReactNode, - forwardRef, - useCallback, - useMemo, -} from "react"; +import React, { ReactNode, forwardRef, useCallback } from "react"; import { cn } from "@/lib/utils"; import BoxFancy, { BoxFancyBorderGradientVariant } from "../../BoxFancy"; import { IconNameV2 } from "@/components/shared/Icon/v2/icons"; -import IconV2 from "@/components/shared/Icon/v2"; -import { PolymorphicComponentProp, PolymorphicRef } from "@/lib/types"; +import Icon from "@/components/shared/Icon/v2"; +import { PolymorphicRef } from "@/lib/types"; -export enum ButtonType { +export enum ButtonVariant { PRIMARY = "primary", SECONDARY = "secondary", HIGHLIGHT = "highlight", @@ -22,11 +16,14 @@ export enum ButtonSize { SMALL = "small", } -const buttonTypeClasses: Record = { +const commonDisabledClasses = + "disabled:cursor-not-allowed disabled:bg-none disabled:bg-gray-800 disabled:border-gray-500 disabled:text-gray-200 disabled:stroke-gray-200 disabled:fill-gray-200"; + +const buttonTypeClasses: Record = { primary: "text-primary-700 bg-primary-200 hover:text-primary-50 hover:bg-primary-300 active:text-primary-50 active:bg-primary-400", secondary: - "text-primary-200 bg-transparent hover:bg-primary-300/40 active:bg-primary-200/20 disabled:bg-transparent disabled:border-grey-500 disabled:border", + "text-primary-200 bg-transparent hover:bg-primary-300/40 active:bg-primary-200/20 disabled:bg-transparent disabled:border", highlight: "text-primary-50 gradient-purple hover:gradient-purple-2 active:gradient-purple-3", }; @@ -37,43 +34,35 @@ const buttonSizeClasses: Record = { }; interface BaseButtonProps { - variant?: ButtonType; + variant?: ButtonVariant | `${ButtonVariant}`; size?: ButtonSize; icon?: ReactNode; iconName?: IconNameV2; - disabled?: boolean; - // inner div className for styling - boxFancyClassName?: string; iconClassName?: string; } -type ButtonProps = PolymorphicComponentProp< - C, - BaseButtonProps ->; +type ButtonProps = BaseButtonProps & React.ComponentPropsWithoutRef<"button">; -type InnerButtonComponent = ( - props: ButtonProps, - ref?: PolymorphicRef +type InnerButtonComponent = ( + props: ButtonProps, + ref?: PolymorphicRef<"button"> ) => React.ReactElement | null; -const iconTypeClasses: Record = { +const iconTypeClasses: Record = { primary: "stroke-primary-700 hover:stroke-primary-50 active:stroke-primary-50", - secondary: "stroke-primary-200", + secondary: "stroke-primary-200 disabled:stroke-gray-500", highlight: "stroke-primary-50", }; const InteralButton: InnerButtonComponent = ( { - component, - variant = ButtonType.PRIMARY, + variant = ButtonVariant.PRIMARY, size = ButtonSize.REGULAR, icon, iconName, disabled, className, - boxFancyClassName, iconClassName, children, onClick, @@ -81,7 +70,6 @@ const InteralButton: InnerButtonComponent = ( }, ref ) => { - const Component = component || "button"; const handleClick = useCallback( (event: React.MouseEvent) => { if (disabled) { @@ -94,45 +82,33 @@ const InteralButton: InnerButtonComponent = ( [disabled, onClick] ); - const buttonClassName = useMemo( - () => - cn( - "w-full items-center fz-16-b transition-colors transition-[border-image] ease-in", - "disabled:text-grey-200 disabled:bg-grey-800", - buttonTypeClasses[variant], - buttonSizeClasses[size], - iconTypeClasses[variant], - boxFancyClassName - ), - [boxFancyClassName, size, variant] - ); - - const iconClasses = useMemo( - () => cn("w-6 h-6 stroke-inherit", iconClassName), - [iconClassName] + const boxFancyClassName = cn( + "w-fit items-center fz-16-b transition-colors transition-[border-image] ease-in", + commonDisabledClasses, + buttonTypeClasses[variant], + buttonSizeClasses[size], + iconTypeClasses[variant], + className ); + const iconClasses = cn("w-6 h-6 stroke-inherit", iconClassName); const borderGradientColor: BoxFancyBorderGradientVariant = - variant === ButtonType.SECONDARY && !disabled ? "purple" : "none"; + variant === ButtonVariant.SECONDARY && !disabled ? "purple" : "none"; return ( - - - {icon || - (iconName && )} - {children} - - + {icon || (iconName && )} + {children} + ); }; diff --git a/pages/login.tsx b/pages/login.tsx index c6d66b46..1f577aa4 100644 --- a/pages/login.tsx +++ b/pages/login.tsx @@ -9,7 +9,7 @@ import { useRouter } from "next/router"; import { GetStaticProps } from "next"; import { serverSideTranslations } from "next-i18next/serverSideTranslations"; -import ButtonV2, { ButtonType } from "@/components/shared/Button/v2"; +import ButtonV2, { ButtonVariant } from "@/components/shared/Button/v2"; import Cover from "@/components/shared/Cover"; import IconV2 from "@/components/shared/Icon/v2"; @@ -66,21 +66,21 @@ const Login: NextPageWithProps = () => { const loginButtons = useMemo(() => { return LoginMethods.map(({ text, type, icon }) => ( - onLoginClick(e, type)} - > - {text} - + + onLoginClick(e, type)} + > + {text} + + )); }, [internalEndpoint, onLoginClick]);