@@ -22,7 +22,7 @@ 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
27
export type Common = {
28
28
id ?: string ;
@@ -32,6 +32,7 @@ export namespace TagProps {
32
32
style ?: CSSProperties ;
33
33
title ?: string ;
34
34
children : ReactNode ;
35
+ as ?: "p" | "span" | "button" | "a" ;
35
36
} ;
36
37
37
38
export type WithIcon = {
@@ -44,18 +45,20 @@ export namespace TagProps {
44
45
} ;
45
46
46
47
export type AsAnchor = {
48
+ as ?: "a" ;
47
49
linkProps : RegisteredLinkProps ;
48
50
onClick ?: never ;
49
51
nativeButtonProps ?: never ;
50
- /** @deprecated Tag is now <p> by default. Use `nativeParagraphProps` instead. */
52
+ /** @deprecated Tag is now ` <p>` by default. Use `nativeParagraphProps` instead. */
51
53
nativeSpanProps ?: never ;
52
54
nativeParagraphProps ?: never ;
53
55
dismissible ?: never ;
54
56
pressed ?: never ;
55
57
} ;
56
58
export type AsButton = {
59
+ as ?: "button" ;
57
60
linkProps ?: never ;
58
- /** @deprecated Tag is now <p> by default. Use `nativeParagraphProps` instead. */
61
+ /** @deprecated Tag is now ` <p>` by default. Use `nativeParagraphProps` instead. */
59
62
nativeSpanProps ?: never ;
60
63
nativeParagraphProps ?: never ;
61
64
/** Default: false */
@@ -65,104 +68,118 @@ export namespace TagProps {
65
68
nativeButtonProps ?: ComponentProps < "button" > & DataAttribute ;
66
69
} ;
67
70
export type AsParagraph = {
71
+ as ?: "p" ;
68
72
linkProps ?: never ;
69
73
onClick ?: never ;
70
74
dismissible ?: never ;
71
75
pressed ?: never ;
72
76
nativeButtonProps ?: never ;
73
- /** @deprecated Tag is now <p> by default. Use `nativeParagraphProps` instead. */
77
+ /** @deprecated Tag is now ` <p>` by default. Use `nativeParagraphProps` instead. */
74
78
nativeSpanProps ?: ComponentProps < "span" > & DataAttribute ;
75
79
nativeParagraphProps ?: ComponentProps < "p" > & DataAttribute ;
76
80
} ;
77
-
78
- /** @deprecated Tag is now <p> by default. Use `AsParagraph` instead. */
79
- export type AsSpan = AsParagraph ;
81
+ export type AsSpan = {
82
+ as : "span" ;
83
+ linkProps ?: never ;
84
+ onClick ?: never ;
85
+ dismissible ?: never ;
86
+ pressed ?: never ;
87
+ nativeButtonProps ?: never ;
88
+ nativeSpanProps ?: ComponentProps < "span" > & DataAttribute ;
89
+ nativeParagraphProps ?: never ;
90
+ } ;
80
91
}
81
92
82
93
/** @see <https://components.react-dsfr.codegouv.studio/?path=/docs/components-tag> */
83
94
export const Tag = memo (
84
- forwardRef < HTMLButtonElement | HTMLAnchorElement | HTMLParagraphElement , TagProps > (
85
- ( props , ref ) => {
86
- const {
87
- id : id_props ,
88
- className : prop_className ,
89
- children,
90
- title,
91
- iconId,
92
- small = false ,
93
- pressed,
94
- dismissible = false ,
95
- linkProps,
96
- nativeButtonProps,
97
- nativeParagraphProps,
98
- nativeSpanProps,
99
- style,
100
- onClick,
101
- ...rest
102
- } = props ;
95
+ forwardRef <
96
+ HTMLButtonElement | HTMLAnchorElement | HTMLParagraphElement | HTMLSpanElement ,
97
+ TagProps
98
+ > ( ( props , ref ) => {
99
+ const {
100
+ id : id_props ,
101
+ className : prop_className ,
102
+ children,
103
+ title,
104
+ iconId,
105
+ small = false ,
106
+ pressed,
107
+ dismissible = false ,
108
+ linkProps,
109
+ nativeButtonProps,
110
+ nativeParagraphProps,
111
+ nativeSpanProps,
112
+ style,
113
+ onClick,
114
+ as : AsTag = "p" ,
115
+ ...rest
116
+ } = props ;
103
117
104
- assert < Equals < keyof typeof rest , never > > ( ) ;
118
+ assert < Equals < keyof typeof rest , never > > ( ) ;
105
119
106
- const id = useAnalyticsId ( {
107
- "defaultIdPrefix" : "fr-tag" ,
108
- "explicitlyProvidedId" : id_props
109
- } ) ;
120
+ const id = useAnalyticsId ( {
121
+ "defaultIdPrefix" : "fr-tag" ,
122
+ "explicitlyProvidedId" : id_props
123
+ } ) ;
110
124
111
- const { Link } = getLink ( ) ;
125
+ const { Link } = getLink ( ) ;
112
126
113
- const className = cx (
114
- fr . cx (
115
- "fr-tag" ,
116
- small && `fr-tag--sm` ,
117
- iconId ,
118
- iconId && "fr-tag--icon-left" , // actually, it's always left but we need it in order to have the icon rendering
119
- dismissible && "fr-tag--dismiss"
120
- ) ,
121
- linkProps !== undefined && linkProps . className ,
122
- prop_className
123
- ) ;
127
+ const className = cx (
128
+ fr . cx (
129
+ "fr-tag" ,
130
+ small && `fr-tag--sm` ,
131
+ iconId ,
132
+ iconId && "fr-tag--icon-left" , // actually, it's always left but we need it in order to have the icon rendering
133
+ dismissible && "fr-tag--dismiss"
134
+ ) ,
135
+ linkProps !== undefined && linkProps . className ,
136
+ prop_className
137
+ ) ;
124
138
125
- const nativeParagraphOrSpanProps = nativeParagraphProps ?? nativeSpanProps ;
139
+ // to support old usage
140
+ const nativeParagraphOrSpanProps = nativeParagraphProps ?? nativeSpanProps ;
126
141
127
- return (
128
- < >
129
- { linkProps !== undefined && (
130
- < Link
131
- { ...linkProps }
132
- id = { id_props ?? linkProps . id ?? id }
133
- title = { title ?? linkProps . title }
134
- className = { cx ( linkProps ?. className , className ) }
135
- style = { {
136
- ...linkProps ?. style ,
137
- ...style
138
- } }
139
- ref = { ref as React . ForwardedRef < HTMLAnchorElement > }
140
- { ...rest }
141
- >
142
- { children }
143
- </ Link >
144
- ) }
145
- { nativeButtonProps !== undefined && (
146
- < button
147
- { ...nativeButtonProps }
148
- id = { id_props ?? nativeButtonProps . id ?? id }
149
- className = { cx ( nativeButtonProps ?. className , className ) }
150
- style = { {
151
- ...nativeButtonProps ?. style ,
152
- ...style
153
- } }
154
- title = { title ?? nativeButtonProps ?. title }
155
- onClick = { onClick ?? nativeButtonProps ?. onClick }
156
- disabled = { nativeButtonProps ?. disabled }
157
- ref = { ref as React . ForwardedRef < HTMLButtonElement > }
158
- aria-pressed = { pressed }
159
- { ...rest }
160
- >
161
- { children }
162
- </ button >
163
- ) }
164
- { linkProps === undefined && nativeButtonProps === undefined && (
165
- < p
142
+ return (
143
+ < >
144
+ { linkProps !== undefined && (
145
+ < Link
146
+ { ...linkProps }
147
+ id = { id_props ?? linkProps . id ?? id }
148
+ title = { title ?? linkProps . title }
149
+ className = { cx ( linkProps ?. className , className ) }
150
+ style = { {
151
+ ...linkProps ?. style ,
152
+ ...style
153
+ } }
154
+ ref = { ref as React . ForwardedRef < HTMLAnchorElement > }
155
+ { ...rest }
156
+ >
157
+ { children }
158
+ </ Link >
159
+ ) }
160
+ { nativeButtonProps !== undefined && (
161
+ < button
162
+ { ...nativeButtonProps }
163
+ id = { id_props ?? nativeButtonProps . id ?? id }
164
+ className = { cx ( nativeButtonProps ?. className , className ) }
165
+ style = { {
166
+ ...nativeButtonProps ?. style ,
167
+ ...style
168
+ } }
169
+ title = { title ?? nativeButtonProps ?. title }
170
+ onClick = { onClick ?? nativeButtonProps ?. onClick }
171
+ disabled = { nativeButtonProps ?. disabled }
172
+ ref = { ref as React . ForwardedRef < HTMLButtonElement > }
173
+ aria-pressed = { pressed }
174
+ { ...rest }
175
+ >
176
+ { children }
177
+ </ button >
178
+ ) }
179
+ { linkProps === undefined &&
180
+ nativeButtonProps === undefined &&
181
+ ( AsTag === "span" || AsTag === "p" ) && (
182
+ < AsTag
166
183
{ ...nativeParagraphOrSpanProps }
167
184
id = { id_props ?? nativeParagraphOrSpanProps ?. id ?? id }
168
185
className = { cx ( nativeParagraphOrSpanProps ?. className , className ) }
@@ -175,12 +192,11 @@ export const Tag = memo(
175
192
{ ...rest }
176
193
>
177
194
{ children }
178
- </ p >
195
+ </ AsTag >
179
196
) }
180
- </ >
181
- ) ;
182
- }
183
- )
197
+ </ >
198
+ ) ;
199
+ } )
184
200
) as MemoExoticComponent <
185
201
ForwardRefExoticComponent <
186
202
TagProps . Common &
@@ -189,6 +205,7 @@ export const Tag = memo(
189
205
| ( TagProps . AsAnchor & RefAttributes < HTMLAnchorElement > )
190
206
| ( TagProps . AsButton & RefAttributes < HTMLButtonElement > )
191
207
| ( TagProps . AsParagraph & RefAttributes < HTMLParagraphElement > )
208
+ | ( TagProps . AsSpan & RefAttributes < HTMLParagraphElement > )
192
209
)
193
210
>
194
211
> ;
0 commit comments