1- import type { TVClassName , TVProps } from '@fuf-stack/pixel-utils' ;
21import type { ButtonProps as HeroButtonProps } from '@heroui/button' ;
32import type { ReactNode } from 'react' ;
43
54import { Button as HeroButton } from '@heroui/button' ;
65import { button as heroButtonVariants } from '@heroui/theme' ;
76
8- import { tv , variantsToClassNames } from '@fuf-stack/pixel-utils' ;
7+ import { tv } from '@fuf-stack/pixel-utils' ;
98
109import LoadingSpinner from './subcomponents/LoadingSpinner' ;
1110
12- export const buttonVariants = tv ( {
13- slots : {
14- base : '' ,
15- } ,
11+ const tvConfig = < T extends Parameters < typeof tv > [ 0 ] > ( c : T ) => {
12+ return c ;
13+ } ;
14+
15+ const buttonVariantsConfig = tvConfig ( {
16+ extend : heroButtonVariants ,
1617 variants : {
1718 color : {
19+ ...heroButtonVariants . variants . color ,
1820 // see: https://github.com/heroui-inc/heroui/blob/canary/packages/core/theme/src/components/button.ts
1921 info : '' ,
20- ...heroButtonVariants . variants . color ,
2122 } ,
2223 variant : heroButtonVariants . variants . variant ,
2324 size : heroButtonVariants . variants . size ,
@@ -26,13 +27,23 @@ export const buttonVariants = tv({
2627 // white text on solid / shadow success button
2728 {
2829 color : 'success' ,
29- variant : [ 'solid' , 'shadow' ] ,
30+ variant : 'solid' ,
31+ class : 'text-white' ,
32+ } ,
33+ {
34+ color : 'success' ,
35+ variant : 'shadow' ,
3036 class : 'text-white' ,
3137 } ,
3238 // white text on solid / shadow warning button
3339 {
3440 color : 'warning' ,
35- variant : [ 'solid' , 'shadow' ] ,
41+ variant : 'solid' ,
42+ class : 'text-white' ,
43+ } ,
44+ {
45+ color : 'warning' ,
46+ variant : 'shadow' ,
3647 class : 'text-white' ,
3748 } ,
3849 {
@@ -43,7 +54,7 @@ export const buttonVariants = tv({
4354 {
4455 color : 'info' ,
4556 variant : 'shadow' ,
46- class : 'text-info-foreground" bg-info shadow-info/40 shadow-lg' ,
57+ class : 'text-info-foreground bg-info shadow-info/40 shadow-lg' ,
4758 } ,
4859 {
4960 color : 'info' ,
@@ -74,18 +85,17 @@ export const buttonVariants = tv({
7485 ] ,
7586} ) ;
7687
77- type VariantProps = TVProps < typeof buttonVariants > ;
78- type ClassName = TVClassName < typeof buttonVariants > ;
88+ export const buttonVariants : ReturnType < typeof tv > = tv ( buttonVariantsConfig ) ;
7989
80- export interface ButtonProps extends VariantProps {
90+ export interface ButtonProps {
8191 /** sets HTML aria-label attribute */
8292 ariaLabel ?: string ;
8393 /** content of the button */
8494 children ?: ReactNode ;
8595 /** CSS class name */
86- className ?: ClassName ;
96+ className ?: string ;
8797 /** color of the button */
88- color ?: VariantProps [ 'color' ] ;
98+ color ?: HeroButtonProps [ 'color' ] | 'info' ;
8999 /** disables the button */
90100 disabled ?: boolean ;
91101 /** disables all animations */
@@ -107,7 +117,7 @@ export interface ButtonProps extends VariantProps {
107117 /** HTML button type attribute */
108118 type ?: 'button' | 'submit' | 'reset' | undefined ;
109119 /** visual style variant */
110- variant ?: VariantProps [ 'variant' ] ;
120+ variant ?: HeroButtonProps [ 'variant' ] ;
111121}
112122
113123/**
@@ -116,7 +126,7 @@ export interface ButtonProps extends VariantProps {
116126const Button = ( {
117127 ariaLabel = undefined ,
118128 children = undefined ,
119- className = undefined ,
129+ className : _className = undefined ,
120130 color = 'default' ,
121131 disableAnimation = false ,
122132 disabled = false ,
@@ -130,27 +140,27 @@ const Button = ({
130140 type = undefined ,
131141 variant = 'solid' ,
132142} : ButtonProps ) => {
133- // classNames from slots
134- const variants = buttonVariants ( { color, variant, size } ) ;
135- const classNames = variantsToClassNames ( variants , className , 'base' ) ;
143+ const className = buttonVariants ( {
144+ className : _className ,
145+ disableAnimation,
146+ isDisabled : disabled ,
147+ color,
148+ size,
149+ variant,
150+ isIconOnly : ! ! ( icon && ! children ) ,
151+ radius,
152+ } ) ;
136153
137154 return (
138155 < HeroButton
139156 aria-label = { ariaLabel }
140- className = { classNames . base }
141- color = { color as HeroButtonProps [ 'color' ] }
157+ className = { className }
142158 data-testid = { testId }
143- disableAnimation = { disableAnimation }
144159 disableRipple = { disableAnimation || ! ripple }
145- isDisabled = { disabled }
146- isIconOnly = { ! ! ( icon && ! children ) }
147160 isLoading = { loading }
148161 onPress = { onClick }
149- radius = { radius }
150- size = { size }
151162 spinner = { < LoadingSpinner /> }
152163 type = { type }
153- variant = { variant }
154164 >
155165 { icon }
156166 { children }
0 commit comments