@@ -15,8 +15,8 @@ import {AvatarContext} from './Avatar';
15
15
import { ButtonContext , LinkButtonContext } from './Button' ;
16
16
import { Checkbox } from './Checkbox' ;
17
17
import { colorToken } from '../style/tokens' with { type : 'macro' } ;
18
+ import { composeRenderProps , ContextValue , DEFAULT_SLOT , type GridListItem , GridListItemProps , Provider } from 'react-aria-components' ;
18
19
import { ContentContext , FooterContext , TextContext } from './Content' ;
19
- import { ContextValue , DEFAULT_SLOT , type GridListItem , GridListItemProps , Provider } from 'react-aria-components' ;
20
20
import { createContext , CSSProperties , forwardRef , ReactNode , useContext } from 'react' ;
21
21
import { DividerContext } from './Divider' ;
22
22
import { DOMProps , DOMRef , DOMRefValue } from '@react-types/shared' ;
@@ -32,9 +32,14 @@ import {SkeletonContext, SkeletonWrapper, useIsSkeleton} from './Skeleton';
32
32
import { useDOMRef } from '@react-spectrum/utils' ;
33
33
import { useSpectrumContextProps } from './useSpectrumContextProps' ;
34
34
35
+ interface CardRenderProps {
36
+ /** The size of the Card. */
37
+ size : 'XS' | 'S' | 'M' | 'L' | 'XL'
38
+ }
39
+
35
40
export interface CardProps extends Omit < GridListItemProps , 'className' | 'style' | 'children' > , StyleProps {
36
41
/** The children of the Card. */
37
- children : ReactNode ,
42
+ children : ReactNode | ( ( renderProps : CardRenderProps ) => ReactNode ) ,
38
43
/**
39
44
* The size of the Card.
40
45
* @default 'M'
@@ -396,7 +401,7 @@ export const Card = forwardRef(function Card(props: CardProps, ref: DOMRef<HTMLD
396
401
[ SkeletonContext , isSkeleton ]
397
402
] } >
398
403
< ImageCoordinator >
399
- { props . children }
404
+ { typeof props . children === 'function' ? props . children ( { size } ) : props . children }
400
405
</ ImageCoordinator >
401
406
</ Provider >
402
407
) ;
@@ -550,45 +555,47 @@ export interface AssetCardProps extends Omit<CardProps, 'density'> {}
550
555
export const AssetCard = forwardRef ( function AssetCard ( props : AssetCardProps , ref : DOMRef < HTMLDivElement > ) {
551
556
return (
552
557
< Card { ...props } ref = { ref } density = "regular" >
553
- < Provider
554
- values = { [
555
- [ ImageContext , {
556
- alt : '' ,
557
- styles : style ( {
558
- width : 'full' ,
559
- aspectRatio : 'square' ,
560
- objectFit : 'contain' ,
561
- pointerEvents : 'none' ,
562
- userSelect : 'none'
563
- } )
564
- } ] ,
565
- [ IllustrationContext , {
566
- render ( icon ) {
567
- return (
568
- < SkeletonWrapper >
569
- < div
570
- className = { style ( {
571
- display : 'flex' ,
572
- alignItems : 'center' ,
573
- justifyContent : 'center' ,
574
- backgroundColor : 'gray-100' ,
575
- aspectRatio : 'square'
576
- } ) } >
577
- { icon }
578
- </ div >
579
- </ SkeletonWrapper >
580
- ) ;
581
- } ,
582
- styles : style ( {
583
- height : 'auto' ,
584
- maxSize : 160 ,
585
- // TODO: this is made up.
586
- width : '[50%]'
587
- } )
588
- } ]
589
- ] } >
590
- { props . children }
591
- </ Provider >
558
+ { composeRenderProps ( props . children , children => (
559
+ < Provider
560
+ values = { [
561
+ [ ImageContext , {
562
+ alt : '' ,
563
+ styles : style ( {
564
+ width : 'full' ,
565
+ aspectRatio : 'square' ,
566
+ objectFit : 'contain' ,
567
+ pointerEvents : 'none' ,
568
+ userSelect : 'none'
569
+ } )
570
+ } ] ,
571
+ [ IllustrationContext , {
572
+ render ( icon ) {
573
+ return (
574
+ < SkeletonWrapper >
575
+ < div
576
+ className = { style ( {
577
+ display : 'flex' ,
578
+ alignItems : 'center' ,
579
+ justifyContent : 'center' ,
580
+ backgroundColor : 'gray-100' ,
581
+ aspectRatio : 'square'
582
+ } ) } >
583
+ { icon }
584
+ </ div >
585
+ </ SkeletonWrapper >
586
+ ) ;
587
+ } ,
588
+ styles : style ( {
589
+ height : 'auto' ,
590
+ maxSize : 160 ,
591
+ // TODO: this is made up.
592
+ width : '[50%]'
593
+ } )
594
+ } ]
595
+ ] } >
596
+ { children }
597
+ </ Provider >
598
+ ) ) }
592
599
</ Card >
593
600
) ;
594
601
} ) ;
@@ -610,35 +617,37 @@ export const UserCard = forwardRef(function UserCard(props: CardProps, ref: DOMR
610
617
let { size = 'M' } = props ;
611
618
return (
612
619
< Card { ...props } ref = { ref } density = "spacious" >
613
- < Provider
614
- values = { [
615
- [ ImageContext , {
616
- alt : '' ,
617
- styles : style ( {
618
- width : 'full' ,
619
- aspectRatio : '[3/1]' ,
620
- objectFit : 'cover' ,
621
- pointerEvents : 'none' ,
622
- userSelect : 'none'
623
- } )
624
- } ] ,
625
- [ AvatarContext , {
626
- size : avatarSize [ size ] ,
627
- UNSAFE_style : {
628
- '--size' : avatarSize [ size ] + 'px'
629
- } as CSSProperties ,
630
- styles : style ( {
631
- position : 'relative' ,
632
- marginTop : {
633
- default : 0 ,
634
- ':is([slot=preview] + &)' : '[calc(var(--size) / -2)]'
635
- }
636
- } ) ,
637
- isOverBackground : true
638
- } ]
639
- ] } >
640
- { props . children }
641
- </ Provider >
620
+ { composeRenderProps ( props . children , children => (
621
+ < Provider
622
+ values = { [
623
+ [ ImageContext , {
624
+ alt : '' ,
625
+ styles : style ( {
626
+ width : 'full' ,
627
+ aspectRatio : '[3/1]' ,
628
+ objectFit : 'cover' ,
629
+ pointerEvents : 'none' ,
630
+ userSelect : 'none'
631
+ } )
632
+ } ] ,
633
+ [ AvatarContext , {
634
+ size : avatarSize [ size ] ,
635
+ UNSAFE_style : {
636
+ '--size' : avatarSize [ size ] + 'px'
637
+ } as CSSProperties ,
638
+ styles : style ( {
639
+ position : 'relative' ,
640
+ marginTop : {
641
+ default : 0 ,
642
+ ':is([slot=preview] + &)' : '[calc(var(--size) / -2)]'
643
+ }
644
+ } ) ,
645
+ isOverBackground : true
646
+ } ]
647
+ ] } >
648
+ { children }
649
+ </ Provider >
650
+ ) ) }
642
651
</ Card >
643
652
) ;
644
653
} ) ;
@@ -660,69 +669,71 @@ export const ProductCard = forwardRef(function ProductCard(props: ProductCardPro
660
669
let { size = 'M' } = props ;
661
670
return (
662
671
< Card { ...props } ref = { ref } density = "spacious" >
663
- < Provider
664
- values = { [
665
- [ ImageContext , {
666
- slots : {
667
- preview : {
668
- alt : '' ,
669
- styles : style ( {
670
- width : 'full' ,
671
- aspectRatio : '[5/1]' ,
672
- objectFit : 'cover' ,
673
- pointerEvents : 'none' ,
674
- userSelect : 'none'
675
- } )
676
- } ,
677
- thumbnail : {
678
- alt : '' ,
679
- styles : style ( {
680
- position : 'relative' ,
681
- pointerEvents : 'none' ,
682
- userSelect : 'none' ,
683
- size : {
684
- size : {
685
- XS : 24 ,
686
- S : 36 ,
687
- M : 40 ,
688
- L : 44 ,
689
- XL : 56
690
- }
691
- } ,
692
- borderRadius : {
693
- default : 'default' ,
672
+ { composeRenderProps ( props . children , children => (
673
+ < Provider
674
+ values = { [
675
+ [ ImageContext , {
676
+ slots : {
677
+ preview : {
678
+ alt : '' ,
679
+ styles : style ( {
680
+ width : 'full' ,
681
+ aspectRatio : '[5/1]' ,
682
+ objectFit : 'cover' ,
683
+ pointerEvents : 'none' ,
684
+ userSelect : 'none'
685
+ } )
686
+ } ,
687
+ thumbnail : {
688
+ alt : '' ,
689
+ styles : style ( {
690
+ position : 'relative' ,
691
+ pointerEvents : 'none' ,
692
+ userSelect : 'none' ,
694
693
size : {
695
- XS : 'sm' ,
696
- S : 'sm'
697
- }
698
- } ,
699
- objectFit : 'cover' ,
700
- marginTop : {
701
- default : 0 ,
702
- ':is([slot=preview] + &)' : '[calc(self(height) / -2)]'
703
- } ,
704
- outlineStyle : 'solid' ,
705
- outlineWidth : {
706
- default : 2 ,
707
- size : {
708
- XS : 1
709
- }
710
- } ,
711
- outlineColor : '--s2-container-bg'
712
- } ) ( { size} )
694
+ size : {
695
+ XS : 24 ,
696
+ S : 36 ,
697
+ M : 40 ,
698
+ L : 44 ,
699
+ XL : 56
700
+ }
701
+ } ,
702
+ borderRadius : {
703
+ default : 'default' ,
704
+ size : {
705
+ XS : 'sm' ,
706
+ S : 'sm'
707
+ }
708
+ } ,
709
+ objectFit : 'cover' ,
710
+ marginTop : {
711
+ default : 0 ,
712
+ ':is([slot=preview] + &)' : '[calc(self(height) / -2)]'
713
+ } ,
714
+ outlineStyle : 'solid' ,
715
+ outlineWidth : {
716
+ default : 2 ,
717
+ size : {
718
+ XS : 1
719
+ }
720
+ } ,
721
+ outlineColor : '--s2-container-bg'
722
+ } ) ( { size} )
723
+ }
713
724
}
714
- }
715
- } ] ,
716
- [ FooterContext , {
717
- styles : mergeStyles ( footer , style ( {
718
- justifyContent : 'end'
719
- } ) )
720
- } ] ,
721
- [ ButtonContext , { size : buttonSize [ size ] } ] ,
722
- [ LinkButtonContext , { size : buttonSize [ size ] } ]
723
- ] } >
724
- { props . children }
725
- </ Provider >
725
+ } ] ,
726
+ [ FooterContext , {
727
+ styles : mergeStyles ( footer , style ( {
728
+ justifyContent : 'end'
729
+ } ) )
730
+ } ] ,
731
+ [ ButtonContext , { size : buttonSize [ size ] } ] ,
732
+ [ LinkButtonContext , { size : buttonSize [ size ] } ]
733
+ ] } >
734
+ { children }
735
+ </ Provider >
736
+ ) ) }
726
737
</ Card >
727
738
) ;
728
739
} ) ;
0 commit comments