@@ -22,8 +22,14 @@ type DataAttribute = Record<`data-${string}`, string | boolean | null | undefine
22
22
23
23
export type TagProps = TagProps . Common &
24
24
( TagProps . WithIcon | TagProps . WithoutIcon ) &
25
- ( TagProps . AsAnchor | TagProps . AsButton | TagProps . AsParagraph ) ;
25
+ ( TagProps . AsAnchor | TagProps . AsButton | TagProps . AsParagraph | TagProps . AsSpan ) ;
26
26
export namespace TagProps {
27
+ export type HTMLElement =
28
+ | HTMLButtonElement
29
+ | HTMLAnchorElement
30
+ | HTMLParagraphElement
31
+ | HTMLSpanElement ;
32
+
27
33
export type Common = {
28
34
id ?: string ;
29
35
className ?: string ;
@@ -32,6 +38,7 @@ export namespace TagProps {
32
38
style ?: CSSProperties ;
33
39
title ?: string ;
34
40
children : ReactNode ;
41
+ as ?: "p" | "span" | "button" | "a" ;
35
42
} ;
36
43
37
44
export type WithIcon = {
@@ -44,18 +51,20 @@ export namespace TagProps {
44
51
} ;
45
52
46
53
export type AsAnchor = {
54
+ as ?: "a" ;
47
55
linkProps : RegisteredLinkProps ;
48
56
onClick ?: never ;
49
57
nativeButtonProps ?: never ;
50
- /** @deprecated Tag is now <p> by default. Use `nativeParagraphProps` instead. */
58
+ /** @deprecated Tag is now ` <p>` by default. Use `nativeParagraphProps` instead. */
51
59
nativeSpanProps ?: never ;
52
60
nativeParagraphProps ?: never ;
53
61
dismissible ?: never ;
54
62
pressed ?: never ;
55
63
} ;
56
64
export type AsButton = {
65
+ as ?: "button" ;
57
66
linkProps ?: never ;
58
- /** @deprecated Tag is now <p> by default. Use `nativeParagraphProps` instead. */
67
+ /** @deprecated Tag is now ` <p>` by default. Use `nativeParagraphProps` instead. */
59
68
nativeSpanProps ?: never ;
60
69
nativeParagraphProps ?: never ;
61
70
/** Default: false */
@@ -65,23 +74,32 @@ export namespace TagProps {
65
74
nativeButtonProps ?: ComponentProps < "button" > & DataAttribute ;
66
75
} ;
67
76
export type AsParagraph = {
77
+ as ?: "p" ;
68
78
linkProps ?: never ;
69
79
onClick ?: never ;
70
80
dismissible ?: never ;
71
81
pressed ?: never ;
72
82
nativeButtonProps ?: never ;
73
- /** @deprecated Tag is now <p> by default. Use `nativeParagraphProps` instead. */
83
+ /** @deprecated Tag is now ` <p>` by default. Use `nativeParagraphProps` instead. */
74
84
nativeSpanProps ?: ComponentProps < "span" > & DataAttribute ;
75
85
nativeParagraphProps ?: ComponentProps < "p" > & DataAttribute ;
76
86
} ;
77
-
78
- /** @deprecated Tag is now <p> by default. Use `AsParagraph` instead. */
79
- export type AsSpan = AsParagraph ;
87
+ export type AsSpan = {
88
+ as : "span" ;
89
+ linkProps ?: never ;
90
+ onClick ?: never ;
91
+ dismissible ?: never ;
92
+ pressed ?: never ;
93
+ nativeButtonProps ?: never ;
94
+ nativeSpanProps ?: ComponentProps < "span" > & DataAttribute ;
95
+ nativeParagraphProps ?: never ;
96
+ } ;
80
97
}
81
98
82
99
/** @see <https://components.react-dsfr.codegouv.studio/?path=/docs/components-tag> */
83
100
export const Tag = memo (
84
- forwardRef < HTMLButtonElement | HTMLAnchorElement | HTMLParagraphElement , TagProps > (
101
+ forwardRef < TagProps . HTMLElement , TagProps > (
102
+ // -- (lint hack) to keep same indent as before
85
103
( props , ref ) => {
86
104
const {
87
105
id : id_props ,
@@ -98,6 +116,7 @@ export const Tag = memo(
98
116
nativeSpanProps,
99
117
style,
100
118
onClick,
119
+ as : AsTag = "p" ,
101
120
...rest
102
121
} = props ;
103
122
@@ -122,6 +141,7 @@ export const Tag = memo(
122
141
prop_className
123
142
) ;
124
143
144
+ // to support old usage
125
145
const nativeParagraphOrSpanProps = nativeParagraphProps ?? nativeSpanProps ;
126
146
127
147
return (
@@ -161,22 +181,24 @@ export const Tag = memo(
161
181
{ children }
162
182
</ button >
163
183
) }
164
- { linkProps === undefined && nativeButtonProps === undefined && (
165
- < p
166
- { ...nativeParagraphOrSpanProps }
167
- id = { id_props ?? nativeParagraphOrSpanProps ?. id ?? id }
168
- className = { cx ( nativeParagraphOrSpanProps ?. className , className ) }
169
- style = { {
170
- ...nativeParagraphOrSpanProps ?. style ,
171
- ...style
172
- } }
173
- title = { title ?? nativeParagraphOrSpanProps ?. title }
174
- ref = { ref as React . ForwardedRef < HTMLParagraphElement > }
175
- { ...rest }
176
- >
177
- { children }
178
- </ p >
179
- ) }
184
+ { linkProps === undefined &&
185
+ nativeButtonProps === undefined &&
186
+ ( AsTag === "span" || AsTag === "p" ) && (
187
+ < AsTag
188
+ { ...nativeParagraphOrSpanProps }
189
+ id = { id_props ?? nativeParagraphOrSpanProps ?. id ?? id }
190
+ className = { cx ( nativeParagraphOrSpanProps ?. className , className ) }
191
+ style = { {
192
+ ...nativeParagraphOrSpanProps ?. style ,
193
+ ...style
194
+ } }
195
+ title = { title ?? nativeParagraphOrSpanProps ?. title }
196
+ ref = { ref as React . ForwardedRef < HTMLParagraphElement > }
197
+ { ...rest }
198
+ >
199
+ { children }
200
+ </ AsTag >
201
+ ) }
180
202
</ >
181
203
) ;
182
204
}
@@ -189,6 +211,7 @@ export const Tag = memo(
189
211
| ( TagProps . AsAnchor & RefAttributes < HTMLAnchorElement > )
190
212
| ( TagProps . AsButton & RefAttributes < HTMLButtonElement > )
191
213
| ( TagProps . AsParagraph & RefAttributes < HTMLParagraphElement > )
214
+ | ( TagProps . AsSpan & RefAttributes < HTMLSpanElement > )
192
215
)
193
216
>
194
217
> ;
0 commit comments