import { AbstractDialogProps , Dialog } from "../../dialog" ; import { Children , ComponentProps , ReactElement , ReactNode , forwardRef , useMemo } from "react" ; import { Content } from "../../placeholders" ; import { Div } from "../../html" ; import { OmitInternalProps , augmentElement , getSlotKey , isNil , mergeProps , useSlots } from "../../shared" ; import { StyleProvider } from "../../styling" ; const DefaultElement = "section" ; export interface InnerModalProps extends AbstractDialogProps < typeof DefaultElement > { /**
     * Whether or not the dialog should take almost all the available space.
     */ fullscreen ? : boolean ; } function useModalContentMarkup ( content ) { return useMemo ( ( ) => { const before = [ ] ; const cards = [ ] ; const after = [ ] ; let hasEncounteredCard = false ; Children . forEach ( content . props . children , ( x , index ) => { if ( getSlotKey ( x ) === "card" ) { cards . push ( augmentElement ( x , { className : "o-ui-modal-choice" , fluid : true , key : index } ) ) ; hasEncounteredCard = true ; } else { if ( hasEncounteredCard ) { after . push ( x ) ; } else { before . push ( x ) ; } } } ) ; const hasCards = cards . length > 0 ; if ( hasCards && cards . length !== 2 ) { throw new Error ( "A choice modal must have exactly 2 card components." ) ; } return { contentMarkup : ( < Content { ... content . props } > { before } { ! hasCards ? undefined : ( < StyleProvider value = { { button : { variant : "secondary" } } } > < Div className = "o-ui-modal-choice-container" > { cards } < /Div> < /StyleProvider>)} { after } < /Content>), hasCards } ; } , [ content ] ) ; } export function InnerModal ( { as = DefaultElement , children , dismissable = true , forwardedRef , fullscreen , zIndex = 1 , ... rest } ) { const { button , "button-group" : buttonGroup , content , footer , header , heading , illustration , image } = useSlots ( children , useMemo ( ( ) => ( { _ : { required : [ "heading" , "content" ] } , button : null , "button-group" : null , content : { className : "o-ui-modal-content" } , footer : null , header : null , heading : null , illustration : null , image : null } ) , [ ] ) ) ; const { contentMarkup , hasCards } = useModalContentMarkup ( content ) ; const size = useMemo ( ( ) => { if ( ! isNil ( image ) || ! isNil ( illustration ) ) { return "md" as const ; } if ( hasCards ) { return "lg" as const ; } return fullscreen ? "fullscreen" as const : "sm" as const ; } , [ fullscreen , image , illustration , hasCards ] ) ; return ( < Dialog { ... mergeProps ( rest , { as , dismissable , ref : forwardedRef , size , zIndex } ) } > { image } { illustration } { heading } { header } { contentMarkup } { footer } { button } { buttonGroup } < /Dialog>); } InnerModal . defaultElement = DefaultElement ; export const Modal = forwardRef < any , OmitInternalProps < InnerModalProps > > ( ( props , ref ) => ( < InnerModal { ... props } forwardedRef = { ref } / > ) ) ; export type ModalProps = ComponentProps < typeof Modal > ;