@@ -22,8 +22,14 @@ type DataAttribute = Record<`data-${string}`, string | boolean | null | undefine
2222
2323export type TagProps = TagProps . Common &
2424 ( TagProps . WithIcon | TagProps . WithoutIcon ) &
25- ( TagProps . AsAnchor | TagProps . AsButton | TagProps . AsParagraph ) ;
25+ ( TagProps . AsAnchor | TagProps . AsButton | TagProps . AsParagraph | TagProps . AsSpan ) ;
2626export namespace TagProps {
27+ export type HTMLElement =
28+ | HTMLButtonElement
29+ | HTMLAnchorElement
30+ | HTMLParagraphElement
31+ | HTMLSpanElement ;
32+
2733 export type Common = {
2834 id ?: string ;
2935 className ?: string ;
@@ -32,6 +38,7 @@ export namespace TagProps {
3238 style ?: CSSProperties ;
3339 title ?: string ;
3440 children : ReactNode ;
41+ as ?: "p" | "span" | "button" | "a" ;
3542 } ;
3643
3744 export type WithIcon = {
@@ -44,18 +51,20 @@ export namespace TagProps {
4451 } ;
4552
4653 export type AsAnchor = {
54+ as ?: "a" ;
4755 linkProps : RegisteredLinkProps ;
4856 onClick ?: never ;
4957 nativeButtonProps ?: never ;
50- /** @deprecated Tag is now <p> by default. Use `nativeParagraphProps` instead. */
58+ /** @deprecated Tag is now ` <p>` by default. Use `nativeParagraphProps` instead. */
5159 nativeSpanProps ?: never ;
5260 nativeParagraphProps ?: never ;
5361 dismissible ?: never ;
5462 pressed ?: never ;
5563 } ;
5664 export type AsButton = {
65+ as ?: "button" ;
5766 linkProps ?: never ;
58- /** @deprecated Tag is now <p> by default. Use `nativeParagraphProps` instead. */
67+ /** @deprecated Tag is now ` <p>` by default. Use `nativeParagraphProps` instead. */
5968 nativeSpanProps ?: never ;
6069 nativeParagraphProps ?: never ;
6170 /** Default: false */
@@ -65,23 +74,32 @@ export namespace TagProps {
6574 nativeButtonProps ?: ComponentProps < "button" > & DataAttribute ;
6675 } ;
6776 export type AsParagraph = {
77+ as ?: "p" ;
6878 linkProps ?: never ;
6979 onClick ?: never ;
7080 dismissible ?: never ;
7181 pressed ?: never ;
7282 nativeButtonProps ?: never ;
73- /** @deprecated Tag is now <p> by default. Use `nativeParagraphProps` instead. */
83+ /** @deprecated Tag is now ` <p>` by default. Use `nativeParagraphProps` instead. */
7484 nativeSpanProps ?: ComponentProps < "span" > & DataAttribute ;
7585 nativeParagraphProps ?: ComponentProps < "p" > & DataAttribute ;
7686 } ;
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+ } ;
8097}
8198
8299/** @see <https://components.react-dsfr.codegouv.studio/?path=/docs/components-tag> */
83100export const Tag = memo (
84- forwardRef < HTMLButtonElement | HTMLAnchorElement | HTMLParagraphElement , TagProps > (
101+ forwardRef < TagProps . HTMLElement , TagProps > (
102+ // -- (lint hack) to keep same indent as before
85103 ( props , ref ) => {
86104 const {
87105 id : id_props ,
@@ -98,6 +116,7 @@ export const Tag = memo(
98116 nativeSpanProps,
99117 style,
100118 onClick,
119+ as : AsTag = "p" ,
101120 ...rest
102121 } = props ;
103122
@@ -122,6 +141,7 @@ export const Tag = memo(
122141 prop_className
123142 ) ;
124143
144+ // to support old usage
125145 const nativeParagraphOrSpanProps = nativeParagraphProps ?? nativeSpanProps ;
126146
127147 return (
@@ -161,22 +181,24 @@ export const Tag = memo(
161181 { children }
162182 </ button >
163183 ) }
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+ ) }
180202 </ >
181203 ) ;
182204 }
@@ -189,6 +211,7 @@ export const Tag = memo(
189211 | ( TagProps . AsAnchor & RefAttributes < HTMLAnchorElement > )
190212 | ( TagProps . AsButton & RefAttributes < HTMLButtonElement > )
191213 | ( TagProps . AsParagraph & RefAttributes < HTMLParagraphElement > )
214+ | ( TagProps . AsSpan & RefAttributes < HTMLSpanElement > )
192215 )
193216 >
194217> ;
0 commit comments