From 556afbda728ef34a278f786f11cce6c459817178 Mon Sep 17 00:00:00 2001 From: Dustin Savery <2447456+dusave@users.noreply.github.com> Date: Tue, 19 Nov 2024 09:49:44 -0800 Subject: [PATCH 1/7] Fix HMR errors (#5209) * adding optional chaining checks to aid with hot-module reloading * Add changeset --------- Co-authored-by: Cameron Dutro --- .changeset/tidy-turtles-protect.md | 5 ++++ packages/react/src/ActionMenu/ActionMenu.tsx | 4 ++- .../react/src/hooks/useMenuInitialFocus.ts | 10 +++---- .../src/hooks/useMenuKeyboardNavigation.ts | 26 +++++++++---------- 4 files changed, 26 insertions(+), 19 deletions(-) create mode 100644 .changeset/tidy-turtles-protect.md diff --git a/.changeset/tidy-turtles-protect.md b/.changeset/tidy-turtles-protect.md new file mode 100644 index 00000000000..6d378fe75da --- /dev/null +++ b/.changeset/tidy-turtles-protect.md @@ -0,0 +1,5 @@ +--- +'@primer/react': patch +--- + +Check certain refs for nullishness to address HMR issues in dotcom diff --git a/packages/react/src/ActionMenu/ActionMenu.tsx b/packages/react/src/ActionMenu/ActionMenu.tsx index 376dce0ac1a..b2dd4b81a9b 100644 --- a/packages/react/src/ActionMenu/ActionMenu.tsx +++ b/packages/react/src/ActionMenu/ActionMenu.tsx @@ -260,7 +260,9 @@ const Overlay: React.FC> = ({ // If the menu anchor is an icon button, we need to label the menu by tooltip that also labelled the anchor. const [anchorAriaLabelledby, setAnchorAriaLabelledby] = useState(null) useEffect(() => { - if (anchorRef.current) { + // Necessary for HMR reloads + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + if (anchorRef?.current) { const ariaLabelledby = anchorRef.current.getAttribute('aria-labelledby') if (ariaLabelledby) { setAnchorAriaLabelledby(ariaLabelledby) diff --git a/packages/react/src/hooks/useMenuInitialFocus.ts b/packages/react/src/hooks/useMenuInitialFocus.ts index 103dccb89c0..3897796d8a0 100644 --- a/packages/react/src/hooks/useMenuInitialFocus.ts +++ b/packages/react/src/hooks/useMenuInitialFocus.ts @@ -3,8 +3,8 @@ import {iterateFocusableElements} from '@primer/behaviors/utils' export const useMenuInitialFocus = ( open: boolean, - containerRef: React.RefObject, - anchorRef: React.RefObject, + containerRef?: React.RefObject, + anchorRef?: React.RefObject, ) => { /** * We need to pick the first element to focus based on how the menu was opened, @@ -15,7 +15,7 @@ export const useMenuInitialFocus = ( React.useEffect( function inferOpeningKey() { - const anchorElement = anchorRef.current + const anchorElement = anchorRef?.current const clickHandler = (event: MouseEvent) => { // event.detail === 0 means onClick was fired by Enter/Space key @@ -46,12 +46,12 @@ export const useMenuInitialFocus = ( */ React.useEffect( function moveFocusOnOpen() { - if (!open || !containerRef.current) return // wait till the menu is open + if (!open || !containerRef?.current) return // wait till the menu is open const iterable = iterateFocusableElements(containerRef.current) if (openingGesture === 'mouse-click') { - if (anchorRef.current) anchorRef.current.focus() + if (anchorRef?.current) anchorRef.current.focus() else throw new Error('For focus management, please attach anchorRef') } else if (openingGesture && ['ArrowDown', 'Space', 'Enter'].includes(openingGesture)) { const firstElement = iterable.next().value diff --git a/packages/react/src/hooks/useMenuKeyboardNavigation.ts b/packages/react/src/hooks/useMenuKeyboardNavigation.ts index 4000fd578fe..96150189354 100644 --- a/packages/react/src/hooks/useMenuKeyboardNavigation.ts +++ b/packages/react/src/hooks/useMenuKeyboardNavigation.ts @@ -14,9 +14,9 @@ import type {MenuCloseHandler} from '../ActionMenu' export const useMenuKeyboardNavigation = ( open: boolean, onClose: MenuCloseHandler | undefined, - containerRef: React.RefObject, - anchorRef: React.RefObject, - isSubmenu: boolean, + containerRef?: React.RefObject, + anchorRef?: React.RefObject, + isSubmenu: boolean = false, ) => { useMenuInitialFocus(open, containerRef, anchorRef) useMnemonics(open, containerRef) @@ -32,12 +32,12 @@ export const useMenuKeyboardNavigation = ( const useCloseMenuOnTab = ( open: boolean, onClose: MenuCloseHandler | undefined, - containerRef: React.RefObject, - anchorRef: React.RefObject, + containerRef?: React.RefObject, + anchorRef?: React.RefObject, ) => { React.useEffect(() => { - const container = containerRef.current - const anchor = anchorRef.current + const container = containerRef?.current + const anchor = anchorRef?.current const handler = (event: KeyboardEvent) => { if (open && event.key === 'Tab') onClose?.('tab') @@ -59,10 +59,10 @@ const useCloseSubmenuOnArrow = ( open: boolean, isSubmenu: boolean, onClose: MenuCloseHandler | undefined, - containerRef: React.RefObject, + containerRef?: React.RefObject, ) => { React.useEffect(() => { - const container = containerRef.current + const container = containerRef?.current const handler = (event: KeyboardEvent) => { if (open && isSubmenu && event.key === 'ArrowLeft') onClose?.('arrow-left') @@ -81,12 +81,12 @@ const useCloseSubmenuOnArrow = ( */ const useMoveFocusToMenuItem = ( open: boolean, - containerRef: React.RefObject, - anchorRef: React.RefObject, + containerRef?: React.RefObject, + anchorRef?: React.RefObject, ) => { React.useEffect(() => { - const container = containerRef.current - const anchor = anchorRef.current + const container = containerRef?.current + const anchor = anchorRef?.current const handler = (event: KeyboardEvent) => { if (!open || !container) return From 1d4116d9dccda2789e8f0d53bc129ebedeed82a0 Mon Sep 17 00:00:00 2001 From: Jon Rohan Date: Tue, 19 Nov 2024 11:41:47 -0800 Subject: [PATCH 2/7] AvatarStack: Created DEV stories and update snapshots for CSS modules (#5313) * Create SxProp dev stories * Refactor the e2e test * test(vrt): update snapshots --------- Co-authored-by: jonrohan --- ...tarStack-SX-Prop-dark-colorblind-linux.png | Bin 0 -> 6265 bytes .../AvatarStack-SX-Prop-dark-dimmed-linux.png | Bin 0 -> 6300 bytes ...Stack-SX-Prop-dark-high-contrast-linux.png | Bin 0 -> 6215 bytes .../AvatarStack-SX-Prop-dark-linux.png | Bin 0 -> 6265 bytes ...tarStack-SX-Prop-dark-tritanopia-linux.png | Bin 0 -> 6265 bytes ...arStack-SX-Prop-light-colorblind-linux.png | Bin 0 -> 6144 bytes ...tack-SX-Prop-light-high-contrast-linux.png | Bin 0 -> 6144 bytes .../AvatarStack-SX-Prop-light-linux.png | Bin 0 -> 6144 bytes ...arStack-SX-Prop-light-tritanopia-linux.png | Bin 0 -> 6144 bytes e2e/components/AvatarStack.test.ts | 366 ++++-------------- .../AvatarStack/AvatarStack.dev.stories.tsx | 23 ++ 11 files changed, 92 insertions(+), 297 deletions(-) create mode 100644 .playwright/snapshots/components/AvatarStack.test.ts-snapshots/AvatarStack-SX-Prop-dark-colorblind-linux.png create mode 100644 .playwright/snapshots/components/AvatarStack.test.ts-snapshots/AvatarStack-SX-Prop-dark-dimmed-linux.png create mode 100644 .playwright/snapshots/components/AvatarStack.test.ts-snapshots/AvatarStack-SX-Prop-dark-high-contrast-linux.png create mode 100644 .playwright/snapshots/components/AvatarStack.test.ts-snapshots/AvatarStack-SX-Prop-dark-linux.png create mode 100644 .playwright/snapshots/components/AvatarStack.test.ts-snapshots/AvatarStack-SX-Prop-dark-tritanopia-linux.png create mode 100644 .playwright/snapshots/components/AvatarStack.test.ts-snapshots/AvatarStack-SX-Prop-light-colorblind-linux.png create mode 100644 .playwright/snapshots/components/AvatarStack.test.ts-snapshots/AvatarStack-SX-Prop-light-high-contrast-linux.png create mode 100644 .playwright/snapshots/components/AvatarStack.test.ts-snapshots/AvatarStack-SX-Prop-light-linux.png create mode 100644 .playwright/snapshots/components/AvatarStack.test.ts-snapshots/AvatarStack-SX-Prop-light-tritanopia-linux.png create mode 100644 packages/react/src/AvatarStack/AvatarStack.dev.stories.tsx diff --git a/.playwright/snapshots/components/AvatarStack.test.ts-snapshots/AvatarStack-SX-Prop-dark-colorblind-linux.png b/.playwright/snapshots/components/AvatarStack.test.ts-snapshots/AvatarStack-SX-Prop-dark-colorblind-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..9c9be1bf23325a938363fbeb1091c72c9b6008d8 GIT binary patch literal 6265 zcmeHL`B&3d7LUUj=#sv9 zeeUPpcT1xp!kylBej5Y=Ih{CuBpL*=TeU6FTYs@x{(6KNVB5CjM2ClgT84KmfIvIE zPaOF&=4zc%a`t;k+hmIo|xImOE`X^O!>|3p|CLLtzlb#I9>@2iaHAa;p_Nc z?YG>GdOxh0d|d7L_xDgPWU_~3G|c0{b^CwDb)3&RzUa^W$bXN0VC&3o^`~ygAU;7o zWze7BbqMypU(`p}%!SD^1<`5%ywM0VW|&1!Jxp-~ftD9(7D}?syJh}IOItwy_~wZN z=-=lP(ZwH4 zvr)|iS8R26xv^B;zeR6JQomLiEsD0I{Syzy1 z>T8I^`*qE5;W>DMDE;K>YK2ciZ$=9vy-%il(P-C8dwf^%b!(GDzy3LKs@*tIoEkS-zfOk6i$eo)lywK*eSxzU|LXXg-`k4;czza z9%RgrbR;54uGb?9MiQ0+8HfBk+7df04Pv*fdxq9+yoi%0lMB^-dMQpt491na26kqN zd$*S-n{L(uIkGXl2^eHowq{t$p0JF6q^sl$BYV6YL4+pAtIXioh>ORkrb#}3-?P@BbzQ`;n zu=-_NN5nN>>%c~qTc+%G;9ybXK;7My~G0UOO3rtR}c2wh=M41bAN5gv7KYR@c|s( zC?~5IhKGxllJK-97(yk4nAXOv^L4Z_17jj*!-EL~`W<10H;YnFtV#9>^7nqp)GQn> zHdA|f{k~a~xjfhW%4j$2{6nUSZEUQ~?w0w{Y7?(mMrL3z_xxn0333gs(-|FY!f z*uX#uP-MQD3R|pz+!x_5SR_`HY0x4I=J>3L@(G+MIKrfxUCTu(Z?>1RFU)!Jn^hRP z?{BdCpQUlquFlSnR?i4c3b-9CR_hvoMHNKubaP{C#}Z)fgb4X{2e&glPo(Jw>+<`+ zvXGxNt3Y-j9s5&j8|Sj5pB-u>_>{#Po^ESe)UJ@}FsX52yEOL%km03B>baV?2A`|O zFQT$G@~Zn#98|UZY|3KDYYylwqV685)>Vs2n;nmZFJ^#m}5oIKcQJWHvtl ziJAfM1(1%%#?s$#xnv2Gugxx`7MEe*l;Gggcdu{<=LjV)v%5k~(_qfp>s$J%9Dx|H z=xBv=o>hoz1;T1t{bZNFdUn=?Lno>o{2uSvnZBwWRd^|Xp^Zb)6yH$nh<}-P!Ia)rzXb&PLlx|S|<()E_B~~D` zDT`Um!RKbFD5@SEOiY|)X8^Z94wvdW0k+j*?8+3ayebCk^!m{C`35-kD}+|zjW+zN zx$DCwKLx1^p1|zE^va~M4LW-8$hZA+C=*y%;06>`*!Z>$kWc1E#gr zg^FB}LbpNBdkTP=fyv|)^^xy-XeA^EdwZK?b{d-ray9~ehz+1$GXsgITt@*){0 zjATux3RF7)^~2i>GxedtYLkhE-%-Uk@KE3kn&r zOipj(<7}@joLYT;tEp))jNUW0Bh#0MUEkwUX0d2%PB-;GWvJnIQ}Cwb7X=pK>l%=UE< z2pLYw)z0~cJ~Y7A(6)fBt?|u-1BPhhG)`X5iCHI^&akZ$FTA?9I-vf1m+~i@oXz7K z%=tt8;U;vO(EWjL#U^bwX|qY2&BFI*MiZMFvZ*1P8nUS&n;Np&y8qs>_Wwieu-e_B XKvRP~AGz8F?4T1zBaXC$o%{NKMhO(| literal 0 HcmV?d00001 diff --git a/.playwright/snapshots/components/AvatarStack.test.ts-snapshots/AvatarStack-SX-Prop-dark-dimmed-linux.png b/.playwright/snapshots/components/AvatarStack.test.ts-snapshots/AvatarStack-SX-Prop-dark-dimmed-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..d04ec76d0a50cb18326b62374c6fdea7f9c95b28 GIT binary patch literal 6300 zcmeI0YfzI{8pq!*3v}wRc9z*KoTG!@5Y_|uwUDL*e`rIb7s!W zGv}P=`9Ht;pHuSb8HC$go^JsF;CAxFF(d#utvLqp<{um@&d2(WIHorUNW>=qOSDG= z0J~yO9{c;*FBsKNIq$v``;!#s_tx#vYk#(~+Opmon2Zm} zK+*zA@h2v$(qqPh%br$`PR{Hr3+d80m%99jb`E&YLzt9k<~>Nl=3&(l5Y)ii_2Z{Z z6Mu3Sb&LGN$-V0Ek)RPF{!A00g?m|uat46)X^C+{?l{&f>QSi^@bQ~hb^^d(AHx9P zpKn_L;O$R--Qu^RX0rq5ixf`4m%CO`rl@EI8`htS%Fn+1g<|xVqE$&@R^Hs$0@g*CNGQzH z4z0DdX)=1f^-D<;vcBLW2gM2nJm*PK(`s6g{|ra_1LL_zR3UgFV`OEBw-pqYU4O{P zyN(dV58p5a%;caFti~7K03dpb6B}PCM{^Jho2w%bIW@hFojFX`8K!&jX?b}m^BXY1 znQEkG*>NhBiXNdPJS}?u!d1dX;1kX%mwNO-o!{;FR>` zBGveL+_PE|0Hn`q%AeL07meuk`NO-jxuhNrKKZidE)k@vr|Gp5q-NQbrRTM$0{U}x zlgz$6{gJ$-srM@i7Y3WDTXh(l-d(a~w9V|dw}$Z9hVRf4x%iy52m`0Cf_M!WSj_5*C99or=Uv==%@20banp^) zAjC+Qwx++-Di+E&v>LSKPE!V$I`62$Odtj|OWMTCyDnK50>Wj}+!xx@%n(WiEEkuy z@=du&)MwykIyR_8cu)6a%_b-|CvVMFM%y0bEd;c|aU7fZPGIqdLk!ThMrtoBGd1&ymfN`^6&=$A!-3I0=~N4HppF-DU< zfkR43F`ZB>om)0<2}nm0iYpqX?&q&EIr8|({8t06@RiC6Y3{`7P@YEReo>if$rVtQ4p z1l`NU$F%8uQV`IS>#v3KXpUtt!C)~l!&e)HS7{U?Z6;rNjFz@5T1W`EG%3`kPkj4Ao}*U)KJwX+R=Wm3ZI*^)Y}_!J|)HUvD%B@qgqz1G8VaZ zb!&?+HevU1Ow^kFs~y6Jb3Nw0hBttJxwU#W*0AD<7t$`>rX_VVIHW9StfY2wXlZI{ z>HtTIjJ(txZ;^qDL1mMiSAweH2U~c)BHNRm7+vx1c2`dcMhf}ziDzj0p!FBE<>fik zMNJl};g^6c4OQ<<*?$#V6dLCa$tMT)yoO5FxjPIwD)XJ_P>&-zm6rEalW5}`)njAH zX^%1x1Z$AxK5!nzYQ8bx>k3N=8Ryz5d%m1Dq2$zI(FMj}yK9?Va|2KSh-8FYM`{<)G z({RS6>`wp1hJhx=SO^>r87ru^HO&Mly&}ls$jqZhccO`6)DFS~I>kmC5)^6<- z6DbR2_=Yx@io`33^WD9D>_kG6!mZwVkfluwoyyN;Oizf%W>Keyx(SjUgC#H0<%>P5ugg*1W8M3?SdCs>gf#_$VAmdR(&b zsGpu8I>4gn2iLg%*O(uDI8iXKe3-pRSM!uyIjt=YV0w~e8(X)2X(#S)yHo1UItP*AW~OQx|iAGH|ia#N58pOCi|0>3=aUJ)Um zp;%^mQ=22Yz@vn=s+`a2nf?x`D?d0;tqtp^^c7fLv^f{j(;?-kmPm^}SmV=pQ`27U zIovzl)^@$MB{DPrP9Jy&OfJYZC4$k>mYLHO5C1aUG+Xr@_w0gilOe1>HK$-?Z1Nc= zdJm*5@hGasgi|2*3I`OG{5Bo;tim!k_&*+Ezf)YHAJGqmu0bYoUyU=_s?5U<^RiIT zImm|(x7Tdl$0;o=yD|YgyrcWq`fxNrB- zb{}o`(RLsGp3lE+hHNurn<4*qhI|YC@#bH#?eVs&rH+4n;N(Bf9AkZw{Pn*9oL;Tb literal 0 HcmV?d00001 diff --git a/.playwright/snapshots/components/AvatarStack.test.ts-snapshots/AvatarStack-SX-Prop-dark-high-contrast-linux.png b/.playwright/snapshots/components/AvatarStack.test.ts-snapshots/AvatarStack-SX-Prop-dark-high-contrast-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..b81ee92059bbeaf8308d612dcd1cc977b6c23935 GIT binary patch literal 6215 zcmeI0=~L6!8pnT@K|8f-XY7;;NN($`-d;i4Yb7i~T&Pq~(gp)nNDwH53M3K;TNa9K zp_B%0Wl04AkpY@S5(#S-5-kN(NFs(LEGAL52!Vtx3yDc?=znnEcJkuPnR#A4=lh)R z_jBfyei<3I=PmcQ007u?{)H@^JzV^iI zCl7sw#7O4cKaC;c4Wh^>Hs-He8=~OBR#yNpN#&+wsG~WP>I3Z#;2%Hq?E=1gXT}Qv z&isT2fH(ioVyM^`?>O-)y`7=yEEEc8FrhtO2nwXr!VxsuI1WLBNl}r}E#oMtHIY+p z5k24ZHPryXe-m1(Fx5j0+7)T~vd7n5T+BoBMYSq_^Up$UKwrw`!cJNnDrLAWg&v8z zA5~L@6m&l@ufww8jAcXqlErAvk#3EtIsg_pM`Ymdcn7F&}?YN}z8jUhxKoskwt80fF3H_Th(Gj*1cq+Z1& z+UFHZn(@0U@ST>xy(A$o49a=t8fJ)J&;<8IvZe=OQjB$!QmLgMMbw;Jeca8^@%yj?27q75GEH*QnS7{7QPx+qK_;* z4hDd1$84c+p&Wr-G={kmm*<)&e8Wdsbv3p@m2G;xNx45M3bgeoOlcYdD|1!Epq%AA zVH)zdzrX2^qdoWV8wN%5ZhT#`WXYAnjP1i_Zg3*r%ZQU27cu2TO05CcNnGe&2SKsj*u~8+>|juSV&3A5 zrb9>k(9iQ`$>16o|Mk4DKpm`Oo0sU!yvGZ-9_qPaZZ$CU6l*TtX1eXt+y>bqcl0W; zrX=Gp$o!WNxXjqKXKFoUb8h*d%FF(6OcsWTv-Z#_6qwg#>rD3{%E^sPTW7-Mz1vb? zs4{PNPmemwX;ezyd_KI>EMxSS?JV#h5A|eBn=KZ#e3Aky2SJcA{nFYpHR$(7ZkO@T zP;~{8pPia8`;aKXR|xy{`=LIdW%gG0(U6U{v_PD7tK`VJwkfrDaOJCkLzJ3Bs>N&Q zZ5MN{^JvJv#Q9$zOTq%%H=^J6@jNhLA1{@T>?|%RVG3+!SU6X~w;HC!aflPNEQaaj z#B^@CeWSdR{vMdJ&o4gn;RBV`wv+-7u{_Od{;Hu+bfZ^=HBDV~i8-koWo@y4b*sXr z#boU_0>INBCt*8_!>(8sQkEi7-`vkVEgs)o?hq~FJdVB6XpXjc1{Y+@83>5`C+mNp z_F}pUM4PwVS8Xms^?q~@E`J$QHFRJ_#RV%3vro5tvoogRgK$!lC@d?uC^ zT*#AJ+undAI>H>0TD`tV+p41=&8w3BMrs(7Bsl@SU2A$EKXJ%geDcN`<8YSx zAiHK-74&JK*(|p!+k2IqjOm^rZC}#$>#H`4t}&x~WVLlcM__$cpe_M>v?yqSq6>rO=Lp~lLo3dy=qD0HqdEkv&;z+C#D?A}jpSYheTz;^!ayHrU4OBrB zEB*uFF(T-Q$O}EW+D774)o4d)4jlp67*35R*-LgARo04nwlQ~dNwz)LT=y0pO-sO} zr_Yp@C=D~@eG1FOnD0rfq+5`)JU8yDZnRKiA^8J)z$a~{**Y*ryRzcba;aXjq9e?> z&gOcj_7ocG-NfY?Y)e1htAE~*L+3Jl2U(r~kXL>?JpU&VY49>j{^E#2v{1+T&i`o}mBGAuCf{f)W_6^ZHKJ z=ghXKZ)WZTfDg9q?kqY5ab5< Y`M=%sq0Qa#`3{`_JTjDV=IV|A0Ze_0C;$Ke literal 0 HcmV?d00001 diff --git a/.playwright/snapshots/components/AvatarStack.test.ts-snapshots/AvatarStack-SX-Prop-dark-linux.png b/.playwright/snapshots/components/AvatarStack.test.ts-snapshots/AvatarStack-SX-Prop-dark-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..9c9be1bf23325a938363fbeb1091c72c9b6008d8 GIT binary patch literal 6265 zcmeHL`B&3d7LUUj=#sv9 zeeUPpcT1xp!kylBej5Y=Ih{CuBpL*=TeU6FTYs@x{(6KNVB5CjM2ClgT84KmfIvIE zPaOF&=4zc%a`t;k+hmIo|xImOE`X^O!>|3p|CLLtzlb#I9>@2iaHAa;p_Nc z?YG>GdOxh0d|d7L_xDgPWU_~3G|c0{b^CwDb)3&RzUa^W$bXN0VC&3o^`~ygAU;7o zWze7BbqMypU(`p}%!SD^1<`5%ywM0VW|&1!Jxp-~ftD9(7D}?syJh}IOItwy_~wZN z=-=lP(ZwH4 zvr)|iS8R26xv^B;zeR6JQomLiEsD0I{Syzy1 z>T8I^`*qE5;W>DMDE;K>YK2ciZ$=9vy-%il(P-C8dwf^%b!(GDzy3LKs@*tIoEkS-zfOk6i$eo)lywK*eSxzU|LXXg-`k4;czza z9%RgrbR;54uGb?9MiQ0+8HfBk+7df04Pv*fdxq9+yoi%0lMB^-dMQpt491na26kqN zd$*S-n{L(uIkGXl2^eHowq{t$p0JF6q^sl$BYV6YL4+pAtIXioh>ORkrb#}3-?P@BbzQ`;n zu=-_NN5nN>>%c~qTc+%G;9ybXK;7My~G0UOO3rtR}c2wh=M41bAN5gv7KYR@c|s( zC?~5IhKGxllJK-97(yk4nAXOv^L4Z_17jj*!-EL~`W<10H;YnFtV#9>^7nqp)GQn> zHdA|f{k~a~xjfhW%4j$2{6nUSZEUQ~?w0w{Y7?(mMrL3z_xxn0333gs(-|FY!f z*uX#uP-MQD3R|pz+!x_5SR_`HY0x4I=J>3L@(G+MIKrfxUCTu(Z?>1RFU)!Jn^hRP z?{BdCpQUlquFlSnR?i4c3b-9CR_hvoMHNKubaP{C#}Z)fgb4X{2e&glPo(Jw>+<`+ zvXGxNt3Y-j9s5&j8|Sj5pB-u>_>{#Po^ESe)UJ@}FsX52yEOL%km03B>baV?2A`|O zFQT$G@~Zn#98|UZY|3KDYYylwqV685)>Vs2n;nmZFJ^#m}5oIKcQJWHvtl ziJAfM1(1%%#?s$#xnv2Gugxx`7MEe*l;Gggcdu{<=LjV)v%5k~(_qfp>s$J%9Dx|H z=xBv=o>hoz1;T1t{bZNFdUn=?Lno>o{2uSvnZBwWRd^|Xp^Zb)6yH$nh<}-P!Ia)rzXb&PLlx|S|<()E_B~~D` zDT`Um!RKbFD5@SEOiY|)X8^Z94wvdW0k+j*?8+3ayebCk^!m{C`35-kD}+|zjW+zN zx$DCwKLx1^p1|zE^va~M4LW-8$hZA+C=*y%;06>`*!Z>$kWc1E#gr zg^FB}LbpNBdkTP=fyv|)^^xy-XeA^EdwZK?b{d-ray9~ehz+1$GXsgITt@*){0 zjATux3RF7)^~2i>GxedtYLkhE-%-Uk@KE3kn&r zOipj(<7}@joLYT;tEp))jNUW0Bh#0MUEkwUX0d2%PB-;GWvJnIQ}Cwb7X=pK>l%=UE< z2pLYw)z0~cJ~Y7A(6)fBt?|u-1BPhhG)`X5iCHI^&akZ$FTA?9I-vf1m+~i@oXz7K z%=tt8;U;vO(EWjL#U^bwX|qY2&BFI*MiZMFvZ*1P8nUS&n;Np&y8qs>_Wwieu-e_B XKvRP~AGz8F?4T1zBaXC$o%{NKMhO(| literal 0 HcmV?d00001 diff --git a/.playwright/snapshots/components/AvatarStack.test.ts-snapshots/AvatarStack-SX-Prop-dark-tritanopia-linux.png b/.playwright/snapshots/components/AvatarStack.test.ts-snapshots/AvatarStack-SX-Prop-dark-tritanopia-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..9c9be1bf23325a938363fbeb1091c72c9b6008d8 GIT binary patch literal 6265 zcmeHL`B&3d7LUUj=#sv9 zeeUPpcT1xp!kylBej5Y=Ih{CuBpL*=TeU6FTYs@x{(6KNVB5CjM2ClgT84KmfIvIE zPaOF&=4zc%a`t;k+hmIo|xImOE`X^O!>|3p|CLLtzlb#I9>@2iaHAa;p_Nc z?YG>GdOxh0d|d7L_xDgPWU_~3G|c0{b^CwDb)3&RzUa^W$bXN0VC&3o^`~ygAU;7o zWze7BbqMypU(`p}%!SD^1<`5%ywM0VW|&1!Jxp-~ftD9(7D}?syJh}IOItwy_~wZN z=-=lP(ZwH4 zvr)|iS8R26xv^B;zeR6JQomLiEsD0I{Syzy1 z>T8I^`*qE5;W>DMDE;K>YK2ciZ$=9vy-%il(P-C8dwf^%b!(GDzy3LKs@*tIoEkS-zfOk6i$eo)lywK*eSxzU|LXXg-`k4;czza z9%RgrbR;54uGb?9MiQ0+8HfBk+7df04Pv*fdxq9+yoi%0lMB^-dMQpt491na26kqN zd$*S-n{L(uIkGXl2^eHowq{t$p0JF6q^sl$BYV6YL4+pAtIXioh>ORkrb#}3-?P@BbzQ`;n zu=-_NN5nN>>%c~qTc+%G;9ybXK;7My~G0UOO3rtR}c2wh=M41bAN5gv7KYR@c|s( zC?~5IhKGxllJK-97(yk4nAXOv^L4Z_17jj*!-EL~`W<10H;YnFtV#9>^7nqp)GQn> zHdA|f{k~a~xjfhW%4j$2{6nUSZEUQ~?w0w{Y7?(mMrL3z_xxn0333gs(-|FY!f z*uX#uP-MQD3R|pz+!x_5SR_`HY0x4I=J>3L@(G+MIKrfxUCTu(Z?>1RFU)!Jn^hRP z?{BdCpQUlquFlSnR?i4c3b-9CR_hvoMHNKubaP{C#}Z)fgb4X{2e&glPo(Jw>+<`+ zvXGxNt3Y-j9s5&j8|Sj5pB-u>_>{#Po^ESe)UJ@}FsX52yEOL%km03B>baV?2A`|O zFQT$G@~Zn#98|UZY|3KDYYylwqV685)>Vs2n;nmZFJ^#m}5oIKcQJWHvtl ziJAfM1(1%%#?s$#xnv2Gugxx`7MEe*l;Gggcdu{<=LjV)v%5k~(_qfp>s$J%9Dx|H z=xBv=o>hoz1;T1t{bZNFdUn=?Lno>o{2uSvnZBwWRd^|Xp^Zb)6yH$nh<}-P!Ia)rzXb&PLlx|S|<()E_B~~D` zDT`Um!RKbFD5@SEOiY|)X8^Z94wvdW0k+j*?8+3ayebCk^!m{C`35-kD}+|zjW+zN zx$DCwKLx1^p1|zE^va~M4LW-8$hZA+C=*y%;06>`*!Z>$kWc1E#gr zg^FB}LbpNBdkTP=fyv|)^^xy-XeA^EdwZK?b{d-ray9~ehz+1$GXsgITt@*){0 zjATux3RF7)^~2i>GxedtYLkhE-%-Uk@KE3kn&r zOipj(<7}@joLYT;tEp))jNUW0Bh#0MUEkwUX0d2%PB-;GWvJnIQ}Cwb7X=pK>l%=UE< z2pLYw)z0~cJ~Y7A(6)fBt?|u-1BPhhG)`X5iCHI^&akZ$FTA?9I-vf1m+~i@oXz7K z%=tt8;U;vO(EWjL#U^bwX|qY2&BFI*MiZMFvZ*1P8nUS&n;Np&y8qs>_Wwieu-e_B XKvRP~AGz8F?4T1zBaXC$o%{NKMhO(| literal 0 HcmV?d00001 diff --git a/.playwright/snapshots/components/AvatarStack.test.ts-snapshots/AvatarStack-SX-Prop-light-colorblind-linux.png b/.playwright/snapshots/components/AvatarStack.test.ts-snapshots/AvatarStack-SX-Prop-light-colorblind-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..187994fbcc58a0c02fa6bee8e5c46a78f0ac12b0 GIT binary patch literal 6144 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 z { - test.describe('Default', () => { - for (const theme of themes) { - test.describe(theme, () => { - test('default @vrt', async ({page}) => { - await visit(page, { - id: 'components-avatarstack--default', - globals: { - colorScheme: theme, - }, - }) - - // Default state - expect(await page.screenshot()).toMatchSnapshot(`AvatarStack.Default.${theme}.png`) - }) - - test('axe @aat', async ({page}) => { - await visit(page, { - id: 'components-avatarstack--default', - globals: { - colorScheme: theme, - }, - }) - await expect(page).toHaveNoViolations({ - rules: { - 'color-contrast': { - enabled: theme !== 'dark_dimmed', - }, - }, - }) - }) - }) - } - }) +const stories: Array<{title: string; id: string}> = [ + { + title: 'Default', + id: 'components-avatarstack--default', + }, + { + title: 'Playground', + id: 'components-avatarstack--playground', + }, + { + title: 'Align Left', + id: 'components-avatarstack-features--align-left', + }, + { + title: 'Align Right', + id: 'components-avatarstack-features--align-right', + }, + { + title: 'Disable Expand On Hover', + id: 'components-avatarstack-features--disable-expand-on-hover', + }, + { + title: 'Custom Size On Parent', + id: 'components-avatarstack-features--custom-size-on-parent', + }, + { + title: 'Custom Size On Parent Responsive', + id: 'components-avatarstack-features--custom-size-on-parent-responsive', + }, + { + title: 'Custom Size On Children', + id: 'components-avatarstack-features--custom-size-on-children', + }, + { + title: 'Custom Size On Children Responsive', + id: 'components-avatarstack-features--custom-size-on-children-responsive', + }, + { + title: 'SX Prop', + id: 'components-avatarstack-dev--sx-prop', + }, +] - test.describe('Playground', () => { - for (const theme of themes) { - test.describe(theme, () => { - test('default @vrt', async ({page}) => { - await visit(page, { - id: 'components-avatarstack--playground', - globals: { - colorScheme: theme, - }, - }) - - // Default state - expect(await page.screenshot()).toMatchSnapshot(`AvatarStack.Playground.${theme}.png`) - }) - - test('axe @aat', async ({page}) => { - await visit(page, { - id: 'components-avatarstack--playground', - globals: { - colorScheme: theme, - }, - }) - await expect(page).toHaveNoViolations({ - rules: { - 'color-contrast': { - enabled: theme !== 'dark_dimmed', - }, - }, - }) - }) - }) - } - }) - - test.describe('Align Left', () => { - for (const theme of themes) { - test.describe(theme, () => { - test('default @vrt', async ({page}) => { - await visit(page, { - id: 'components-avatarstack-features--align-left', - globals: { - colorScheme: theme, - }, - }) - - // Default state - expect(await page.screenshot()).toMatchSnapshot(`AvatarStack.Align Left.${theme}.png`) - }) - - test('axe @aat', async ({page}) => { - await visit(page, { - id: 'components-avatarstack-features--align-left', - globals: { - colorScheme: theme, - }, - }) - await expect(page).toHaveNoViolations({ - rules: { - 'color-contrast': { - enabled: theme !== 'dark_dimmed', - }, - }, - }) - }) - }) - } - }) - - test.describe('Align Right', () => { - for (const theme of themes) { - test.describe(theme, () => { - test('default @vrt', async ({page}) => { - await visit(page, { - id: 'components-avatarstack-features--align-right', - globals: { - colorScheme: theme, - }, - }) - - // Default state - expect(await page.screenshot()).toMatchSnapshot(`AvatarStack.Align Right.${theme}.png`) - }) - - test('axe @aat', async ({page}) => { - await visit(page, { - id: 'components-avatarstack-features--align-right', - globals: { - colorScheme: theme, - }, - }) - await expect(page).toHaveNoViolations({ - rules: { - 'color-contrast': { - enabled: theme !== 'dark_dimmed', - }, - }, - }) - }) - }) - } - }) - - test.describe('Disable Expand On Hover', () => { - for (const theme of themes) { - test.describe(theme, () => { - test('default @vrt', async ({page}) => { - await visit(page, { - id: 'components-avatarstack-features--disable-expand-on-hover', - globals: { - colorScheme: theme, - }, - }) - - // Default state - expect(await page.screenshot()).toMatchSnapshot(`AvatarStack.Disable Expand On Hover.${theme}.png`) - }) - - test('axe @aat', async ({page}) => { - await visit(page, { - id: 'components-avatarstack-features--disable-expand-on-hover', - globals: { - colorScheme: theme, - }, - }) - await expect(page).toHaveNoViolations({ - rules: { - 'color-contrast': { - enabled: theme !== 'dark_dimmed', - }, - }, - }) - }) - }) - } - }) - - test.describe('Custom Size On Parent', () => { - for (const theme of themes) { - test.describe(theme, () => { - test('default @vrt', async ({page}) => { - await visit(page, { - id: 'components-avatarstack-features--custom-size-on-parent', - globals: { - colorScheme: theme, - }, - }) - - // Default state - expect(await page.screenshot()).toMatchSnapshot(`AvatarStack.Custom Size On Parent.${theme}.png`) - }) - - test('axe @aat', async ({page}) => { - await visit(page, { - id: 'components-avatarstack-features--custom-size-on-parent', - globals: { - colorScheme: theme, - }, - }) - await expect(page).toHaveNoViolations({ - rules: { - 'color-contrast': { - enabled: theme !== 'dark_dimmed', - }, - }, - }) - }) - }) - } - }) - - test.describe('Custom Size On Parent Responsive', () => { - for (const theme of themes) { - test.describe(theme, () => { - test('default @vrt', async ({page}) => { - await visit(page, { - id: 'components-avatarstack-features--custom-size-on-parent-responsive', - globals: { - colorScheme: theme, - }, - }) - - // Default state - expect(await page.screenshot()).toMatchSnapshot(`AvatarStack.Custom Size On Parent Responsive.${theme}.png`) - }) - - test('axe @aat', async ({page}) => { - await visit(page, { - id: 'components-avatarstack-features--custom-size-on-parent-responsive', - globals: { - colorScheme: theme, - }, - }) - await expect(page).toHaveNoViolations({ - rules: { - 'color-contrast': { - enabled: theme !== 'dark_dimmed', +test.describe('AvatarStack', () => { + for (const story of stories) { + test.describe(story.title, () => { + for (const theme of themes) { + test.describe(theme, () => { + test('@vrt', async ({page}) => { + await visit(page, { + id: story.id, + globals: { + colorScheme: theme, }, - }, - }) - }) - }) - } - }) + }) - test.describe('Custom Size On Children', () => { - for (const theme of themes) { - test.describe(theme, () => { - test('default @vrt', async ({page}) => { - await visit(page, { - id: 'components-avatarstack-features--custom-size-on-children', - globals: { - colorScheme: theme, - }, + expect(await page.screenshot()).toMatchSnapshot(`AvatarStack.${story.title}.${theme}.png`) }) - // Default state - expect(await page.screenshot()).toMatchSnapshot(`AvatarStack.Custom Size On Children.${theme}.png`) - }) - - test('axe @aat', async ({page}) => { - await visit(page, { - id: 'components-avatarstack-features--custom-size-on-children', - globals: { - colorScheme: theme, - }, - }) - await expect(page).toHaveNoViolations({ - rules: { - 'color-contrast': { - enabled: theme !== 'dark_dimmed', + test('@aat', async ({page}) => { + await visit(page, { + id: story.id, + globals: { + colorScheme: theme, }, - }, - }) - }) - }) - } - }) - - test.describe('Custom Size On Children Responsive', () => { - for (const theme of themes) { - test.describe(theme, () => { - test('default @vrt', async ({page}) => { - await visit(page, { - id: 'components-avatarstack-features--custom-size-on-children-responsive', - globals: { - colorScheme: theme, - }, - }) - - // Default state - expect(await page.screenshot()).toMatchSnapshot(`AvatarStack.Custom Size On Children Responsive.${theme}.png`) - }) - - test('axe @aat', async ({page}) => { - await visit(page, { - id: 'components-avatarstack-features--custom-size-on-children-responsive', - globals: { - colorScheme: theme, - }, - }) - await expect(page).toHaveNoViolations({ - rules: { - 'color-contrast': { - enabled: theme !== 'dark_dimmed', + }) + await expect(page).toHaveNoViolations({ + rules: { + 'color-contrast': { + enabled: theme !== 'dark_dimmed', + }, }, - }, + }) }) }) - }) - } - }) + } + }) + } }) diff --git a/packages/react/src/AvatarStack/AvatarStack.dev.stories.tsx b/packages/react/src/AvatarStack/AvatarStack.dev.stories.tsx new file mode 100644 index 00000000000..e1da2e33122 --- /dev/null +++ b/packages/react/src/AvatarStack/AvatarStack.dev.stories.tsx @@ -0,0 +1,23 @@ +import React from 'react' +import type {Meta} from '@storybook/react' +import AvatarStack from './AvatarStack' +import Avatar from '../Avatar' + +export default { + title: 'Components/AvatarStack/Dev', + component: AvatarStack, +} as Meta + +export const SxProp = () => ( + + + + + + +) From 56ff1c0094a0920d5d982521a0dfb8ebb94b7e86 Mon Sep 17 00:00:00 2001 From: Mike Perrotti Date: Wed, 20 Nov 2024 13:58:06 -0500 Subject: [PATCH 3/7] Manually corrects `.docs.json` files (#5316) * manually corrects prop docs * tweaks --- .../react/src/ActionBar/ActionBar.docs.json | 46 ++++-- .../react/src/ActionList/ActionList.docs.json | 55 ++++++- .../react/src/ActionMenu/ActionMenu.docs.json | 37 ++++- .../AnchoredOverlay/AnchoredOverlay.docs.json | 56 ++++++- .../src/Autocomplete/Autocomplete.docs.json | 44 ++++- packages/react/src/Avatar/Avatar.docs.json | 25 ++- .../react/src/AvatarPair/AvatarPair.docs.json | 12 +- .../src/AvatarStack/AvatarStack.docs.json | 42 ++++- packages/react/src/Banner/Banner.docs.json | 68 +++++++- .../react/src/Blankslate/Blankslate.docs.json | 38 ++++- .../react/src/BranchName/BranchName.docs.json | 14 +- .../src/Breadcrumbs/Breadcrumbs.docs.json | 24 ++- packages/react/src/Button/Button.docs.json | 96 ++++++++++- .../react/src/Button/IconButton.docs.json | 58 ++++++- packages/react/src/Button/types.ts | 2 +- .../src/ButtonGroup/ButtonGroup.docs.json | 20 ++- .../react/src/Checkbox/Checkbox.docs.json | 20 ++- .../src/CheckboxGroup/CheckboxGroup.docs.json | 23 ++- .../src/CounterLabel/CounterLabel.docs.json | 24 ++- .../react/src/DataTable/DataTable.docs.json | 150 +++++++++++++++--- packages/react/src/Details/Details.docs.json | 6 +- packages/react/src/Dialog/Dialog.docs.json | 107 +++++++++++-- packages/react/src/Dialog/Dialog.tsx | 2 +- packages/react/src/DialogV1/Dialog.docs.json | 14 +- .../src/FeatureFlags/FeatureFlags.docs.json | 17 ++ packages/react/src/Flash/Flash.docs.json | 24 ++- .../src/FormControl/FormControl.docs.json | 100 +++++++++++- packages/react/src/Hidden/Hidden.docs.json | 12 +- .../src/InlineMessage/InlineMessage.docs.json | 14 +- packages/react/src/Label/Label.docs.json | 39 ++++- .../react/src/LabelGroup/LabelGroup.docs.json | 21 ++- packages/react/src/Link/Link.docs.json | 15 +- packages/react/src/NavList/NavList.docs.json | 34 ++++ packages/react/src/Overlay/Overlay.docs.json | 21 +++ .../react/src/PageHeader/PageHeader.docs.json | 71 ++++++++- .../react/src/PageLayout/PageLayout.docs.json | 48 +++++- .../react/src/Pagination/Pagination.docs.json | 22 ++- .../react/src/PointerBox/PointerBox.docs.json | 26 ++- packages/react/src/Popover/Popover.docs.json | 8 +- packages/react/src/Portal/Portal.docs.json | 17 +- .../src/ProgressBar/ProgressBar.docs.json | 65 +++++++- packages/react/src/Radio/Radio.docs.json | 17 +- .../react/src/RadioGroup/RadioGroup.docs.json | 25 ++- .../src/RelativeTime/RelativeTime.docs.json | 39 ++++- .../SegmentedControl.docs.json | 41 ++++- packages/react/src/Select/Select.docs.json | 41 ++++- .../src/SelectPanel/SelectPanel.docs.json | 76 ++++++++- packages/react/src/Spinner/Spinner.docs.json | 21 ++- .../SplitPageLayout/SplitPageLayout.docs.json | 51 +++++- .../react/src/StateLabel/StateLabel.docs.json | 39 ++++- packages/react/src/SubNav/SubNav.docs.json | 23 ++- packages/react/src/TabNav/TabNav.docs.json | 14 +- packages/react/src/Text/Text.docs.json | 37 ++++- .../react/src/TextInput/TextInput.docs.json | 51 +++++- .../TextInputWithTokens.docs.json | 39 ++++- .../react/src/Textarea/Textarea.docs.json | 35 +++- .../react/src/Timeline/Timeline.docs.json | 18 ++- .../src/ToggleSwitch/ToggleSwitch.docs.json | 32 +++- packages/react/src/Token/Token.docs.json | 36 ++++- .../react/src/TooltipV2/Tooltip.docs.json | 30 +++- .../react/src/TreeView/TreeView.docs.json | 55 ++++++- .../react/src/Truncate/Truncate.docs.json | 15 +- .../src/UnderlineNav/UnderlineNav.docs.json | 30 +++- .../SelectPanel2/SelectPanel.docs.json | 18 +++ .../Skeleton/SkeletonAvatar.docs.json | 21 ++- .../Skeleton/SkeletonBox.docs.json | 18 ++- .../Skeleton/SkeletonText.docs.json | 36 ++++- .../UnderlinePanels/UnderlinePanels.docs.json | 2 +- 68 files changed, 2239 insertions(+), 158 deletions(-) create mode 100644 packages/react/src/FeatureFlags/FeatureFlags.docs.json diff --git a/packages/react/src/ActionBar/ActionBar.docs.json b/packages/react/src/ActionBar/ActionBar.docs.json index 7b8f2659f96..8d1ce1dba9b 100644 --- a/packages/react/src/ActionBar/ActionBar.docs.json +++ b/packages/react/src/ActionBar/ActionBar.docs.json @@ -3,29 +3,45 @@ "name": "ActionBar", "status": "alpha", "a11yReviewed": true, - "stories": [], + "stories": [ + { + "id": "components-actionbar--default" + } + ], "importPath": "@primer/react", "props": [ { - "name": "size", - "type": "'small' | 'medium' | 'large'", + "name": "aria-label", + "type": "string", "required": false, - "description": "Size of the action bar" + "description": "When provided, a label is added to the action bar", + "defaultValue": "" }, { - "name": "aria-label", + "name": "aria-labelledby", "type": "string", - "description": "When provided, a label is added to the action bar" + "required": false, + "description": "When provided, uses the element with that ID as the accessible name for the ActionBar", + "defaultValue": "" }, { "name": "children", - "type": "React.ReactElement", - "required": true + "type": "ReactNode", + "required": false, + "description": "Buttons in the action bar", + "defaultValue": "" + }, + { + "name": "size", + "type": "'small' | 'large' | 'medium'", + "required": false, + "description": "Size of the action bar", + "defaultValue": "" } ], "subcomponents": [ { - "name": "ActionBar.Icon", + "name": "ActionBar.IconButton", "props": [ { "name": "children", @@ -38,19 +54,19 @@ "name": "icon", "type": "Component", "defaultValue": "", - "description": "provide an octicon. It will be placed in the center of the button" + "description": "Provide an octicon. It will be placed in the center of the button" }, { "name": "aria-label", "type": "string", "defaultValue": "", "description": "Use an aria label to describe the functionality of the button. Please refer to [our guidance on alt text](https://primer.style/guides/accessibility/alternative-text-for-images) for tips on writing good alternative text." - }, - { - "name": "sx", - "type": "SystemStyleObject" } - ] + ], + "passthrough": { + "element": "IconButton", + "url": "/react/IconButton" + } }, { "name": "ActionBar.Divider", diff --git a/packages/react/src/ActionList/ActionList.docs.json b/packages/react/src/ActionList/ActionList.docs.json index 2d7ff88c1a9..59bbc7ae805 100644 --- a/packages/react/src/ActionList/ActionList.docs.json +++ b/packages/react/src/ActionList/ActionList.docs.json @@ -26,10 +26,10 @@ "description": "Whether multiple items or a single item can be selected." }, { - "name": "showDivider", + "name": "showDividers", "type": "boolean", - "defaultValue": "false", - "description": "Display a divider above each item in this list when it does not follow a header or divider." + "description": "Display a divider above each `Item` in this `List` when it does not follow a `Header` or `Divider`.", + "defaultValue": "" }, { "name": "role", @@ -51,7 +51,7 @@ "type": "React.ReactNode | ActionList.LeadingVisual | ActionList.Description | ActionList.TrailingVisual", "defaultValue": "", "required": true, - "description": "" + "description": "Primary content for an Item" }, { "name": "variant", @@ -100,6 +100,13 @@ "defaultValue": "", "description": "ARIA role describing the function of the item. `option` is a common value." }, + { + "name": "id", + "type": "string", + "required": false, + "description": "id to attach to the root element of the Item", + "defaultValue": "" + }, { "name": "sx", "type": "SystemStyleObject" @@ -123,6 +130,13 @@ "required": false, "description": "The level of the heading" }, + { + "name": "visuallyHidden", + "type": "boolean", + "required": false, + "description": "", + "defaultValue": "" + }, { "name": "sx", "type": "SystemStyleObject" @@ -154,6 +168,13 @@ "type": "React.ElementType", "defaultValue": "\"a\"" }, + { + "name": "inactiveText", + "type": "string", + "required": false, + "description": "Text describing why the item is inactive. This may be used when an item's usual functionality\nis unavailable due to a system error such as a database outage.", + "defaultValue": "" + }, { "name": "sx", "type": "SystemStyleObject" @@ -277,6 +298,20 @@ "defaultValue": "'subtle'", "description": "`filled` style has a background color and top and bottom borders. Subtle style has no background or borders." }, + { + "name": "auxiliaryText", + "type": "string", + "required": false, + "description": "Secondary text which provides additional information about a `Group`.", + "defaultValue": "" + }, + { + "name": "visuallyHidden", + "type": "boolean", + "required": false, + "description": "", + "defaultValue": "" + }, { "name": "as", "type": "h1 | h2 | h3 | h4 | h5 | h6", @@ -336,6 +371,16 @@ "type": "SystemStyleObject" } ] + }, + { + "filePath": "/Users/mperrotti/work-dir/react/packages/react/src/ActionList/Divider.tsx", + "name": "ActionList.Divider", + "props": [ + { + "name": "sx", + "type": "SystemStyleObject" + } + ] } ] -} \ No newline at end of file +} diff --git a/packages/react/src/ActionMenu/ActionMenu.docs.json b/packages/react/src/ActionMenu/ActionMenu.docs.json index e1b262a66b1..cdd205fd7db 100644 --- a/packages/react/src/ActionMenu/ActionMenu.docs.json +++ b/packages/react/src/ActionMenu/ActionMenu.docs.json @@ -3,7 +3,29 @@ "name": "ActionMenu", "status": "beta", "a11yReviewed": false, - "stories": [], + "stories": [ + { + "id": "components-actionmenu--default" + }, + { + "id": "components-actionmenu-features--links-and-actions" + }, + { + "id": "components-actionmenu-features--single-select" + }, + { + "id": "components-actionmenu-features--multi-select" + }, + { + "id": "components-actionmenu-features--inactive-items" + }, + { + "id": "components-actionmenu-features--loading-items" + }, + { + "id": "components-actionmenu-features--submenus" + } + ], "importPath": "@primer/react", "props": [ { @@ -58,6 +80,12 @@ "defaultValue": "", "required": true, "description": "Accepts a single child element" + }, + { + "name": "id", + "type": "string", + "description": "", + "defaultValue": "" } ] }, @@ -82,6 +110,13 @@ "type": "| 'inside-top' | 'inside-bottom' | 'inside-left' | 'inside-right' | 'inside-center' | 'outside-top' | 'outside-bottom' | 'outside-left' | 'outside-right'", "defaultValue": "'outside-bottom'", "description": "Controls which side of the anchor the menu will appear" + }, + { + "name": "data-test-id", + "type": "unknown", + "required": false, + "description": "ID to use for React testing utilities.", + "defaultValue": "" } ], "passthrough": { diff --git a/packages/react/src/AnchoredOverlay/AnchoredOverlay.docs.json b/packages/react/src/AnchoredOverlay/AnchoredOverlay.docs.json index 1cb80dfa148..699fd82c050 100644 --- a/packages/react/src/AnchoredOverlay/AnchoredOverlay.docs.json +++ b/packages/react/src/AnchoredOverlay/AnchoredOverlay.docs.json @@ -3,18 +3,56 @@ "name": "AnchoredOverlay", "status": "alpha", "a11yReviewed": false, - "stories": [], + "stories": [ + { + "id": "components-anchoredoverlay--default" + }, + { + "id": "components-anchoredoverlay-features--portal-inside-scrolling-element" + }, + { + "id": "components-anchoredoverlay-features--custom-anchor-id" + }, + { + "id": "components-anchoredoverlay-features--height" + }, + { + "id": "components-anchoredoverlay-features--width" + }, + { + "id": "components-anchoredoverlay-features--anchor-alignment" + }, + { + "id": "components-anchoredoverlay-features--anchor-side" + }, + { + "id": "components-anchoredoverlay-features--offset-position-from-anchor" + }, + { + "id": "components-anchoredoverlay-features--offset-alignment-from-anchor" + }, + { + "id": "components-anchoredoverlay-features--focus-trap-overrides" + }, + { + "id": "components-anchoredoverlay-features--focus-zone-overrides" + }, + { + "id": "components-anchoredoverlay-features--overlay-props-overrides" + } + ], "importPath": "@primer/react", "props": [ { "name": "open", "type": "boolean", + "required": true, "defaultValue": "false", "description": "Determines whether the overlay portion of the component should be shown or not." }, { "name": "onOpen", - "type": "(gesture: 'anchor-click' | 'anchor-key-press') => unknown", + "type": "(gesture: 'anchor-click' | 'anchor-key-press', event?: KeyboardEvent | undefined) => unknown", "defaultValue": "", "description": "A callback that is called whenever the overlay is currently closed and an \"open gesture\" is detected." }, @@ -95,6 +133,20 @@ "type": "boolean", "defaultValue": "true", "description": "Determines if the Overlay width should be adjusted responsively if there is not enough space to display the Overlay. If `preventOverflow` is set to `false`, the Overlay will be displayed at the maximum width that fits within the viewport." + }, + { + "name": "height", + "type": "'small' | 'initial' | 'large' | 'medium' | 'auto' | 'fit-content' | 'xsmall' | 'xlarge'", + "required": false, + "description": "", + "defaultValue": "" + }, + { + "name": "width", + "type": "'small' | 'large' | 'medium' | 'auto' | 'xlarge' | 'xxlarge'", + "required": false, + "description": "", + "defaultValue": "" } ] } diff --git a/packages/react/src/Autocomplete/Autocomplete.docs.json b/packages/react/src/Autocomplete/Autocomplete.docs.json index ff776c4ab01..94b13ca91e6 100644 --- a/packages/react/src/Autocomplete/Autocomplete.docs.json +++ b/packages/react/src/Autocomplete/Autocomplete.docs.json @@ -3,12 +3,52 @@ "name": "Autocomplete", "status": "alpha", "a11yReviewed": false, - "stories": [], + "stories": [ + { + "id": "components-autocomplete--default" + }, + { + "id": "components-autocomplete-features--with-token-input" + }, + { + "id": "components-autocomplete-features--add-new-item" + }, + { + "id": "components-autocomplete-features--custom-search-filter-fn" + }, + { + "id": "components-autocomplete-features--custom-sort-after-menu-close" + }, + { + "id": "components-autocomplete-features--with-callback-when-overlay-open-state-changes" + }, + { + "id": "components-autocomplete-features--async-loading-of-items" + }, + { + "id": "components-autocomplete-features--rendering-the-menu-outside-an-overlay" + }, + { + "id": "components-autocomplete-features--custom-overlay-menu-anchor" + }, + { + "id": "components-autocomplete-features--in-overlay-with-custom-scroll-container-ref" + }, + { + "id": "components-autocomplete-features--in-a-dialog" + } + ], "importPath": "@primer/react", "props": [ { "name": "children", "type": "React.ReactNode" + }, + { + "name": "id", + "type": "string", + "description": "May be used to customize how the ID is set on the text input to be used by ARIA attributes on related elements.", + "defaultValue": "" } ], "subcomponents": [ @@ -68,7 +108,7 @@ { "name": "selectedItemIds", "required": true, - "type": "(string | number)[]", + "type": "string[]", "description": "The IDs of the selected items" }, { diff --git a/packages/react/src/Avatar/Avatar.docs.json b/packages/react/src/Avatar/Avatar.docs.json index ca2581332dc..e678fec6eb5 100644 --- a/packages/react/src/Avatar/Avatar.docs.json +++ b/packages/react/src/Avatar/Avatar.docs.json @@ -3,7 +3,23 @@ "name": "Avatar", "status": "alpha", "a11yReviewed": false, - "stories": [], + "stories": [ + { + "id": "components-avatar--default" + }, + { + "id": "components-avatar-features--square" + }, + { + "id": "components-avatar-features--square-sx-prop" + }, + { + "id": "components-avatar-features--size" + }, + { + "id": "components-avatar-features--size-responsive" + } + ], "importPath": "@primer/react", "props": [ { @@ -24,6 +40,13 @@ "defaultValue": "false", "description": "If true, the avatar will be square instead of circular." }, + { + "name": "src", + "type": "string", + "required": false, + "description": "URL of the avatar image.", + "defaultValue": "" + }, { "name": "sx", "type": "SystemStyleObject" diff --git a/packages/react/src/AvatarPair/AvatarPair.docs.json b/packages/react/src/AvatarPair/AvatarPair.docs.json index 6185196dff3..176ec3916df 100644 --- a/packages/react/src/AvatarPair/AvatarPair.docs.json +++ b/packages/react/src/AvatarPair/AvatarPair.docs.json @@ -3,7 +3,17 @@ "name": "AvatarPair", "status": "alpha", "a11yReviewed": false, - "stories": [], + "stories": [ + { + "id": "components-avatarpair--default" + }, + { + "id": "components-avatarpair-features--parent-circle" + }, + { + "id": "components-avatarpair-features--parent-square" + } + ], "importPath": "@primer/react", "props": [ { diff --git a/packages/react/src/AvatarStack/AvatarStack.docs.json b/packages/react/src/AvatarStack/AvatarStack.docs.json index 3f38da7c4eb..286e889c4d8 100644 --- a/packages/react/src/AvatarStack/AvatarStack.docs.json +++ b/packages/react/src/AvatarStack/AvatarStack.docs.json @@ -3,9 +3,43 @@ "name": "AvatarStack", "status": "alpha", "a11yReviewed": false, - "stories": [], + "stories": [ + { + "id": "components-avatarstack--default" + }, + { + "id": "components-avatarstack-features--align-left" + }, + { + "id": "components-avatarstack-features--align-right" + }, + { + "id": "components-avatarstack-features--disable-expand-on-hover" + }, + { + "id": "components-avatarstack-features--custom-size-on-parent" + }, + { + "id": "components-avatarstack-features--custom-size-on-parent-responsive" + }, + { + "id": "components-avatarstack-features--custom-size-on-children" + }, + { + "id": "components-avatarstack-features--custom-size-on-children-responsive" + }, + { + "id": "components-avatarstack-features--with-single-avatar" + } + ], "importPath": "@primer/react", "props": [ + { + "name": "children", + "type": "ReactNode", + "description": "A set of Avatar components to stack", + "defaultValue": "" + }, { "name": "alignRight", "type": "boolean", @@ -24,6 +58,12 @@ "defaultValue": "20", "description": "The size of the avatar children in pixels." }, + { + "name": "className", + "type": "string", + "description": "Class name for custom styling.", + "defaultValue": "" + }, { "name": "sx", "type": "SystemStyleObject" diff --git a/packages/react/src/Banner/Banner.docs.json b/packages/react/src/Banner/Banner.docs.json index 9451a4dbef5..5e2c8980b3b 100644 --- a/packages/react/src/Banner/Banner.docs.json +++ b/packages/react/src/Banner/Banner.docs.json @@ -1,10 +1,53 @@ { "id": "banner", "name": "Banner", - "status": "draft", + "status": "alpha", "a11yReviewed": true, "importPath": "@primer/react/experimental", - "stories": [], + "stories": [ + { + "id": "components-banner--default" + }, + { + "id": "components-banner-features--critical" + }, + { + "id": "components-banner-features--info" + }, + { + "id": "components-banner-features--success" + }, + { + "id": "components-banner-features--upsell" + }, + { + "id": "components-banner-features--warning" + }, + { + "id": "components-banner-features--dismiss" + }, + { + "id": "components-banner-features--dismiss-with-actions" + }, + { + "id": "components-banner-features--with-hidden-title" + }, + { + "id": "components-banner-features--with-hidden-title-and-actions" + }, + { + "id": "components-banner-features--dismissible-with-hidden-title-and-actions" + }, + { + "id": "components-banner-features--dismissible-with-hidden-title-and-secondary-action" + }, + { + "id": "components-banner-features--with-actions" + }, + { + "id": "components-banner-features--custom-icon" + } + ], "props": [ { "name": "aria-label", @@ -69,15 +112,30 @@ }, { "name": "Banner.Description", - "props": [] + "props": [ + { + "name": "className", + "type": "string", + "description": "Class name(s) for custom styling.", + "defaultValue": "" + } + ] }, { "name": "Banner.PrimaryAction", - "props": [] + "props": [], + "passthrough": { + "element": "Button", + "url": "/react/Button" + } }, { "name": "Banner.SecondaryAction", - "props": [] + "props": [], + "passthrough": { + "element": "Button", + "url": "/react/Button" + } } ] } diff --git a/packages/react/src/Blankslate/Blankslate.docs.json b/packages/react/src/Blankslate/Blankslate.docs.json index 9241118b4ea..a2cf0807b05 100644 --- a/packages/react/src/Blankslate/Blankslate.docs.json +++ b/packages/react/src/Blankslate/Blankslate.docs.json @@ -3,13 +3,35 @@ "name": "Blankslate", "status": "draft", "a11yReviewed": false, - "stories": [], + "stories": [ + { + "id": "drafts-components-blankslate--default" + }, + { + "id": "drafts-components-blankslate-features--with-visual" + }, + { + "id": "drafts-components-blankslate-features--with-primary-action" + }, + { + "id": "drafts-components-blankslate-features--with-secondary-action" + }, + { + "id": "drafts-components-blankslate-features--with-border" + }, + { + "id": "drafts-components-blankslate-features--narrow" + }, + { + "id": "drafts-components-blankslate-features--spacious" + } + ], "importPath": "@primer/react/experimental", "props": [ { "name": "border", "type": "boolean", - "description": "" + "description": "Add a border around this component" }, { "name": "narrow", @@ -20,6 +42,12 @@ "name": "spacious", "type": "boolean", "description": "" + }, + { + "name": "className", + "type": "string", + "description": "Class name(s) for custom styling.", + "defaultValue": "" } ], "subcomponents": [ @@ -45,7 +73,8 @@ "props": [ { "name": "href", - "type": "string" + "type": "string", + "description": "Link to complete primary action" } ] }, @@ -54,7 +83,8 @@ "props": [ { "name": "href", - "type": "string" + "type": "string", + "description": "Link to complete secondary action" } ] } diff --git a/packages/react/src/BranchName/BranchName.docs.json b/packages/react/src/BranchName/BranchName.docs.json index 7529b5ef337..585a62d2720 100644 --- a/packages/react/src/BranchName/BranchName.docs.json +++ b/packages/react/src/BranchName/BranchName.docs.json @@ -3,7 +3,17 @@ "name": "BranchName", "status": "alpha", "a11yReviewed": false, - "stories": [], + "stories": [ + { + "id": "components-branchname--default" + }, + { + "id": "components-branchname-features--with-branch-icon" + }, + { + "id": "components-branchname-features--not-a-link" + } + ], "importPath": "@primer/react", "props": [ { @@ -21,4 +31,4 @@ } ], "subcomponents": [] -} \ No newline at end of file +} diff --git a/packages/react/src/Breadcrumbs/Breadcrumbs.docs.json b/packages/react/src/Breadcrumbs/Breadcrumbs.docs.json index 640e078d600..1ee3dcb3b4c 100644 --- a/packages/react/src/Breadcrumbs/Breadcrumbs.docs.json +++ b/packages/react/src/Breadcrumbs/Breadcrumbs.docs.json @@ -3,9 +3,20 @@ "name": "Breadcrumbs", "status": "alpha", "a11yReviewed": false, - "stories": [], + "stories": [ + { + "id": "components-breadcrumbs--default" + } + ], "importPath": "@primer/react", "props": [ + { + "name": "className", + "type": "string", + "required": false, + "description": "", + "defaultValue": "" + }, { "name": "children", "type": "Breadcrumbs.Item[]", @@ -25,7 +36,14 @@ "name": "selected", "type": "boolean", "defaultValue": "false", - "description": "" + "description": "Whether this item represents the current page" + }, + { + "name": "to", + "type": "string | Partial", + "required": false, + "description": "Used when the item is rendered using a component like React Router's `Link`. The path to navigate to.", + "defaultValue": "" }, { "name": "ref", @@ -47,4 +65,4 @@ } } ] -} \ No newline at end of file +} diff --git a/packages/react/src/Button/Button.docs.json b/packages/react/src/Button/Button.docs.json index 627f75d6808..39e688b1acf 100644 --- a/packages/react/src/Button/Button.docs.json +++ b/packages/react/src/Button/Button.docs.json @@ -3,7 +3,86 @@ "name": "Button", "status": "alpha", "a11yReviewed": false, - "stories": [], + "stories": [ + { + "id": "components-button--default" + }, + { + "id": "components-button-features--primary" + }, + { + "id": "components-button-features--danger" + }, + { + "id": "components-button-features--invisible" + }, + { + "id": "components-button-features--link" + }, + { + "id": "components-button-features--leading-visual" + }, + { + "id": "components-button-features--trailing-visual" + }, + { + "id": "components-button-features--trailing-counter" + }, + { + "id": "components-button-features--trailing-counter-with-no-text" + }, + { + "id": "components-button-features--trailing-counter-all-variants" + }, + { + "id": "components-button-features--trailing-action" + }, + { + "id": "components-button-features--block" + }, + { + "id": "components-button-features--disabled" + }, + { + "id": "components-button-features--inactive" + }, + { + "id": "components-button-features--small" + }, + { + "id": "components-button-features--medium" + }, + { + "id": "components-button-features--large" + }, + { + "id": "components-button-features--loading" + }, + { + "id": "components-button-features--loading-custom-announcement" + }, + { + "id": "components-button-features--loading-with-leading-visual" + }, + { + "id": "components-button-features--loading-with-trailing-visual" + }, + { + "id": "components-button-features--loading-with-trailing-action" + }, + { + "id": "components-button-features--loading-trigger" + }, + { + "id": "components-button-features--label-wrap" + }, + { + "id": "components-button-features--inactive-button-with-tooltip" + }, + { + "id": "components-button-features--expanded-button" + } + ], "importPath": "@primer/react", "props": [ { @@ -29,7 +108,7 @@ }, { "name": "count", - "type": "number | string", + "type": "number", "description": "For counter buttons, the number to display." }, { @@ -83,9 +162,14 @@ "type": "React.ElementType", "description": "A visual to display after the button text." }, + { + "name": "trailingAction", + "type": "React.ElementType", + "description": "Trailing action appears to the right of the trailing visual and is always locked to the end" + }, { "name": "variant", - "type": "'default'\n| 'primary'\n| 'danger'\n| 'invisible'", + "type": "'default'\n| 'primary'\n| 'danger'\n| 'invisible'\n| 'link'", "defaultValue": "'default'", "description": "Change the visual style of the button." }, @@ -94,6 +178,12 @@ "type": "boolean", "defaultValue": "false", "description": "Whether the button label should wrap to multiple lines of it is longer than the button width." + }, + { + "name": "disabled", + "type": "boolean", + "description": "Avoid disabling buttons because it will make them inaccessible to users who rely on keyboard navigation. Buttons that are disabled can not be clicked, selected, or navigated through.", + "defaultValue": "" } ], "passthrough": { diff --git a/packages/react/src/Button/IconButton.docs.json b/packages/react/src/Button/IconButton.docs.json index dc357c85695..4513186be1c 100644 --- a/packages/react/src/Button/IconButton.docs.json +++ b/packages/react/src/Button/IconButton.docs.json @@ -3,7 +3,56 @@ "name": "IconButton", "status": "alpha", "a11yReviewed": false, - "stories": [], + "stories": [ + { + "id": "components-iconbutton--default" + }, + { + "id": "components-iconbutton-features--primary" + }, + { + "id": "components-iconbutton-features--danger" + }, + { + "id": "components-iconbutton-features--invisible" + }, + { + "id": "components-iconbutton-features--disabled" + }, + { + "id": "components-iconbutton-features--small" + }, + { + "id": "components-iconbutton-features--medium" + }, + { + "id": "components-iconbutton-features--large" + }, + { + "id": "components-iconbutton-features--with-description" + }, + { + "id": "components-iconbutton-features--external-tooltip" + }, + { + "id": "components-iconbutton-features--external-tooltip-version1" + }, + { + "id": "components-iconbutton-features--as-a-menu-anchor" + }, + { + "id": "components-iconbutton-features--loading" + }, + { + "id": "components-iconbutton-features--loading-trigger" + }, + { + "id": "components-iconbutton-features--keyshortcuts-on-description" + }, + { + "id": "components-iconbutton-features--keyshortcuts" + } + ], "importPath": "@primer/react", "props": [ { @@ -56,6 +105,13 @@ "description": "The direction of the tooltip. ", "required": false }, + { + "name": "description", + "type": "string", + "required": false, + "description": "If `description` is provided, we will use a Tooltip to describe the button. Then `aria-label` is used to label the button.", + "defaultValue": "" + }, { "name": "sx", "type": "SystemStyleObject" diff --git a/packages/react/src/Button/types.ts b/packages/react/src/Button/types.ts index 2d3fae5b07b..2f94f999eba 100644 --- a/packages/react/src/Button/types.ts +++ b/packages/react/src/Button/types.ts @@ -31,7 +31,7 @@ export type ButtonBaseProps = { */ size?: Size /** - * Items that are disabled can not be clicked, selected, or navigated through. + * Avoid disabling buttons because it will make them inaccessible to users who rely on keyboard navigation. that are disabled can not be clicked, selected, or navigated through. */ disabled?: boolean /** diff --git a/packages/react/src/ButtonGroup/ButtonGroup.docs.json b/packages/react/src/ButtonGroup/ButtonGroup.docs.json index 06c470b1253..bc7c4828eb8 100644 --- a/packages/react/src/ButtonGroup/ButtonGroup.docs.json +++ b/packages/react/src/ButtonGroup/ButtonGroup.docs.json @@ -3,7 +3,23 @@ "name": "ButtonGroup", "status": "alpha", "a11yReviewed": false, - "stories": [], + "stories": [ + { + "id": "components-buttongroup--default" + }, + { + "id": "components-buttongroup-features--icon-buttons" + }, + { + "id": "components-buttongroup-features--loading-buttons" + }, + { + "id": "components-buttongroup-features--dropdown-split" + }, + { + "id": "components-buttongroup-features--as-toolbar" + } + ], "importPath": "@primer/react", "props": [ { @@ -16,4 +32,4 @@ } ], "subcomponents": [] -} \ No newline at end of file +} diff --git a/packages/react/src/Checkbox/Checkbox.docs.json b/packages/react/src/Checkbox/Checkbox.docs.json index 8e493070d97..ffe55c31e13 100644 --- a/packages/react/src/Checkbox/Checkbox.docs.json +++ b/packages/react/src/Checkbox/Checkbox.docs.json @@ -3,7 +3,23 @@ "name": "Checkbox", "status": "alpha", "a11yReviewed": false, - "stories": [], + "stories": [ + { + "id": "components-checkbox--default" + }, + { + "id": "components-checkbox-features--with-leading-visual" + }, + { + "id": "components-checkbox-features--disabled" + }, + { + "id": "components-checkbox-features--with-caption" + }, + { + "id": "components-checkbox-features--indeterminate" + } + ], "importPath": "@primer/react", "props": [ { @@ -63,4 +79,4 @@ } ], "subcomponents": [] -} \ No newline at end of file +} diff --git a/packages/react/src/CheckboxGroup/CheckboxGroup.docs.json b/packages/react/src/CheckboxGroup/CheckboxGroup.docs.json index 4d289ce5c81..d32a6d208f8 100644 --- a/packages/react/src/CheckboxGroup/CheckboxGroup.docs.json +++ b/packages/react/src/CheckboxGroup/CheckboxGroup.docs.json @@ -3,7 +3,26 @@ "name": "CheckboxGroup", "status": "alpha", "a11yReviewed": false, - "stories": [], + "stories": [ + { + "id": "components-checkboxgroup--default" + }, + { + "id": "components-checkboxgroup-features--visually-hidden-label" + }, + { + "id": "components-checkboxgroup-features--with-external-label" + }, + { + "id": "components-checkboxgroup-features--error" + }, + { + "id": "components-checkboxgroup-features--success" + }, + { + "id": "components-checkboxgroup-features--caption" + } + ], "importPath": "@primer/react", "props": [ { @@ -102,4 +121,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/packages/react/src/CounterLabel/CounterLabel.docs.json b/packages/react/src/CounterLabel/CounterLabel.docs.json index 17a0b4cb94e..b551fb900a0 100644 --- a/packages/react/src/CounterLabel/CounterLabel.docs.json +++ b/packages/react/src/CounterLabel/CounterLabel.docs.json @@ -3,7 +3,17 @@ "name": "CounterLabel", "status": "alpha", "a11yReviewed": false, - "stories": [], + "stories": [ + { + "id": "components-counterlabel--default" + }, + { + "id": "components-counterlabel-features--primary-theme" + }, + { + "id": "components-counterlabel-features--secondary-theme" + } + ], "importPath": "@primer/react", "props": [ { @@ -11,7 +21,17 @@ "type": "'primary' | 'secondary'", "defaultValue": "", "description": "Pass in 'primary' for a darker background and inverse text, or 'secondary' for a lighter background and primary text. Omitting the scheme prop renders the default counter scheme" + }, + { + "name": "className", + "type": "string", + "description": "Class name(s) for custom styling.", + "defaultValue": "" + }, + { + "name": "sx", + "type": "BetterSystemStyleObject" } ], "subcomponents": [] -} \ No newline at end of file +} diff --git a/packages/react/src/DataTable/DataTable.docs.json b/packages/react/src/DataTable/DataTable.docs.json index d4d298fb049..773441478d2 100644 --- a/packages/react/src/DataTable/DataTable.docs.json +++ b/packages/react/src/DataTable/DataTable.docs.json @@ -5,40 +5,43 @@ "a11yReviewed": true, "stories": [ { - "id": "experimental-components-datatable-features--with-title" + "id": "drafts-components-datatable--default" }, { - "id": "experimental-components-datatable-features--with-title-and-subtitle" + "id": "drafts-components-datatable-features--with-title" }, { - "id": "experimental-components-datatable-features--with-sorting" + "id": "drafts-components-datatable-features--with-title-and-subtitle" }, { - "id": "experimental-components-datatable-features--with-actions" + "id": "drafts-components-datatable-features--with-sorting" }, { - "id": "experimental-components-datatable-features--with-action" + "id": "drafts-components-datatable-features--with-actions" }, { - "id": "experimental-components-datatable-features--with-row-action" + "id": "drafts-components-datatable-features--with-action" }, { - "id": "experimental-components-datatable-features--with-row-actions" + "id": "drafts-components-datatable-features--with-row-action" }, { - "id": "experimental-components-datatable-features--with-row-action-menu" + "id": "drafts-components-datatable-features--with-row-actions" }, { - "id": "experimental-components-datatable-features--with-custom-heading" + "id": "drafts-components-datatable-features--with-row-action-menu" }, { - "id": "experimental-components-datatable-features--with-no-content" + "id": "drafts-components-datatable-features--with-custom-heading" }, { - "id": "experimental-components-datatable-features--with-loading" + "id": "drafts-components-datatable-features--with-no-content" }, { - "id": "experimental-components-datatable-features--with-pagination" + "id": "drafts-components-datatable-features--with-loading" + }, + { + "id": "drafts-components-datatable-features--with-pagination" } ], "importPath": "@primer/react/experimental", @@ -67,6 +70,34 @@ "name": "cellPadding", "type": "'condensed' | 'normal' | 'spacious'", "description": "Specify the amount of space that should be available around the contents of a cell" + }, + { + "name": "aria-describedby", + "type": "string", + "required": false, + "description": "Provide an id to an element which uniquely describes this table", + "defaultValue": "" + }, + { + "name": "aria-labelledby", + "type": "string", + "required": false, + "description": "Provide an id to an element which uniquely labels this table", + "defaultValue": "" + }, + { + "name": "initialSortColumn", + "type": "string | number", + "required": false, + "description": "Provide the id or field of the column by which the table is sorted. When\nusing this `prop`, the input data must be sorted by this column in\nascending order", + "defaultValue": "" + }, + { + "name": "initialSortDirection", + "type": "'ASC' | 'DESC'", + "required": false, + "description": "Provide the sort direction that the table should be sorted by on the\ncurrently sorted column", + "defaultValue": "" } ], "subcomponents": [ @@ -103,6 +134,15 @@ } ] }, + { + "name": "Table.Actions", + "props": [ + { + "name": "children", + "type": "React.ReactNode" + } + ] + }, { "name": "Table.Body", "props": [ @@ -124,6 +164,13 @@ { "name": "Table.Header", "props": [ + { + "name": "align", + "type": "'end' | 'start'", + "required": false, + "description": "The horizontal alignment of the cell's content", + "defaultValue": "" + }, { "name": "children", "type": "React.ReactNode" @@ -133,6 +180,13 @@ { "name": "Table.Cell", "props": [ + { + "name": "align", + "type": "'end' | 'start'", + "required": false, + "description": "The horizontal alignment of the cell's content", + "defaultValue": "" + }, { "name": "children", "type": "React.ReactNode" @@ -144,6 +198,10 @@ } ] }, + { + "name": "Table.CellPlaceholder", + "props": [] + }, { "name": "Table.Container", "props": [ @@ -153,6 +211,10 @@ } ] }, + { + "name": "Table.Divider", + "props": [] + }, { "name": "Table.Title", "props": [ @@ -163,7 +225,8 @@ { "name": "id", "type": "string", - "required": true + "required": true, + "description": "Provide a unique id for the table subtitle. This should be used along with\n`aria-labelledby` on `DataTable`" } ] }, @@ -177,7 +240,8 @@ { "name": "id", "type": "string", - "required": true + "required": true, + "description": "Provide a unique id for the table subtitle. This should be used along with\n`aria-describedby` on `DataTable`" } ] }, @@ -187,16 +251,19 @@ { "name": "cellPadding", "type": "'condensed' | 'normal' | 'spacious'", - "description": "Specify the amount of space that should be available around the contents of a cell" + "description": "Specify the amount of space that should be available around the contents of a cell", + "defaultValue": "normal" }, { "name": "columns", + "required": true, "type": "Array>" }, { "name": "rows", "type": "number", - "description": "Optionally specify the number of rows which should be included in the skeleton state of the component" + "description": "Optionally specify the number of rows which should be included in the skeleton state of the component", + "defaultValue": "10" } ] }, @@ -206,28 +273,42 @@ { "name": "aria-label", "type": "string", - "required": true + "required": true, + "description": "Defines a string value that labels the current element.\nProvide a label for the navigation landmark rendered by this component\n@see aria-labelledby." }, { "name": "defaultPageIndex", - "type": "string" + "type": "string", + "description": "Provide an optional index to specify the default selected page" }, { "name": "id", - "type": "string" + "type": "string", + "description": "Optionally provide an `id` that is placed on the navigation landmark\nrendered by this component" }, { "name": "onChange", - "type": "({ pageIndex }: { pageIndex: number }) => void" + "type": "({ pageIndex }: { pageIndex: number }) => void", + "description": "Optionally provide a handler that is called whenever the pagination state\nis updated" }, { "name": "pageSize", - "type": "number" + "type": "number", + "description": "Optionally specify the number of items within a page", + "defaultValue": "25" }, { "name": "totalCount", "type": "number", - "required": true + "required": true, + "description": "Specify the total number of items within the collection" + }, + { + "name": "showPages", + "type": "boolean | { narrow?: boolean; regular?: boolean; wide?: boolean; }", + "required": false, + "description": "Whether to show the page numbers", + "defaultValue": "{narrow: false}" } ] }, @@ -258,6 +339,31 @@ } ] }, + { + "name": "Table.SortHeader", + "props": [ + { + "name": "direction", + "type": "'ASC' | 'DESC' | 'NONE'", + "required": true, + "description": "Specify the sort direction for the TableHeader", + "defaultValue": "" + }, + { + "name": "onToggleSort", + "type": "() => void", + "required": true, + "description": "Provide a handler that is called when the sortable TableHeader is\ninteracted with via a click or keyboard interaction", + "defaultValue": "" + }, + { + "name": "align", + "type": "'end' | 'start'", + "description": "The horizontal alignment of the cell's content", + "defaultValue": "" + } + ] + }, { "name": "Column options", "props": [ diff --git a/packages/react/src/Details/Details.docs.json b/packages/react/src/Details/Details.docs.json index 0dff5c8d6da..6b4ce4e945a 100644 --- a/packages/react/src/Details/Details.docs.json +++ b/packages/react/src/Details/Details.docs.json @@ -3,7 +3,11 @@ "name": "Details", "status": "alpha", "a11yReviewed": false, - "stories": [], + "stories": [ + { + "id": "components-details--default" + } + ], "importPath": "@primer/react", "props": [ { diff --git a/packages/react/src/Dialog/Dialog.docs.json b/packages/react/src/Dialog/Dialog.docs.json index 695b5c553c4..195991edd36 100644 --- a/packages/react/src/Dialog/Dialog.docs.json +++ b/packages/react/src/Dialog/Dialog.docs.json @@ -6,19 +6,34 @@ "a11yReviewed": false, "stories": [ { - "id": "components-dialog--default" + "id": "drafts-components-dialog--default" }, { - "id": "components-dialog-features--bottom-sheet-narrow" + "id": "drafts-components-dialog-features--with-custom-renderers" }, { - "id": "components-dialog-features--full-screen-narrow" + "id": "drafts-components-dialog-features--stress-test" }, { - "id": "components-dialog-features--side-sheet" + "id": "drafts-components-dialog-features--repro-multistep-dialog-with-conditional-footer" }, { - "id": "components-dialog-features--return-focus-ref" + "id": "drafts-components-dialog-features--bottom-sheet-narrow" + }, + { + "id": "drafts-components-dialog-features--full-screen-narrow" + }, + { + "id": "drafts-components-dialog-features--side-sheet" + }, + { + "id": "drafts-components-dialog-features--return-focus-ref" + }, + { + "id": "drafts-components-dialog-features--new-issues" + }, + { + "id": "drafts-components-dialog-features--retains-focus-trap-with-dynamic-content" } ], "importPath": "@primer/react/experimental", @@ -61,15 +76,17 @@ { "name": "role", "type": "'dialog' | 'alertdialog'", - "description": "The ARIA role to assign to this dialog." + "description": "The ARIA role to assign to this dialog. @see https://www.w3.org/TR/wai-aria-practices-1.1/#dialog_modal\n@see https://www.w3.org/TR/wai-aria-practices-1.1/#alertdialog" }, { "name": "width", - "type": "'small' | 'medium' | 'large' | 'xlarge'" + "type": "'small' | 'medium' | 'large' | 'xlarge'", + "description": "The width of the dialog.\nsmall: 296px\nmedium: 320px\nlarge: 480px\nxlarge: 640px" }, { "name": "height", - "type": "'small' | 'large' | 'auto'" + "type": "'small' | 'large' | 'auto'", + "description": "The height of the dialog.\nsmall: 296x480\nlarge: 480x640\nauto: variable based on contents" }, { "name": "returnFocusRef", @@ -81,6 +98,13 @@ "type": "React.RefObject", "description": "Focus this element when the Dialog opens" }, + { + "name": "position", + "type": "'center' | 'left' | 'right' | { narrow: 'center' | 'left' | 'right' | 'bottom' | 'fullscreen', regular: 'center' | 'left' | 'right' | 'bottom' | 'fullscreen', wide: 'center' | 'left' | 'right' | 'bottom' | 'fullscreen' }", + "required": false, + "description": "The position of the dialog", + "defaultValue": "" + }, { "name": "className", "type": "string | undefined", @@ -88,5 +112,70 @@ "description": "CSS string" } ], - "subcomponents": [] + "subcomponents": [ + { + "name": "Dialog.Body", + "props": [] + }, + { + "name": "Dialog.Buttons", + "props": [ + { + "name": "buttons", + "type": "DialogButtonProps[] (see table below)", + "required": true + } + ] + }, + { + "name": "Dialog.CloseButton", + "props": [ + { + "name": "onClose", + "type": "() => void", + "required": true, + "description": "Callback for closing the Dialog", + "defaultValue": "" + } + ] + }, + { + "name": "Dialog.Footer", + "props": [] + }, + { + "name": "Dialog.Header", + "props": [] + }, + { + "name": "Dialog.Title", + "props": [] + }, + { + "name": "DialogButtonProps", + "props": [ + { + "name": "buttonType", + "type": "'default' | 'danger' | 'primary' | 'normal'", + "description": "The variant of Button to use" + }, + { + "name": "content", + "type": "React.ReactNode", + "required": true, + "description": "The Button's inner text" + }, + { + "name": "autoFocus", + "type": "boolean", + "description": "If true, and if this is the only button with autoFocus set to true, focus this button automatically when the dialog appears." + }, + { + "name": "ref", + "type": "React.RefObject", + "description": " A reference to the rendered Button’s DOM node, used together with `autoFocus` for `focusTrap`’s `initialFocus`." + } + ] + } + ] } diff --git a/packages/react/src/Dialog/Dialog.tsx b/packages/react/src/Dialog/Dialog.tsx index de6299e7e1f..65799b75fb5 100644 --- a/packages/react/src/Dialog/Dialog.tsx +++ b/packages/react/src/Dialog/Dialog.tsx @@ -31,7 +31,7 @@ import {clsx} from 'clsx' */ export type DialogButtonProps = Omit & { /** - * The type of Button element to use + * The variant of Button to use */ buttonType?: 'default' | 'primary' | 'danger' | 'normal' diff --git a/packages/react/src/DialogV1/Dialog.docs.json b/packages/react/src/DialogV1/Dialog.docs.json index 254859970d8..77b44d8279a 100644 --- a/packages/react/src/DialogV1/Dialog.docs.json +++ b/packages/react/src/DialogV1/Dialog.docs.json @@ -4,7 +4,11 @@ "name": "Dialog", "status": "deprecated", "a11yReviewed": false, - "stories": [], + "stories": [ + { + "id": "components-dialog--default" + } + ], "importPath": "@primer/react/deprecated", "props": [ { @@ -37,6 +41,14 @@ "type": "string", "description": "Pass a label to be used to describe the Dialog. Use either a `aria-label` or an `aria-labelledby` but not both." }, + { + "name": "narrow", + "type": "boolean" + }, + { + "name": "wide", + "type": "boolean" + }, { "name": "sx", "type": "SystemStyleObject" diff --git a/packages/react/src/FeatureFlags/FeatureFlags.docs.json b/packages/react/src/FeatureFlags/FeatureFlags.docs.json new file mode 100644 index 00000000000..a39f86ceea8 --- /dev/null +++ b/packages/react/src/FeatureFlags/FeatureFlags.docs.json @@ -0,0 +1,17 @@ +{ + "id": "feature_flags", + "name": "FeatureFlags", + "status": "draft", + "a11yReviewed": false, + "stories": [], + "importPath": "@primer/react/experimental", + "props": [ + { + "name": "flags", + "type": "FeatureFlags", + "required": true, + "description": "Object where keys are feature flag names and values are boolean" + } + ], + "subcomponents": [] +} diff --git a/packages/react/src/Flash/Flash.docs.json b/packages/react/src/Flash/Flash.docs.json index 90f03a9fc48..806ca0e2cb5 100644 --- a/packages/react/src/Flash/Flash.docs.json +++ b/packages/react/src/Flash/Flash.docs.json @@ -3,7 +3,29 @@ "name": "Flash", "status": "alpha", "a11yReviewed": false, - "stories": [], + "stories": [ + { + "id": "components-flash--default" + }, + { + "id": "components-flash-features--success" + }, + { + "id": "components-flash-features--danger" + }, + { + "id": "components-flash-features--warning" + }, + { + "id": "components-flash-features--full" + }, + { + "id": "components-flash-features--with-icon-and-action" + }, + { + "id": "components-flash-features--with-icon-action-dismiss" + } + ], "importPath": "@primer/react", "props": [ { diff --git a/packages/react/src/FormControl/FormControl.docs.json b/packages/react/src/FormControl/FormControl.docs.json index 94dcd39ad7c..24f3fff2670 100644 --- a/packages/react/src/FormControl/FormControl.docs.json +++ b/packages/react/src/FormControl/FormControl.docs.json @@ -3,7 +3,56 @@ "name": "FormControl", "status": "alpha", "a11yReviewed": false, - "stories": [], + "stories": [ + { + "id": "components-formcontrol--default" + }, + { + "id": "components-formcontrol-features--with-complex-inputs" + }, + { + "id": "components-formcontrol-features--form-control-with-custom-input" + }, + { + "id": "components-formcontrol-features--with-checkbox-and-radio-inputs" + }, + { + "id": "components-formcontrol-features--single-input" + }, + { + "id": "components-formcontrol-features--validation-example" + }, + { + "id": "components-formcontrol-features--with-select-panel" + }, + { + "id": "components-formcontrol-features--with-leading-visual" + }, + { + "id": "components-formcontrol-features--disabled-inputs" + }, + { + "id": "components-formcontrol-features--custom-required" + }, + { + "id": "components-formcontrol-features--with-caption" + }, + { + "id": "components-formcontrol-features--with-caption-and-disabled" + }, + { + "id": "components-formcontrol-features--with-hidden-label" + }, + { + "id": "components-formcontrol-features--with-required-indicator" + }, + { + "id": "components-formcontrol-features--with-success-validation" + }, + { + "id": "components-formcontrol-features--with-error-validation" + } + ], "importPath": "@primer/react", "props": [ { @@ -31,6 +80,24 @@ "defaultValue": "false", "description": "If true, the user must specify a value for the input before the owning form can be submitted" }, + { + "name": "id", + "type": "string", + "description": "The unique identifier for this control. Used to associate the label, validation text, and caption text", + "defaultValue": "" + }, + { + "name": "layout", + "type": "'vertical' | 'horizontal'", + "description": "The direction the content flows.\nVertical layout is used by default, and horizontal layout is used for checkbox and radio inputs.", + "defaultValue": "vertical" + }, + { + "name": "className", + "type": "string", + "description": "Class name(s) for custom styling.", + "defaultValue": "" + }, { "name": "sx", "type": "SystemStyleObject" @@ -68,6 +135,23 @@ "defaultValue": "true", "description": "Whether to show or hide the required text in the accessibility tree, the required text is still shown visually." }, + { + "name": "htmlFor", + "type": "string", + "description": "This prop may be used to override the `htmlFor` set from FormControl's React Context.\nThe unique identifier for the associated input", + "defaultValue": "" + }, + { + "name": "id", + "type": "string", + "description": "When `as` prop is 'label', it may be used to override the `htmlFor` given to the