1
+ import { HTMLAttributes } from 'react' ;
1
2
import { cn } from '../cn' ;
2
3
import { Anchor } from './anchor' ;
3
4
@@ -29,21 +30,38 @@ export declare namespace CallToActionProps {
29
30
30
31
export interface AnchorProps extends BaseProps , React . ComponentPropsWithoutRef < typeof Anchor > {
31
32
href : string ;
33
+ as ?: never ;
32
34
}
33
35
34
36
export interface ButtonProps
35
37
extends BaseProps ,
36
38
React . DetailedHTMLProps < React . ButtonHTMLAttributes < HTMLButtonElement > , HTMLButtonElement > {
37
39
href ?: never ;
38
- onClick : ( event : React . MouseEvent < HTMLButtonElement > ) => void ;
40
+ as ?: never ;
41
+ }
42
+
43
+ /**
44
+ * Use inside `<summary>` or as visual part of bigger interactive element.
45
+ * Prefer using `href` prop using CallToAction as `<button>` in other cases.
46
+ */
47
+ export interface NonInteractiveProps
48
+ extends BaseProps ,
49
+ React . DetailedHTMLProps < HTMLAttributes < HTMLElement > , HTMLElement > {
50
+ href ?: never ;
51
+ as : 'span' | 'div' ;
39
52
}
40
53
}
41
54
42
- export type CallToActionProps = CallToActionProps . AnchorProps | CallToActionProps . ButtonProps ;
55
+ export type CallToActionProps =
56
+ | CallToActionProps . AnchorProps
57
+ | CallToActionProps . ButtonProps
58
+ | CallToActionProps . NonInteractiveProps ;
43
59
44
60
/**
45
61
* This is called `Button` in Figma in the new Hive brand design system.
46
- * It's a styled variant of {@link Anchor}.
62
+ * It's a styled variant of {@link Anchor}. Based on the presence of the
63
+ * `href` prop or `as` prop, it renders a `button`, `a` or `props.as`
64
+ * (for non-interactive elements) element.
47
65
*
48
66
* // TODO: Consider renaming it to `Button`.
49
67
*/
@@ -54,22 +72,38 @@ export function CallToAction(props: CallToActionProps) {
54
72
props . className ,
55
73
) ;
56
74
75
+ const growingBorderBox = (
76
+ < span className = "absolute inset-0 rounded-lg border border-green-800 dark:border-neutral-200" />
77
+ ) ;
78
+
57
79
if ( 'href' in props && typeof props . href === 'string' ) {
58
80
const { className : _1 , variant : _2 , children, ...rest } = props ;
59
81
60
82
return (
61
83
< Anchor className = { className } { ...rest } >
62
- < div className = "absolute inset-0 rounded-lg border border-green-800 dark:border-neutral-200" />
84
+ { growingBorderBox }
63
85
{ children }
64
86
</ Anchor >
65
87
) ;
66
88
}
67
89
90
+ if ( props . as ) {
91
+ const { className : _1 , variant : _2 , children, as, ...rest } = props ;
92
+ // for this use case HTMLElement is enough, we don't need to use the more specific HTMLDivElement
93
+ const Root = as as 'span' ;
94
+ return (
95
+ < Root className = { className } { ...rest } >
96
+ { growingBorderBox }
97
+ { children }
98
+ </ Root >
99
+ ) ;
100
+ }
101
+
68
102
const { className : _1 , variant : _2 , children, ...rest } = props ;
69
103
70
104
return (
71
105
< button className = { className } { ...rest } >
72
- < div className = "absolute inset-0 rounded-lg border border-green-800 dark:border-neutral-200" />
106
+ { growingBorderBox }
73
107
{ children }
74
108
</ button >
75
109
) ;
0 commit comments