@contentful/f36-modal 4.59.3 → 4.60.1

Sign up to get free protection for your applications and to get access to all the features.
package/dist/esm/index.js CHANGED
@@ -4,12 +4,12 @@ import yo from 'react-modal';
4
4
  import { Flex, Box } from '@contentful/f36-core';
5
5
  import { cx, css } from 'emotion';
6
6
  import { CloseIcon } from '@contentful/f36-icons';
7
- import { Button, ButtonGroup } from '@contentful/f36-button';
7
+ import { IconButton, ButtonGroup, Button } from '@contentful/f36-button';
8
8
  import { Subheading, Text } from '@contentful/f36-typography';
9
9
  import m from '@contentful/f36-tokens';
10
10
  import q from 'react-dom';
11
11
 
12
- var ro=Object.defineProperty,ao=Object.defineProperties;var lo=Object.getOwnPropertyDescriptors;var E=Object.getOwnPropertySymbols;var Y=Object.prototype.hasOwnProperty,J=Object.prototype.propertyIsEnumerable;var G=(o,e,t)=>e in o?ro(o,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):o[e]=t,l=(o,e)=>{for(var t in e||(e={}))Y.call(e,t)&&G(o,t,e[t]);if(E)for(var t of E(e))J.call(e,t)&&G(o,t,e[t]);return o},u=(o,e)=>ao(o,lo(e));var h=(o,e)=>{var t={};for(var r in o)Y.call(o,r)&&e.indexOf(r)<0&&(t[r]=o[r]);if(o!=null&&E)for(var r of E(o))e.indexOf(r)<0&&J.call(o,r)&&(t[r]=o[r]);return t};var W=(o,e,t)=>new Promise((r,i)=>{var a=n=>{try{d(t.next(n));}catch(M){i(M);}},s=n=>{try{d(t.throw(n));}catch(M){i(M);}},d=n=>n.done?r(n.value):Promise.resolve(n.value).then(a,s);d((t=t.apply(o,e)).next());});function Q(){return {root:css({position:"relative",padding:`${m.spacingM} ${m.spacingM} ${m.spacingM} ${m.spacingL}`,borderRadius:`${m.borderRadiusMedium} ${m.borderRadiusMedium} 0 0`,borderBottom:`1px solid ${m.gray300}`}),buttonContainer:css({position:"relative",width:m.spacing2Xl,height:m.spacingL,button:{position:"absolute",top:`calc(-1 * ${m.spacing2Xs})`,right:0}})}}var H=s=>{var d=s,{onClose:o,title:e,subtitle:t,testId:r="cf-ui-modal-header",className:i}=d,a=h(d,["onClose","title","subtitle","testId","className"]);let n=Q();return x__default.createElement(Flex,u(l({},a),{className:cx(n.root,i),testId:r,alignItems:"center",justifyContent:"space-between"}),x__default.createElement(Subheading,{as:"h2",isTruncated:!0,marginBottom:"none"},e,t&&x__default.createElement(Text,{marginLeft:"spacingXs",fontColor:"gray700"},t)),o&&x__default.createElement(Flex,{alignItems:"center",className:n.buttonContainer},x__default.createElement(Button,{variant:"transparent","aria-label":"Close",startIcon:x__default.createElement(CloseIcon,{size:"small"}),onClick:()=>{o();},size:"small"})))};H.displayName="ModalHeader";function V(){return {root:css({padding:`${m.spacingM} ${m.spacingL}`,color:m.gray700,fontSize:m.fontSizeM,fontFamily:m.fontStackPrimary,lineHeight:m.lineHeightM,overflowY:"auto",overflowX:"auto",boxSizing:"border-box"})}}var w=i=>{var a=i,{testId:o="cf-ui-modal-content",className:e,children:t}=a,r=h(a,["testId","className","children"]);let s=V();return x__default.createElement(Box,u(l({},r),{as:"div",className:cx(s.root,e),testId:o}),t)};w.displayName="ModalContent";function Z(o){let e=cx(css({backgroundColor:m.colorWhite,borderRadius:o.size==="zen"?0:m.borderRadiusMedium,boxShadow:m.boxShadowHeavy,maxHeight:`calc(100vh - 1rem * (100 / ${m.fontBaseDefault}))`,maxWidth:`calc(100vw - 1rem * (100 / ${m.fontBaseDefault}))`,overflow:"hidden",display:"flex",flexDirection:"column"}),o.allowHeightOverflow?css({overflow:"auto",maxHeight:"none"}):null,o.size==="zen"?css({maxWidth:"none",maxHeight:"none",margin:0,height:"100%",width:"100%"}):null,o.size==="fullscreen"?css({maxWidth:`calc(100vw - ${m.spacingXl})`,maxHeight:`calc(100vh - ${m.spacingXl})`,margin:0,height:"100vh",width:"100vw"}):null,o.className);return {portal:css({display:"block"}),base:{root:cx(css({zIndex:m.zIndexModalContent,position:"relative",padding:0,display:"inline-block",margin:"0 auto",textAlign:"left",outline:"none",transform:o.size==="zen"?"scale(1)":"scale(0.85)",transition:`transform ${m.transitionDurationDefault} ${m.transitionEasingDefault}`}),o.size==="zen"?css({width:"100%",height:"100%"}):null),afterOpen:css({transform:"scale(1) !important"}),beforeClose:css({transform:o.size==="zen"?"scale(1)":"scale(0.85) !important"})},modalOverlay:{root:cx(css({display:"flex",alignItems:"baseline",flexWrap:"wrap",top:0,right:0,bottom:0,left:0,zIndex:m.zIndexModal,opacity:0,transition:`opacity ${m.transitionDurationDefault} ${m.transitionEasingDefault}`,position:"fixed",overflowY:"auto",backgroundColor:"rgba(12, 20, 28, 0.74902)",textAlign:"center",padding:m.spacing2Xl}),o.size==="fullscreen"?css({padding:0}):null,o.position==="center"?css({alignItems:"center",justifyContent:"center"}):null,o.overlayClassName),afterOpen:css({opacity:"1 !important"}),beforeClose:css({opacity:"0 !important"})},modal:e}}var xo={medium:"520px",small:"400px",large:"700px",fullWidth:"100vw",zen:"100vw",fullscreen:"100vw"};function Po(o){if(o&&o.querySelectorAll){let e=o.querySelectorAll("input, button");if(e.length>0){let t=e[0];typeof t.focus=="function"&&t.focus();}}}var j=M=>{var S=M,{allowHeightOverflow:o=!1,position:e="center",shouldCloseOnEscapePress:t=!0,shouldCloseOnOverlayClick:r=!0,size:i="medium",testId:a="cf-ui-modal",topOffset:s="50px",aria:d}=S,n=h(S,["allowHeightOverflow","position","shouldCloseOnEscapePress","shouldCloseOnOverlayClick","size","testId","topOffset","aria"]);var L,T;let z=x.useRef(null),P=u(l({},n),{allowHeightOverflow:o,position:e,shouldCloseOnEscapePress:t,shouldCloseOnOverlayClick:r,size:i,testId:a,topOffset:s}),c=Z({position:e,size:i,allowHeightOverflow:o,className:n.className,overlayClassName:(L=n.overlayProps)==null?void 0:L.className}),B=()=>{var O,I;let f=z.current;if(f){let N=document.activeElement;if(f!==N&&f.contains(N))return}let b=(O=P.initialFocusRef)==null?void 0:O.current;b?(I=b.focus)==null||I.call(b):f&&Po(f);},k=(...f)=>{P.onAfterOpen&&P.onAfterOpen(...f),B();},F=()=>x.createElement(x.Fragment,null,n.title&&x.createElement(H,l({title:n.title,subtitle:n.subtitle,onClose:P.onClose},n.modalHeaderProps)),x.createElement(w,l({},n.modalContentProps),n.children));return x.createElement(yo,{ariaHideApp:!1,aria:d,onRequestClose:P.onClose,isOpen:n.isShown,onAfterOpen:k,shouldCloseOnEsc:t,shouldCloseOnOverlayClick:r,shouldFocusAfterRender:!0,shouldReturnFocusAfterClose:!0,portalClassName:c.portal,style:{content:{top:e==="center"?0:s},overlay:(T=n.overlayProps)==null?void 0:T.style},className:{base:c.base.root,afterOpen:c.base.afterOpen,beforeClose:c.base.beforeClose},overlayClassName:{base:c.modalOverlay.root,afterOpen:c.modalOverlay.afterOpen,beforeClose:c.modalOverlay.beforeClose},closeTimeoutMS:200,contentRef:f=>{z.current=f;}},x.createElement(Box,{testId:a,style:{width:xo[i]||i},className:c.modal,"data-modal-root":!0},typeof n.children=="function"?n.children(P):F()))};j.displayName="Modal";function _(){return {root:css({borderBottomLeftRadius:m.borderRadiusMedium,borderBottomRightRadius:m.borderRadiusMedium,padding:`${m.spacingS} ${m.spacingM}`,width:"100%",boxSizing:"border-box"})}}var $=i=>{var a=i,{testId:o="cf-ui-modal-controls",className:e,children:t}=a,r=h(a,["testId","className","children"]);let s=_();return x__default.createElement(Flex,u(l({},r),{className:cx(s.root,e),testId:o,flexDirection:"row",justifyContent:"flex-end"}),x__default.createElement(ButtonGroup,{variant:"spaced",spacing:"spacingS"},t))};$.displayName="ModalControls";var g=j;g.Content=w;g.Header=H;g.Controls=$;var to=({allowHeightOverflow:o=!1,cancelLabel:e="Cancel",cancelTestId:t="cf-ui-modal-confirm-cancel-button",children:r,confirmLabel:i="Confirm",confirmTestId:a="cf-ui-modal-confirm-confirm-button",intent:s="positive",isConfirmDisabled:d=!1,isConfirmLoading:n=!1,isShown:M,modalContentProps:S,modalControlsProps:z,modalHeaderProps:P,onCancel:c,onConfirm:B,shouldCloseOnEscapePress:k=!0,shouldCloseOnOverlayClick:F=!0,size:L="medium",testId:T="cf-ui-modal-confirm",title:f="Are you sure?",initialFocusRef:b})=>{let O=x__default.useRef(null),I=i?x__default.createElement(Button,{testId:a,isDisabled:d,isLoading:n,variant:s,size:"small",onClick:()=>B()},i):null,N=e?x__default.createElement(Button,{testId:t,variant:"secondary",onClick:c,size:"small",ref:b||O},e):null;return x__default.createElement(g,{testId:T,isShown:M,onClose:c,size:L,shouldCloseOnOverlayClick:F,shouldCloseOnEscapePress:k,allowHeightOverflow:o,initialFocusRef:O},()=>x__default.createElement(x__default.Fragment,null,x__default.createElement(g.Header,l({title:f||""},P)),x__default.createElement(g.Content,l({},S),r),x__default.createElement(g.Controls,l({},z),N,I)))};to.displayName="ModalConfirm";var no=o=>{let e=document.getElementById(o);return e!==null||(e=document.createElement("div"),e.setAttribute("id",o),document.body.appendChild(e)),e},D=new Map;function Ro(){D.forEach((i,a)=>W(this,[i,a],function*({render:o,currentConfig:e,delay:t},r){let s=u(l({},e),{isShown:!1});o(s),yield new Promise(d=>setTimeout(d,t)),q.unmountComponentAtNode(no(r)),D.delete(r);}));}function wo(o,e={}){e=l({delay:300},e);let t=`modals-root${e.modalId||Date.now()}`,r=no(t);return new Promise(i=>{let a={onClose:d,isShown:!0};function s({onClose:n,isShown:M}){q.render(o({onClose:n,isShown:M}),r);}function d(n){return W(this,null,function*(){a=u(l({},a),{isShown:!1}),s(a),yield new Promise(M=>setTimeout(M,e.delay)),q.unmountComponentAtNode(r),r.remove(),D.delete(t),i(n);})}s(a),D.set(t,{render:s,currentConfig:a,delay:e.delay});})}var Oo={open:wo,closeAll:Ro};
12
+ var ro=Object.defineProperty,ao=Object.defineProperties;var lo=Object.getOwnPropertyDescriptors;var E=Object.getOwnPropertySymbols;var Y=Object.prototype.hasOwnProperty,J=Object.prototype.propertyIsEnumerable;var G=(o,e,t)=>e in o?ro(o,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):o[e]=t,l=(o,e)=>{for(var t in e||(e={}))Y.call(e,t)&&G(o,t,e[t]);if(E)for(var t of E(e))J.call(e,t)&&G(o,t,e[t]);return o},c=(o,e)=>ao(o,lo(e));var h=(o,e)=>{var t={};for(var r in o)Y.call(o,r)&&e.indexOf(r)<0&&(t[r]=o[r]);if(o!=null&&E)for(var r of E(o))e.indexOf(r)<0&&J.call(o,r)&&(t[r]=o[r]);return t};var W=(o,e,t)=>new Promise((r,i)=>{var a=n=>{try{d(t.next(n));}catch(M){i(M);}},s=n=>{try{d(t.throw(n));}catch(M){i(M);}},d=n=>n.done?r(n.value):Promise.resolve(n.value).then(a,s);d((t=t.apply(o,e)).next());});function Q(){return {root:css({position:"relative",padding:`${m.spacingM} ${m.spacingM} ${m.spacingM} ${m.spacingL}`,borderRadius:`${m.borderRadiusMedium} ${m.borderRadiusMedium} 0 0`,borderBottom:`1px solid ${m.gray300}`}),buttonContainer:css({position:"relative",width:m.spacing2Xl,height:m.spacingL,button:{position:"absolute",top:`calc(-1 * ${m.spacing2Xs})`,right:0}})}}var H=s=>{var d=s,{onClose:o,title:e,subtitle:t,testId:r="cf-ui-modal-header",className:i}=d,a=h(d,["onClose","title","subtitle","testId","className"]);let n=Q();return x__default.createElement(Flex,c(l({},a),{className:cx(n.root,i),testId:r,alignItems:"center",justifyContent:"space-between"}),x__default.createElement(Subheading,{as:"h2",isTruncated:!0,marginBottom:"none"},e,t&&x__default.createElement(Text,{marginLeft:"spacingXs",fontColor:"gray700"},t)),o&&x__default.createElement(Flex,{alignItems:"center",className:n.buttonContainer},x__default.createElement(IconButton,{variant:"transparent","aria-label":"Close",size:"small",icon:x__default.createElement(CloseIcon,{size:"small"}),onClick:()=>{o();}})))};H.displayName="ModalHeader";function V(){return {root:css({padding:`${m.spacingM} ${m.spacingL}`,color:m.gray700,fontSize:m.fontSizeM,fontFamily:m.fontStackPrimary,lineHeight:m.lineHeightM,overflowY:"auto",overflowX:"auto",boxSizing:"border-box"})}}var w=i=>{var a=i,{testId:o="cf-ui-modal-content",className:e,children:t}=a,r=h(a,["testId","className","children"]);let s=V();return x__default.createElement(Box,c(l({},r),{as:"div",className:cx(s.root,e),testId:o}),t)};w.displayName="ModalContent";function Z(o){let e=cx(css({backgroundColor:m.colorWhite,borderRadius:o.size==="zen"?0:m.borderRadiusMedium,boxShadow:m.boxShadowHeavy,maxHeight:`calc(100vh - 1rem * (100 / ${m.fontBaseDefault}))`,maxWidth:`calc(100vw - 1rem * (100 / ${m.fontBaseDefault}))`,overflow:"hidden",display:"flex",flexDirection:"column"}),o.allowHeightOverflow?css({overflow:"auto",maxHeight:"none"}):null,o.size==="zen"?css({maxWidth:"none",maxHeight:"none",margin:0,height:"100%",width:"100%"}):null,o.size==="fullscreen"?css({maxWidth:`calc(100vw - ${m.spacingXl})`,maxHeight:`calc(100vh - ${m.spacingXl})`,margin:0,height:"100vh",width:"100vw"}):null,o.className);return {portal:css({display:"block"}),base:{root:cx(css({zIndex:m.zIndexModalContent,position:"relative",padding:0,display:"inline-block",margin:"0 auto",textAlign:"left",outline:"none",transform:o.size==="zen"?"scale(1)":"scale(0.85)",transition:`transform ${m.transitionDurationDefault} ${m.transitionEasingDefault}`}),o.size==="zen"?css({width:"100%",height:"100%"}):null),afterOpen:css({transform:"scale(1) !important"}),beforeClose:css({transform:o.size==="zen"?"scale(1)":"scale(0.85) !important"})},modalOverlay:{root:cx(css({display:"flex",alignItems:"baseline",flexWrap:"wrap",top:0,right:0,bottom:0,left:0,zIndex:m.zIndexModal,opacity:0,transition:`opacity ${m.transitionDurationDefault} ${m.transitionEasingDefault}`,position:"fixed",overflowY:"auto",backgroundColor:"rgba(12, 20, 28, 0.74902)",textAlign:"center",padding:m.spacing2Xl}),o.size==="fullscreen"?css({padding:0}):null,o.position==="center"?css({alignItems:"center",justifyContent:"center"}):null,o.overlayClassName),afterOpen:css({opacity:"1 !important"}),beforeClose:css({opacity:"0 !important"})},modal:e}}var xo={medium:"520px",small:"400px",large:"700px",fullWidth:"100vw",zen:"100vw",fullscreen:"100vw"};function Po(o){if(o&&o.querySelectorAll){let e=o.querySelectorAll("input, button");if(e.length>0){let t=e[0];typeof t.focus=="function"&&t.focus();}}}var j=M=>{var S=M,{allowHeightOverflow:o=!1,position:e="center",shouldCloseOnEscapePress:t=!0,shouldCloseOnOverlayClick:r=!0,size:i="medium",testId:a="cf-ui-modal",topOffset:s="50px",aria:d}=S,n=h(S,["allowHeightOverflow","position","shouldCloseOnEscapePress","shouldCloseOnOverlayClick","size","testId","topOffset","aria"]);var L,T;let z=x.useRef(null),P=c(l({},n),{allowHeightOverflow:o,position:e,shouldCloseOnEscapePress:t,shouldCloseOnOverlayClick:r,size:i,testId:a,topOffset:s}),f=Z({position:e,size:i,allowHeightOverflow:o,className:n.className,overlayClassName:(L=n.overlayProps)==null?void 0:L.className}),B=()=>{var O,I;let u=z.current;if(u){let N=document.activeElement;if(u!==N&&u.contains(N))return}let b=(O=P.initialFocusRef)==null?void 0:O.current;b?(I=b.focus)==null||I.call(b):u&&Po(u);},k=(...u)=>{P.onAfterOpen&&P.onAfterOpen(...u),B();},F=()=>x.createElement(x.Fragment,null,n.title&&x.createElement(H,l({title:n.title,subtitle:n.subtitle,onClose:P.onClose},n.modalHeaderProps)),x.createElement(w,l({},n.modalContentProps),n.children));return x.createElement(yo,{ariaHideApp:!1,aria:d,onRequestClose:P.onClose,isOpen:n.isShown,onAfterOpen:k,shouldCloseOnEsc:t,shouldCloseOnOverlayClick:r,shouldFocusAfterRender:!0,shouldReturnFocusAfterClose:!0,portalClassName:f.portal,style:{content:{top:e==="center"?0:s},overlay:(T=n.overlayProps)==null?void 0:T.style},className:{base:f.base.root,afterOpen:f.base.afterOpen,beforeClose:f.base.beforeClose},overlayClassName:{base:f.modalOverlay.root,afterOpen:f.modalOverlay.afterOpen,beforeClose:f.modalOverlay.beforeClose},closeTimeoutMS:200,contentRef:u=>{z.current=u;}},x.createElement(Box,{testId:a,style:{width:xo[i]||i},className:f.modal,"data-modal-root":!0},typeof n.children=="function"?n.children(P):F()))};j.displayName="Modal";function _(){return {root:css({borderBottomLeftRadius:m.borderRadiusMedium,borderBottomRightRadius:m.borderRadiusMedium,padding:`${m.spacingS} ${m.spacingM}`,width:"100%",boxSizing:"border-box"})}}var $=i=>{var a=i,{testId:o="cf-ui-modal-controls",className:e,children:t}=a,r=h(a,["testId","className","children"]);let s=_();return x__default.createElement(Flex,c(l({},r),{className:cx(s.root,e),testId:o,flexDirection:"row",justifyContent:"flex-end"}),x__default.createElement(ButtonGroup,{variant:"spaced",spacing:"spacingS"},t))};$.displayName="ModalControls";var g=j;g.Content=w;g.Header=H;g.Controls=$;var to=({allowHeightOverflow:o=!1,cancelLabel:e="Cancel",cancelTestId:t="cf-ui-modal-confirm-cancel-button",children:r,confirmLabel:i="Confirm",confirmTestId:a="cf-ui-modal-confirm-confirm-button",intent:s="positive",isConfirmDisabled:d=!1,isConfirmLoading:n=!1,isShown:M,modalContentProps:S,modalControlsProps:z,modalHeaderProps:P,onCancel:f,onConfirm:B,shouldCloseOnEscapePress:k=!0,shouldCloseOnOverlayClick:F=!0,size:L="medium",testId:T="cf-ui-modal-confirm",title:u="Are you sure?",initialFocusRef:b})=>{let O=x__default.useRef(null),I=i?x__default.createElement(Button,{testId:a,isDisabled:d,isLoading:n,variant:s,size:"small",onClick:()=>B()},i):null,N=e?x__default.createElement(Button,{testId:t,variant:"secondary",onClick:f,size:"small",ref:b||O},e):null;return x__default.createElement(g,{testId:T,isShown:M,onClose:f,size:L,shouldCloseOnOverlayClick:F,shouldCloseOnEscapePress:k,allowHeightOverflow:o,initialFocusRef:O},()=>x__default.createElement(x__default.Fragment,null,x__default.createElement(g.Header,c(l({title:u||""},P),{onClose:f})),x__default.createElement(g.Content,l({},S),r),x__default.createElement(g.Controls,l({},z),N,I)))};to.displayName="ModalConfirm";var no=o=>{let e=document.getElementById(o);return e!==null||(e=document.createElement("div"),e.setAttribute("id",o),document.body.appendChild(e)),e},D=new Map;function Ro(){D.forEach((i,a)=>W(this,[i,a],function*({render:o,currentConfig:e,delay:t},r){let s=c(l({},e),{isShown:!1});o(s),yield new Promise(d=>setTimeout(d,t)),q.unmountComponentAtNode(no(r)),D.delete(r);}));}function wo(o,e={}){e=l({delay:300},e);let t=`modals-root${e.modalId||Date.now()}`,r=no(t);return new Promise(i=>{let a={onClose:d,isShown:!0};function s({onClose:n,isShown:M}){q.render(o({onClose:n,isShown:M}),r);}function d(n){return W(this,null,function*(){a=c(l({},a),{isShown:!1}),s(a),yield new Promise(M=>setTimeout(M,e.delay)),q.unmountComponentAtNode(r),r.remove(),D.delete(t),i(n);})}s(a),D.set(t,{render:s,currentConfig:a,delay:e.delay});})}var Oo={open:wo,closeAll:Ro};
13
13
 
14
14
  export { g as Modal, to as ModalConfirm, w as ModalContent, $ as ModalControls, H as ModalHeader, Oo as ModalLauncher };
15
15
  //# sourceMappingURL=out.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/Modal.tsx","../../src/ModalHeader/ModalHeader.tsx","../../src/ModalHeader/ModalHeader.styles.ts","../../src/ModalContent/ModalContent.tsx","../../src/ModalContent/ModalContent.styles.ts","../../src/Modal.styles.ts","../../src/ModalControls/ModalControls.tsx","../../src/ModalControls/ModalControls.styles.tsx","../../src/CompoundModal.tsx","../../src/ModalConfirm/ModalConfirm.tsx","../../src/ModalLauncher/ModalLauncher.tsx"],"names":["React","ReactModal","Box","cx","CloseIcon","Flex","Button","Text","Subheading","tokens","css","getModalHeaderStyles","ModalHeader","_a","_b","onClose","title","subtitle","testId","className","otherProps","__objRest","styles","__spreadProps","__spreadValues","getModalContentStyles","ModalContent","children","getModalStyles","props","modal","ModalSizesMapper","focusFirstWithinNode","node","elements","firstElement","Modal","allowHeightOverflow","position","shouldCloseOnEscapePress","shouldCloseOnOverlayClick","size","topOffset","aria","contentRef","onInitialFocus","contentEl","activeEl","initialFocusEl","onAfterOpen","args","renderDefault","ref","ButtonGroup","getModalControlStyles","ModalControls","ModalConfirm","cancelLabel","cancelTestId","confirmLabel","confirmTestId","intent","isConfirmDisabled","isConfirmLoading","isShown","modalContentProps","modalControlsProps","modalHeaderProps","onCancel","onConfirm","initialFocusRef","cancelRef","confirmButton","cancelButton","ReactDOM","getRoot","rootElId","rootDom","openModalsIds","closeAll","_0","_1","__async","render","currentConfig","delay","config","resolveDelay","open","componentRenderer","options","resolve","arg","ModalLauncher"],"mappings":"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","sourcesContent":["import * as React from 'react';\nimport ReactModal from 'react-modal';\n\nimport { Box, type CommonProps, type ExpandProps } from '@contentful/f36-core';\n\nimport { ModalHeader, ModalHeaderProps } from './ModalHeader/ModalHeader';\nimport { ModalContent, ModalContentProps } from './ModalContent/ModalContent';\nimport { getModalStyles } from './Modal.styles';\nimport type { ModalSizeType, ModalPositionType } from './types';\n\nconst ModalSizesMapper: { [key in ModalSizeType]: string } = {\n medium: '520px',\n small: '400px',\n large: '700px',\n fullWidth: '100vw',\n zen: '100vw',\n fullscreen: '100vw',\n};\n\nexport interface ModalProps extends CommonProps {\n /**\n * When true, the dialog is shown.\n */\n isShown: boolean;\n\n /**\n * Function that will be run when the modal is requested to be closed, prior to actually closing.\n */\n onClose: ReactModal.Props['onRequestClose'];\n\n /**\n * Function that will be run after the modal has opened.\n */\n onAfterOpen?: ReactModal.Props['onAfterOpen'];\n\n /**\n * Additional aria attributes\n */\n aria?: ReactModal.Props['aria'];\n\n /**\n * Boolean indicating if clicking the overlay should close the overlay.\n * @default true\n */\n shouldCloseOnOverlayClick?: boolean;\n /**\n * Boolean indicating if pressing the esc key should close the overlay.\n * @default true\n */\n shouldCloseOnEscapePress?: boolean;\n /**\n * Indicating if modal is centered or linked to the top\n * @default center\n */\n position?: ModalPositionType;\n /**\n * Top offset if position is 'top'\n * @default 50px\n */\n topOffset?: number | string;\n /**\n * Modal title that is used in header\n */\n title?: string;\n /**\n * Modal subtitle that is used in header\n */\n subtitle?: string;\n /**\n * Size of the modal window\n * @default medium\n */\n size?: ModalSizeType | string | number;\n /**\n * Are modals higher than viewport allowed\n * @default false\n */\n allowHeightOverflow?: boolean;\n\n /**\n * Optional props to override overlay behaviour\n */\n overlayProps?: Pick<CommonProps, 'className' | 'style'>;\n\n /**\n * Optional props to override ModalHeader behaviour\n */\n modalHeaderProps?: Partial<ModalHeaderProps>;\n\n /**\n * Optional props to override ModalContent behaviour\n */\n modalContentProps?: Partial<ModalContentProps>;\n\n /**\n * Optional property to set initial focus\n */\n initialFocusRef?: React.RefObject<HTMLElement>;\n\n children: React.ReactNode | RenderModal;\n}\n\ntype RenderModal = (modalProps: ModalProps) => React.ReactNode;\n\nfunction focusFirstWithinNode(node: HTMLElement) {\n if (node && node.querySelectorAll) {\n const elements = node.querySelectorAll('input, button');\n if (elements.length > 0) {\n const firstElement = elements[0];\n // @ts-expect-error focus might be missing\n if (typeof firstElement.focus === 'function') {\n // @ts-expect-error focus might be missing\n firstElement.focus();\n }\n }\n }\n}\n\nexport const Modal = ({\n allowHeightOverflow = false,\n position = 'center',\n shouldCloseOnEscapePress = true,\n shouldCloseOnOverlayClick = true,\n size = 'medium',\n testId = 'cf-ui-modal',\n topOffset = '50px',\n aria,\n ...otherProps\n}: ExpandProps<ModalProps>) => {\n const contentRef = React.useRef<HTMLDivElement>(null);\n\n const props = {\n ...otherProps,\n allowHeightOverflow,\n position,\n shouldCloseOnEscapePress,\n shouldCloseOnOverlayClick,\n size,\n testId,\n topOffset,\n };\n\n const styles = getModalStyles({\n position,\n size,\n allowHeightOverflow,\n className: otherProps.className,\n overlayClassName: otherProps.overlayProps?.className,\n });\n\n const onInitialFocus = () => {\n const contentEl = contentRef.current;\n if (contentEl) {\n const activeEl = document.activeElement;\n const isContentContainsActive =\n contentEl !== activeEl && contentEl.contains(activeEl);\n\n if (isContentContainsActive) {\n return;\n }\n }\n\n const initialFocusEl = props.initialFocusRef?.current;\n if (initialFocusEl) {\n initialFocusEl.focus?.();\n } else if (contentEl) {\n focusFirstWithinNode(contentEl);\n }\n };\n\n const onAfterOpen: ModalProps['onAfterOpen'] = (...args) => {\n if (props.onAfterOpen) {\n props.onAfterOpen(...args);\n }\n onInitialFocus();\n };\n\n const renderDefault = () => {\n return (\n <>\n {otherProps.title && (\n <ModalHeader\n title={otherProps.title}\n subtitle={otherProps.subtitle}\n onClose={props.onClose}\n {...otherProps.modalHeaderProps}\n />\n )}\n <ModalContent {...otherProps.modalContentProps}>\n {otherProps.children}\n </ModalContent>\n </>\n );\n };\n\n return (\n <ReactModal\n ariaHideApp={false}\n aria={aria}\n onRequestClose={props.onClose}\n isOpen={otherProps.isShown}\n onAfterOpen={onAfterOpen}\n shouldCloseOnEsc={shouldCloseOnEscapePress}\n shouldCloseOnOverlayClick={shouldCloseOnOverlayClick}\n shouldFocusAfterRender\n shouldReturnFocusAfterClose\n portalClassName={styles.portal}\n style={{\n content: {\n top: position === 'center' ? 0 : topOffset,\n },\n overlay: otherProps.overlayProps?.style,\n }}\n className={{\n base: styles.base.root,\n afterOpen: styles.base.afterOpen,\n beforeClose: styles.base.beforeClose,\n }}\n overlayClassName={{\n base: styles.modalOverlay.root,\n afterOpen: styles.modalOverlay.afterOpen,\n beforeClose: styles.modalOverlay.beforeClose,\n }}\n closeTimeoutMS={200}\n contentRef={(ref) => {\n contentRef.current = ref;\n }}\n >\n <Box\n testId={testId}\n style={{\n width: ModalSizesMapper[size] || size,\n }}\n className={styles.modal}\n data-modal-root\n >\n {typeof otherProps.children === 'function'\n ? otherProps.children(props)\n : renderDefault()}\n </Box>\n </ReactModal>\n );\n};\n\nModal.displayName = 'Modal';\n","import React from 'react';\nimport { cx } from 'emotion';\nimport { CloseIcon } from '@contentful/f36-icons';\nimport {\n Flex,\n type PropsWithHTMLElement,\n type CommonProps,\n} from '@contentful/f36-core';\nimport { Button } from '@contentful/f36-button';\nimport { Text, Subheading } from '@contentful/f36-typography';\n\nimport { getModalHeaderStyles } from './ModalHeader.styles';\n\ninterface ModalHeaderInternalProps extends CommonProps {\n title: string;\n subtitle?: string;\n onClose?: Function;\n}\n\nexport type ModalHeaderProps = PropsWithHTMLElement<\n ModalHeaderInternalProps,\n 'div'\n>;\n\nexport const ModalHeader = ({\n onClose,\n title,\n subtitle,\n testId = 'cf-ui-modal-header',\n className,\n ...otherProps\n}: ModalHeaderProps): React.ReactElement => {\n const styles = getModalHeaderStyles();\n\n return (\n <Flex\n {...otherProps}\n className={cx(styles.root, className)}\n testId={testId}\n alignItems=\"center\"\n justifyContent=\"space-between\"\n >\n <Subheading as=\"h2\" isTruncated marginBottom=\"none\">\n {title}\n {subtitle && (\n <Text marginLeft=\"spacingXs\" fontColor=\"gray700\">\n {subtitle}\n </Text>\n )}\n </Subheading>\n {onClose && (\n <Flex alignItems=\"center\" className={styles.buttonContainer}>\n <Button\n variant=\"transparent\"\n aria-label=\"Close\"\n startIcon={<CloseIcon size=\"small\" />}\n onClick={() => {\n onClose();\n }}\n size=\"small\"\n />\n </Flex>\n )}\n </Flex>\n );\n};\n\nModalHeader.displayName = 'ModalHeader';\n","import tokens from '@contentful/f36-tokens';\nimport { css } from 'emotion';\n\nexport function getModalHeaderStyles() {\n return {\n root: css({\n position: 'relative',\n padding: `${tokens.spacingM} ${tokens.spacingM} ${tokens.spacingM} ${tokens.spacingL}`,\n borderRadius: `${tokens.borderRadiusMedium} ${tokens.borderRadiusMedium} 0 0`,\n borderBottom: `1px solid ${tokens.gray300}`,\n }),\n buttonContainer: css({\n position: 'relative',\n width: tokens.spacing2Xl,\n height: tokens.spacingL,\n button: {\n position: 'absolute',\n top: `calc(-1 * ${tokens.spacing2Xs})`,\n right: 0,\n },\n }),\n };\n}\n","import React from 'react';\nimport { cx } from 'emotion';\nimport {\n Box,\n type PropsWithHTMLElement,\n type CommonProps,\n} from '@contentful/f36-core';\nimport { getModalContentStyles } from './ModalContent.styles';\n\ninterface ModalContentInternalProps extends CommonProps {\n children: React.ReactNode;\n}\n\nexport type ModalContentProps = PropsWithHTMLElement<\n ModalContentInternalProps,\n 'div'\n>;\n\nexport const ModalContent = ({\n testId = 'cf-ui-modal-content',\n className,\n children,\n ...otherProps\n}: ModalContentProps) => {\n const styles = getModalContentStyles();\n return (\n <Box\n {...otherProps}\n as=\"div\"\n className={cx(styles.root, className)}\n testId={testId}\n >\n {children}\n </Box>\n );\n};\n\nModalContent.displayName = 'ModalContent';\n","import { css } from 'emotion';\nimport tokens from '@contentful/f36-tokens';\n\nexport function getModalContentStyles() {\n return {\n root: css({\n padding: `${tokens.spacingM} ${tokens.spacingL}`,\n color: tokens.gray700,\n fontSize: tokens.fontSizeM,\n fontFamily: tokens.fontStackPrimary,\n lineHeight: tokens.lineHeightM,\n overflowY: 'auto',\n overflowX: 'auto',\n boxSizing: 'border-box',\n }),\n };\n}\n","import tokens from '@contentful/f36-tokens';\nimport { css, cx } from 'emotion';\n\nimport type { ModalProps } from './Modal';\n\nexport function getModalStyles(props: {\n size: ModalProps['size'];\n position: ModalProps['position'];\n allowHeightOverflow?: boolean;\n className?: string;\n overlayClassName?: string;\n}) {\n const modal = cx(\n css({\n backgroundColor: tokens.colorWhite,\n borderRadius: props.size === 'zen' ? 0 : tokens.borderRadiusMedium,\n boxShadow: tokens.boxShadowHeavy,\n maxHeight: `calc(100vh - 1rem * (100 / ${tokens.fontBaseDefault}))`,\n maxWidth: `calc(100vw - 1rem * (100 / ${tokens.fontBaseDefault}))`,\n overflow: 'hidden',\n display: 'flex',\n flexDirection: 'column',\n }),\n props.allowHeightOverflow\n ? css({\n overflow: 'auto',\n maxHeight: 'none',\n })\n : null,\n props.size === 'zen'\n ? css({\n maxWidth: 'none',\n maxHeight: 'none',\n margin: 0,\n height: '100%',\n width: '100%',\n })\n : null,\n props.size === 'fullscreen'\n ? css({\n maxWidth: `calc(100vw - ${tokens.spacingXl})`,\n maxHeight: `calc(100vh - ${tokens.spacingXl})`,\n margin: 0,\n height: '100vh',\n width: '100vw',\n })\n : null,\n props.className,\n );\n\n return {\n portal: css({\n display: 'block',\n }),\n base: {\n root: cx(\n css({\n zIndex: tokens.zIndexModalContent,\n position: 'relative',\n padding: 0,\n display: 'inline-block',\n margin: '0 auto',\n textAlign: 'left',\n outline: 'none',\n transform: props.size === 'zen' ? 'scale(1)' : 'scale(0.85)',\n transition: `transform ${tokens.transitionDurationDefault} ${tokens.transitionEasingDefault}`,\n }),\n props.size === 'zen'\n ? css({\n width: '100%',\n height: '100%',\n })\n : null,\n ),\n afterOpen: css({\n transform: 'scale(1) !important',\n }),\n beforeClose: css({\n transform: props.size === 'zen' ? 'scale(1)' : 'scale(0.85) !important',\n }),\n },\n modalOverlay: {\n root: cx(\n css({\n display: 'flex',\n alignItems: 'baseline',\n flexWrap: 'wrap',\n top: 0,\n right: 0,\n bottom: 0,\n left: 0,\n zIndex: tokens.zIndexModal,\n opacity: 0,\n transition: `opacity ${tokens.transitionDurationDefault} ${tokens.transitionEasingDefault}`,\n position: 'fixed',\n overflowY: 'auto',\n backgroundColor: 'rgba(12, 20, 28, 0.74902)',\n textAlign: 'center',\n padding: tokens.spacing2Xl,\n }),\n props.size === 'fullscreen'\n ? css({\n padding: 0,\n })\n : null,\n props.position === 'center'\n ? css({\n alignItems: 'center',\n justifyContent: 'center',\n })\n : null,\n props.overlayClassName,\n ),\n afterOpen: css({\n opacity: '1 !important',\n }),\n beforeClose: css({\n opacity: '0 !important',\n }),\n },\n modal,\n };\n}\n","import React from 'react';\n\nimport {\n Flex,\n type PropsWithHTMLElement,\n type CommonProps,\n} from '@contentful/f36-core';\nimport { ButtonGroup } from '@contentful/f36-button';\nimport { getModalControlStyles } from './ModalControls.styles';\nimport { cx } from 'emotion';\n\ninterface ModalControlsInternalProps extends CommonProps {\n children: React.ReactElement[] | React.ReactElement;\n}\n\nexport type ModalControlsProps = PropsWithHTMLElement<\n ModalControlsInternalProps,\n 'div'\n>;\n\nexport const ModalControls = ({\n testId = 'cf-ui-modal-controls',\n className,\n children,\n ...otherProps\n}: ModalControlsProps): React.ReactElement => {\n const styles = getModalControlStyles();\n\n return (\n <Flex\n {...otherProps}\n className={cx(styles.root, className)}\n testId={testId}\n flexDirection=\"row\"\n justifyContent=\"flex-end\"\n >\n <ButtonGroup variant=\"spaced\" spacing=\"spacingS\">\n {children}\n </ButtonGroup>\n </Flex>\n );\n};\n\nModalControls.displayName = 'ModalControls';\n","import { css } from 'emotion';\nimport tokens from '@contentful/f36-tokens';\n\nexport function getModalControlStyles() {\n return {\n root: css({\n borderBottomLeftRadius: tokens.borderRadiusMedium,\n borderBottomRightRadius: tokens.borderRadiusMedium,\n padding: `${tokens.spacingS} ${tokens.spacingM}`,\n width: `100%`,\n // This is required in places where it is not set globally (e.g. dialogs via the app framework)\n boxSizing: 'border-box',\n }),\n };\n}\n","import { Modal as OriginalModal } from './Modal';\nimport { ModalContent } from './ModalContent/ModalContent';\nimport { ModalHeader } from './ModalHeader/ModalHeader';\nimport { ModalControls } from './ModalControls/ModalControls';\n\ntype CompoundModal = typeof OriginalModal & {\n Content: typeof ModalContent;\n Header: typeof ModalHeader;\n Controls: typeof ModalControls;\n};\n\nexport const Modal = OriginalModal as CompoundModal;\nModal.Content = ModalContent;\nModal.Header = ModalHeader;\nModal.Controls = ModalControls;\n","import React from 'react';\n\nimport { Modal } from '../CompoundModal';\nimport type { ModalProps } from '../Modal';\nimport type { ModalHeaderProps } from '../ModalHeader/ModalHeader';\nimport type { ModalContentProps } from '../ModalContent/ModalContent';\nimport type { ModalControlsProps } from '../ModalControls/ModalControls';\nimport { Button } from '@contentful/f36-button';\n\nexport interface ModalConfirmProps {\n /**\n * When true, the dialog is shown.\n */\n isShown: boolean;\n /**\n * Function that will be called when the confirm button is clicked. This does not close the ModalConfirm.\n */\n onConfirm(): void;\n /**\n * Function that will be called when the cancel button is clicked. This does not close the ModalConfirm.\n */\n onCancel: ModalProps['onClose'];\n /**\n Modal title that is used in header\n */\n title?: string;\n /**\n * Label of the confirm button\n */\n confirmLabel?: string | false;\n /**\n * Label of the cancel button\n */\n cancelLabel?: string | false;\n /**\n * The intent of the ModalConfirm. Used for the Button.\n */\n intent?: 'primary' | 'positive' | 'negative';\n /**\n * Size of the modal window\n */\n size?: ModalProps['size'];\n /**\n * Boolean indicating if clicking the overlay should close the overlay.\n */\n shouldCloseOnOverlayClick?: boolean;\n /**\n * Boolean indicating if pressing the esc key should close the overlay.\n */\n shouldCloseOnEscapePress?: boolean;\n /**\n * When true, the confirm button is set to disabled.\n */\n isConfirmDisabled?: boolean;\n /**\n * When true, the confirm button is set to loading.\n */\n isConfirmLoading?: boolean;\n /**\n * Are modals higher than viewport allowed\n */\n allowHeightOverflow?: boolean;\n\n /**\n * Optional props to override ModalHeader behaviour\n */\n modalHeaderProps?: Partial<ModalHeaderProps>;\n\n /**\n * Optional props to override ModalContent behaviour\n */\n modalContentProps?: Partial<ModalContentProps>;\n\n /**\n * Optional props to override ModalControl behaviour\n */\n modalControlsProps?: Partial<ModalControlsProps>;\n\n /**\n * Optional property to set initial focus\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- we don't know the type of element to give initial focus\n initialFocusRef?: React.RefObject<any>;\n\n testId?: string;\n confirmTestId?: string;\n cancelTestId?: string;\n children: React.ReactNode;\n}\n\nexport const ModalConfirm = ({\n allowHeightOverflow = false,\n cancelLabel = 'Cancel',\n cancelTestId = 'cf-ui-modal-confirm-cancel-button',\n children,\n confirmLabel = 'Confirm',\n confirmTestId = 'cf-ui-modal-confirm-confirm-button',\n intent = 'positive',\n isConfirmDisabled = false,\n isConfirmLoading = false,\n isShown,\n modalContentProps,\n modalControlsProps,\n modalHeaderProps,\n onCancel,\n onConfirm,\n shouldCloseOnEscapePress = true,\n shouldCloseOnOverlayClick = true,\n size = 'medium',\n testId = 'cf-ui-modal-confirm',\n title = 'Are you sure?',\n initialFocusRef,\n}: ModalConfirmProps) => {\n const cancelRef = React.useRef(null);\n\n const confirmButton = confirmLabel ? (\n <Button\n testId={confirmTestId}\n isDisabled={isConfirmDisabled}\n isLoading={isConfirmLoading}\n variant={intent}\n size=\"small\"\n onClick={() => onConfirm()}\n >\n {confirmLabel}\n </Button>\n ) : null;\n\n const cancelButton = cancelLabel ? (\n <Button\n testId={cancelTestId}\n variant=\"secondary\"\n onClick={onCancel}\n size=\"small\"\n ref={initialFocusRef || cancelRef}\n >\n {cancelLabel}\n </Button>\n ) : null;\n\n return (\n <Modal\n testId={testId}\n isShown={isShown}\n onClose={onCancel}\n size={size}\n shouldCloseOnOverlayClick={shouldCloseOnOverlayClick}\n shouldCloseOnEscapePress={shouldCloseOnEscapePress}\n allowHeightOverflow={allowHeightOverflow}\n initialFocusRef={cancelRef}\n >\n {() => {\n return (\n <React.Fragment>\n <Modal.Header title={title || ''} {...modalHeaderProps} />\n <Modal.Content {...modalContentProps}>{children}</Modal.Content>\n <Modal.Controls {...modalControlsProps}>\n {cancelButton}\n {confirmButton}\n </Modal.Controls>\n </React.Fragment>\n );\n }}\n </Modal>\n );\n};\n\nModalConfirm.displayName = 'ModalConfirm';\n","/* global Promise */\nimport ReactDOM from 'react-dom';\n\n// @todo: change any to unknown\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport interface ModalLauncherComponentRendererProps<T = any> {\n isShown: boolean;\n onClose: (result?: T) => void;\n}\n\nexport interface ModalLauncherOpenOptions {\n /**\n * Unique id to be used as identifier for the modal contianer\n */\n modalId?: string;\n /**\n * ms before removing the component from the tree\n * @default 300\n */\n delay?: number;\n}\n\ninterface CloseModalData {\n delay: number;\n render: (args: ModalLauncherComponentRendererProps<any>) => void;\n currentConfig: ModalLauncherComponentRendererProps<any>;\n}\n\nconst getRoot = (rootElId: string): HTMLElement => {\n // Reuse the container if we find it\n let rootDom = document.getElementById(rootElId);\n if (rootDom !== null) {\n return rootDom;\n }\n\n // Otherwise create it\n rootDom = document.createElement('div');\n rootDom.setAttribute('id', rootElId);\n document.body.appendChild(rootDom);\n return rootDom;\n};\n\nconst openModalsIds: Map<string, CloseModalData> = new Map();\nfunction closeAll() {\n openModalsIds.forEach(async ({ render, currentConfig, delay }, rootElId) => {\n const config = { ...currentConfig, isShown: false };\n render(config);\n await new Promise((resolveDelay) => setTimeout(resolveDelay, delay));\n ReactDOM.unmountComponentAtNode(getRoot(rootElId));\n openModalsIds.delete(rootElId);\n });\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction open<T = any>(\n componentRenderer: (\n props: ModalLauncherComponentRendererProps<T>,\n ) => JSX.Element,\n options: ModalLauncherOpenOptions = {},\n): Promise<T> {\n options = { delay: 300, ...options };\n\n // Allow components to specify if they wish to reuse the modal container\n const rootElId = `modals-root${options.modalId || Date.now()}`;\n const rootDom = getRoot(rootElId);\n\n return new Promise((resolve) => {\n let currentConfig = { onClose, isShown: true };\n\n function render({\n onClose,\n isShown,\n }: ModalLauncherComponentRendererProps<T>) {\n ReactDOM.render(componentRenderer({ onClose, isShown }), rootDom);\n }\n\n async function onClose(arg?: T) {\n currentConfig = {\n ...currentConfig,\n isShown: false,\n };\n render(currentConfig);\n await new Promise((resolveDelay) =>\n setTimeout(resolveDelay, options.delay),\n );\n ReactDOM.unmountComponentAtNode(rootDom);\n rootDom.remove();\n openModalsIds.delete(rootElId);\n resolve(arg);\n }\n\n render(currentConfig);\n openModalsIds.set(rootElId, {\n render,\n currentConfig,\n delay: options.delay,\n });\n });\n}\n\nexport const ModalLauncher = {\n open,\n closeAll,\n};\n"]}
1
+ {"version":3,"sources":["../../src/Modal.tsx","../../src/ModalHeader/ModalHeader.tsx","../../src/ModalHeader/ModalHeader.styles.ts","../../src/ModalContent/ModalContent.tsx","../../src/ModalContent/ModalContent.styles.ts","../../src/Modal.styles.ts","../../src/ModalControls/ModalControls.tsx","../../src/ModalControls/ModalControls.styles.tsx","../../src/CompoundModal.tsx","../../src/ModalConfirm/ModalConfirm.tsx","../../src/ModalLauncher/ModalLauncher.tsx"],"names":["React","ReactModal","Box","cx","CloseIcon","Flex","IconButton","Text","Subheading","tokens","css","getModalHeaderStyles","ModalHeader","_a","_b","onClose","title","subtitle","testId","className","otherProps","__objRest","styles","__spreadProps","__spreadValues","getModalContentStyles","ModalContent","children","getModalStyles","props","modal","ModalSizesMapper","focusFirstWithinNode","node","elements","firstElement","Modal","allowHeightOverflow","position","shouldCloseOnEscapePress","shouldCloseOnOverlayClick","size","topOffset","aria","contentRef","onInitialFocus","contentEl","activeEl","initialFocusEl","onAfterOpen","args","renderDefault","ref","ButtonGroup","getModalControlStyles","ModalControls","Button","ModalConfirm","cancelLabel","cancelTestId","confirmLabel","confirmTestId","intent","isConfirmDisabled","isConfirmLoading","isShown","modalContentProps","modalControlsProps","modalHeaderProps","onCancel","onConfirm","initialFocusRef","cancelRef","confirmButton","cancelButton","ReactDOM","getRoot","rootElId","rootDom","openModalsIds","closeAll","_0","_1","__async","render","currentConfig","delay","config","resolveDelay","open","componentRenderer","options","resolve","arg","ModalLauncher"],"mappings":"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","sourcesContent":["import * as React from 'react';\nimport ReactModal from 'react-modal';\n\nimport { Box, type CommonProps, type ExpandProps } from '@contentful/f36-core';\n\nimport { ModalHeader, ModalHeaderProps } from './ModalHeader/ModalHeader';\nimport { ModalContent, ModalContentProps } from './ModalContent/ModalContent';\nimport { getModalStyles } from './Modal.styles';\nimport type { ModalSizeType, ModalPositionType } from './types';\n\nconst ModalSizesMapper: { [key in ModalSizeType]: string } = {\n medium: '520px',\n small: '400px',\n large: '700px',\n fullWidth: '100vw',\n zen: '100vw',\n fullscreen: '100vw',\n};\n\nexport interface ModalProps extends CommonProps {\n /**\n * When true, the dialog is shown.\n */\n isShown: boolean;\n\n /**\n * Function that will be run when the modal is requested to be closed, prior to actually closing.\n */\n onClose: ReactModal.Props['onRequestClose'];\n\n /**\n * Function that will be run after the modal has opened.\n */\n onAfterOpen?: ReactModal.Props['onAfterOpen'];\n\n /**\n * Additional aria attributes\n */\n aria?: ReactModal.Props['aria'];\n\n /**\n * Boolean indicating if clicking the overlay should close the overlay.\n * @default true\n */\n shouldCloseOnOverlayClick?: boolean;\n /**\n * Boolean indicating if pressing the esc key should close the overlay.\n * @default true\n */\n shouldCloseOnEscapePress?: boolean;\n /**\n * Indicating if modal is centered or linked to the top\n * @default center\n */\n position?: ModalPositionType;\n /**\n * Top offset if position is 'top'\n * @default 50px\n */\n topOffset?: number | string;\n /**\n * Modal title that is used in header\n */\n title?: string;\n /**\n * Modal subtitle that is used in header\n */\n subtitle?: string;\n /**\n * Size of the modal window\n * @default medium\n */\n size?: ModalSizeType | string | number;\n /**\n * Are modals higher than viewport allowed\n * @default false\n */\n allowHeightOverflow?: boolean;\n\n /**\n * Optional props to override overlay behaviour\n */\n overlayProps?: Pick<CommonProps, 'className' | 'style'>;\n\n /**\n * Optional props to override ModalHeader behaviour\n */\n modalHeaderProps?: Partial<ModalHeaderProps>;\n\n /**\n * Optional props to override ModalContent behaviour\n */\n modalContentProps?: Partial<ModalContentProps>;\n\n /**\n * Optional property to set initial focus\n */\n initialFocusRef?: React.RefObject<HTMLElement>;\n\n children: React.ReactNode | RenderModal;\n}\n\ntype RenderModal = (modalProps: ModalProps) => React.ReactNode;\n\nfunction focusFirstWithinNode(node: HTMLElement) {\n if (node && node.querySelectorAll) {\n const elements = node.querySelectorAll('input, button');\n if (elements.length > 0) {\n const firstElement = elements[0];\n // @ts-expect-error focus might be missing\n if (typeof firstElement.focus === 'function') {\n // @ts-expect-error focus might be missing\n firstElement.focus();\n }\n }\n }\n}\n\nexport const Modal = ({\n allowHeightOverflow = false,\n position = 'center',\n shouldCloseOnEscapePress = true,\n shouldCloseOnOverlayClick = true,\n size = 'medium',\n testId = 'cf-ui-modal',\n topOffset = '50px',\n aria,\n ...otherProps\n}: ExpandProps<ModalProps>) => {\n const contentRef = React.useRef<HTMLDivElement>(null);\n\n const props = {\n ...otherProps,\n allowHeightOverflow,\n position,\n shouldCloseOnEscapePress,\n shouldCloseOnOverlayClick,\n size,\n testId,\n topOffset,\n };\n\n const styles = getModalStyles({\n position,\n size,\n allowHeightOverflow,\n className: otherProps.className,\n overlayClassName: otherProps.overlayProps?.className,\n });\n\n const onInitialFocus = () => {\n const contentEl = contentRef.current;\n if (contentEl) {\n const activeEl = document.activeElement;\n const isContentContainsActive =\n contentEl !== activeEl && contentEl.contains(activeEl);\n\n if (isContentContainsActive) {\n return;\n }\n }\n\n const initialFocusEl = props.initialFocusRef?.current;\n if (initialFocusEl) {\n initialFocusEl.focus?.();\n } else if (contentEl) {\n focusFirstWithinNode(contentEl);\n }\n };\n\n const onAfterOpen: ModalProps['onAfterOpen'] = (...args) => {\n if (props.onAfterOpen) {\n props.onAfterOpen(...args);\n }\n onInitialFocus();\n };\n\n const renderDefault = () => {\n return (\n <>\n {otherProps.title && (\n <ModalHeader\n title={otherProps.title}\n subtitle={otherProps.subtitle}\n onClose={props.onClose}\n {...otherProps.modalHeaderProps}\n />\n )}\n <ModalContent {...otherProps.modalContentProps}>\n {otherProps.children}\n </ModalContent>\n </>\n );\n };\n\n return (\n <ReactModal\n ariaHideApp={false}\n aria={aria}\n onRequestClose={props.onClose}\n isOpen={otherProps.isShown}\n onAfterOpen={onAfterOpen}\n shouldCloseOnEsc={shouldCloseOnEscapePress}\n shouldCloseOnOverlayClick={shouldCloseOnOverlayClick}\n shouldFocusAfterRender\n shouldReturnFocusAfterClose\n portalClassName={styles.portal}\n style={{\n content: {\n top: position === 'center' ? 0 : topOffset,\n },\n overlay: otherProps.overlayProps?.style,\n }}\n className={{\n base: styles.base.root,\n afterOpen: styles.base.afterOpen,\n beforeClose: styles.base.beforeClose,\n }}\n overlayClassName={{\n base: styles.modalOverlay.root,\n afterOpen: styles.modalOverlay.afterOpen,\n beforeClose: styles.modalOverlay.beforeClose,\n }}\n closeTimeoutMS={200}\n contentRef={(ref) => {\n contentRef.current = ref;\n }}\n >\n <Box\n testId={testId}\n style={{\n width: ModalSizesMapper[size] || size,\n }}\n className={styles.modal}\n data-modal-root\n >\n {typeof otherProps.children === 'function'\n ? otherProps.children(props)\n : renderDefault()}\n </Box>\n </ReactModal>\n );\n};\n\nModal.displayName = 'Modal';\n","import React from 'react';\nimport { cx } from 'emotion';\nimport { CloseIcon } from '@contentful/f36-icons';\nimport {\n Flex,\n type PropsWithHTMLElement,\n type CommonProps,\n} from '@contentful/f36-core';\nimport { IconButton } from '@contentful/f36-button';\nimport { Text, Subheading } from '@contentful/f36-typography';\n\nimport { getModalHeaderStyles } from './ModalHeader.styles';\n\ninterface ModalHeaderInternalProps extends CommonProps {\n title: string;\n subtitle?: string;\n onClose?: Function;\n}\n\nexport type ModalHeaderProps = PropsWithHTMLElement<\n ModalHeaderInternalProps,\n 'div'\n>;\n\nexport const ModalHeader = ({\n onClose,\n title,\n subtitle,\n testId = 'cf-ui-modal-header',\n className,\n ...otherProps\n}: ModalHeaderProps): React.ReactElement => {\n const styles = getModalHeaderStyles();\n\n return (\n <Flex\n {...otherProps}\n className={cx(styles.root, className)}\n testId={testId}\n alignItems=\"center\"\n justifyContent=\"space-between\"\n >\n <Subheading as=\"h2\" isTruncated marginBottom=\"none\">\n {title}\n {subtitle && (\n <Text marginLeft=\"spacingXs\" fontColor=\"gray700\">\n {subtitle}\n </Text>\n )}\n </Subheading>\n {onClose && (\n <Flex alignItems=\"center\" className={styles.buttonContainer}>\n <IconButton\n variant=\"transparent\"\n aria-label=\"Close\"\n size=\"small\"\n icon={<CloseIcon size=\"small\" />}\n onClick={() => {\n onClose();\n }}\n />\n </Flex>\n )}\n </Flex>\n );\n};\n\nModalHeader.displayName = 'ModalHeader';\n","import tokens from '@contentful/f36-tokens';\nimport { css } from 'emotion';\n\nexport function getModalHeaderStyles() {\n return {\n root: css({\n position: 'relative',\n padding: `${tokens.spacingM} ${tokens.spacingM} ${tokens.spacingM} ${tokens.spacingL}`,\n borderRadius: `${tokens.borderRadiusMedium} ${tokens.borderRadiusMedium} 0 0`,\n borderBottom: `1px solid ${tokens.gray300}`,\n }),\n buttonContainer: css({\n position: 'relative',\n width: tokens.spacing2Xl,\n height: tokens.spacingL,\n button: {\n position: 'absolute',\n top: `calc(-1 * ${tokens.spacing2Xs})`,\n right: 0,\n },\n }),\n };\n}\n","import React from 'react';\nimport { cx } from 'emotion';\nimport {\n Box,\n type PropsWithHTMLElement,\n type CommonProps,\n} from '@contentful/f36-core';\nimport { getModalContentStyles } from './ModalContent.styles';\n\ninterface ModalContentInternalProps extends CommonProps {\n children: React.ReactNode;\n}\n\nexport type ModalContentProps = PropsWithHTMLElement<\n ModalContentInternalProps,\n 'div'\n>;\n\nexport const ModalContent = ({\n testId = 'cf-ui-modal-content',\n className,\n children,\n ...otherProps\n}: ModalContentProps) => {\n const styles = getModalContentStyles();\n return (\n <Box\n {...otherProps}\n as=\"div\"\n className={cx(styles.root, className)}\n testId={testId}\n >\n {children}\n </Box>\n );\n};\n\nModalContent.displayName = 'ModalContent';\n","import { css } from 'emotion';\nimport tokens from '@contentful/f36-tokens';\n\nexport function getModalContentStyles() {\n return {\n root: css({\n padding: `${tokens.spacingM} ${tokens.spacingL}`,\n color: tokens.gray700,\n fontSize: tokens.fontSizeM,\n fontFamily: tokens.fontStackPrimary,\n lineHeight: tokens.lineHeightM,\n overflowY: 'auto',\n overflowX: 'auto',\n boxSizing: 'border-box',\n }),\n };\n}\n","import tokens from '@contentful/f36-tokens';\nimport { css, cx } from 'emotion';\n\nimport type { ModalProps } from './Modal';\n\nexport function getModalStyles(props: {\n size: ModalProps['size'];\n position: ModalProps['position'];\n allowHeightOverflow?: boolean;\n className?: string;\n overlayClassName?: string;\n}) {\n const modal = cx(\n css({\n backgroundColor: tokens.colorWhite,\n borderRadius: props.size === 'zen' ? 0 : tokens.borderRadiusMedium,\n boxShadow: tokens.boxShadowHeavy,\n maxHeight: `calc(100vh - 1rem * (100 / ${tokens.fontBaseDefault}))`,\n maxWidth: `calc(100vw - 1rem * (100 / ${tokens.fontBaseDefault}))`,\n overflow: 'hidden',\n display: 'flex',\n flexDirection: 'column',\n }),\n props.allowHeightOverflow\n ? css({\n overflow: 'auto',\n maxHeight: 'none',\n })\n : null,\n props.size === 'zen'\n ? css({\n maxWidth: 'none',\n maxHeight: 'none',\n margin: 0,\n height: '100%',\n width: '100%',\n })\n : null,\n props.size === 'fullscreen'\n ? css({\n maxWidth: `calc(100vw - ${tokens.spacingXl})`,\n maxHeight: `calc(100vh - ${tokens.spacingXl})`,\n margin: 0,\n height: '100vh',\n width: '100vw',\n })\n : null,\n props.className,\n );\n\n return {\n portal: css({\n display: 'block',\n }),\n base: {\n root: cx(\n css({\n zIndex: tokens.zIndexModalContent,\n position: 'relative',\n padding: 0,\n display: 'inline-block',\n margin: '0 auto',\n textAlign: 'left',\n outline: 'none',\n transform: props.size === 'zen' ? 'scale(1)' : 'scale(0.85)',\n transition: `transform ${tokens.transitionDurationDefault} ${tokens.transitionEasingDefault}`,\n }),\n props.size === 'zen'\n ? css({\n width: '100%',\n height: '100%',\n })\n : null,\n ),\n afterOpen: css({\n transform: 'scale(1) !important',\n }),\n beforeClose: css({\n transform: props.size === 'zen' ? 'scale(1)' : 'scale(0.85) !important',\n }),\n },\n modalOverlay: {\n root: cx(\n css({\n display: 'flex',\n alignItems: 'baseline',\n flexWrap: 'wrap',\n top: 0,\n right: 0,\n bottom: 0,\n left: 0,\n zIndex: tokens.zIndexModal,\n opacity: 0,\n transition: `opacity ${tokens.transitionDurationDefault} ${tokens.transitionEasingDefault}`,\n position: 'fixed',\n overflowY: 'auto',\n backgroundColor: 'rgba(12, 20, 28, 0.74902)',\n textAlign: 'center',\n padding: tokens.spacing2Xl,\n }),\n props.size === 'fullscreen'\n ? css({\n padding: 0,\n })\n : null,\n props.position === 'center'\n ? css({\n alignItems: 'center',\n justifyContent: 'center',\n })\n : null,\n props.overlayClassName,\n ),\n afterOpen: css({\n opacity: '1 !important',\n }),\n beforeClose: css({\n opacity: '0 !important',\n }),\n },\n modal,\n };\n}\n","import React from 'react';\n\nimport {\n Flex,\n type PropsWithHTMLElement,\n type CommonProps,\n} from '@contentful/f36-core';\nimport { ButtonGroup } from '@contentful/f36-button';\nimport { getModalControlStyles } from './ModalControls.styles';\nimport { cx } from 'emotion';\n\ninterface ModalControlsInternalProps extends CommonProps {\n children: React.ReactElement[] | React.ReactElement;\n}\n\nexport type ModalControlsProps = PropsWithHTMLElement<\n ModalControlsInternalProps,\n 'div'\n>;\n\nexport const ModalControls = ({\n testId = 'cf-ui-modal-controls',\n className,\n children,\n ...otherProps\n}: ModalControlsProps): React.ReactElement => {\n const styles = getModalControlStyles();\n\n return (\n <Flex\n {...otherProps}\n className={cx(styles.root, className)}\n testId={testId}\n flexDirection=\"row\"\n justifyContent=\"flex-end\"\n >\n <ButtonGroup variant=\"spaced\" spacing=\"spacingS\">\n {children}\n </ButtonGroup>\n </Flex>\n );\n};\n\nModalControls.displayName = 'ModalControls';\n","import { css } from 'emotion';\nimport tokens from '@contentful/f36-tokens';\n\nexport function getModalControlStyles() {\n return {\n root: css({\n borderBottomLeftRadius: tokens.borderRadiusMedium,\n borderBottomRightRadius: tokens.borderRadiusMedium,\n padding: `${tokens.spacingS} ${tokens.spacingM}`,\n width: `100%`,\n // This is required in places where it is not set globally (e.g. dialogs via the app framework)\n boxSizing: 'border-box',\n }),\n };\n}\n","import { Modal as OriginalModal } from './Modal';\nimport { ModalContent } from './ModalContent/ModalContent';\nimport { ModalHeader } from './ModalHeader/ModalHeader';\nimport { ModalControls } from './ModalControls/ModalControls';\n\ntype CompoundModal = typeof OriginalModal & {\n Content: typeof ModalContent;\n Header: typeof ModalHeader;\n Controls: typeof ModalControls;\n};\n\nexport const Modal = OriginalModal as CompoundModal;\nModal.Content = ModalContent;\nModal.Header = ModalHeader;\nModal.Controls = ModalControls;\n","import React from 'react';\n\nimport { Modal } from '../CompoundModal';\nimport type { ModalProps } from '../Modal';\nimport type { ModalHeaderProps } from '../ModalHeader/ModalHeader';\nimport type { ModalContentProps } from '../ModalContent/ModalContent';\nimport type { ModalControlsProps } from '../ModalControls/ModalControls';\nimport { Button } from '@contentful/f36-button';\n\nexport interface ModalConfirmProps {\n /**\n * When true, the dialog is shown.\n */\n isShown: boolean;\n /**\n * Function that will be called when the confirm button is clicked. This does not close the ModalConfirm.\n */\n onConfirm(): void;\n /**\n * Function that will be called when the cancel button is clicked. This does not close the ModalConfirm.\n */\n onCancel: ModalProps['onClose'];\n /**\n Modal title that is used in header\n */\n title?: string;\n /**\n * Label of the confirm button\n */\n confirmLabel?: string | false;\n /**\n * Label of the cancel button\n */\n cancelLabel?: string | false;\n /**\n * The intent of the ModalConfirm. Used for the Button.\n */\n intent?: 'primary' | 'positive' | 'negative';\n /**\n * Size of the modal window\n */\n size?: ModalProps['size'];\n /**\n * Boolean indicating if clicking the overlay should close the overlay.\n */\n shouldCloseOnOverlayClick?: boolean;\n /**\n * Boolean indicating if pressing the esc key should close the overlay.\n */\n shouldCloseOnEscapePress?: boolean;\n /**\n * When true, the confirm button is set to disabled.\n */\n isConfirmDisabled?: boolean;\n /**\n * When true, the confirm button is set to loading.\n */\n isConfirmLoading?: boolean;\n /**\n * Are modals higher than viewport allowed\n */\n allowHeightOverflow?: boolean;\n\n /**\n * Optional props to override ModalHeader behaviour\n */\n modalHeaderProps?: Partial<ModalHeaderProps>;\n\n /**\n * Optional props to override ModalContent behaviour\n */\n modalContentProps?: Partial<ModalContentProps>;\n\n /**\n * Optional props to override ModalControl behaviour\n */\n modalControlsProps?: Partial<ModalControlsProps>;\n\n /**\n * Optional property to set initial focus\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- we don't know the type of element to give initial focus\n initialFocusRef?: React.RefObject<any>;\n\n testId?: string;\n confirmTestId?: string;\n cancelTestId?: string;\n children: React.ReactNode;\n}\n\nexport const ModalConfirm = ({\n allowHeightOverflow = false,\n cancelLabel = 'Cancel',\n cancelTestId = 'cf-ui-modal-confirm-cancel-button',\n children,\n confirmLabel = 'Confirm',\n confirmTestId = 'cf-ui-modal-confirm-confirm-button',\n intent = 'positive',\n isConfirmDisabled = false,\n isConfirmLoading = false,\n isShown,\n modalContentProps,\n modalControlsProps,\n modalHeaderProps,\n onCancel,\n onConfirm,\n shouldCloseOnEscapePress = true,\n shouldCloseOnOverlayClick = true,\n size = 'medium',\n testId = 'cf-ui-modal-confirm',\n title = 'Are you sure?',\n initialFocusRef,\n}: ModalConfirmProps) => {\n const cancelRef = React.useRef(null);\n\n const confirmButton = confirmLabel ? (\n <Button\n testId={confirmTestId}\n isDisabled={isConfirmDisabled}\n isLoading={isConfirmLoading}\n variant={intent}\n size=\"small\"\n onClick={() => onConfirm()}\n >\n {confirmLabel}\n </Button>\n ) : null;\n\n const cancelButton = cancelLabel ? (\n <Button\n testId={cancelTestId}\n variant=\"secondary\"\n onClick={onCancel}\n size=\"small\"\n ref={initialFocusRef || cancelRef}\n >\n {cancelLabel}\n </Button>\n ) : null;\n\n return (\n <Modal\n testId={testId}\n isShown={isShown}\n onClose={onCancel}\n size={size}\n shouldCloseOnOverlayClick={shouldCloseOnOverlayClick}\n shouldCloseOnEscapePress={shouldCloseOnEscapePress}\n allowHeightOverflow={allowHeightOverflow}\n initialFocusRef={cancelRef}\n >\n {() => {\n return (\n <React.Fragment>\n <Modal.Header\n title={title || ''}\n {...modalHeaderProps}\n onClose={onCancel}\n />\n <Modal.Content {...modalContentProps}>{children}</Modal.Content>\n <Modal.Controls {...modalControlsProps}>\n {cancelButton}\n {confirmButton}\n </Modal.Controls>\n </React.Fragment>\n );\n }}\n </Modal>\n );\n};\n\nModalConfirm.displayName = 'ModalConfirm';\n","/* global Promise */\nimport ReactDOM from 'react-dom';\n\n// @todo: change any to unknown\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport interface ModalLauncherComponentRendererProps<T = any> {\n isShown: boolean;\n onClose: (result?: T) => void;\n}\n\nexport interface ModalLauncherOpenOptions {\n /**\n * Unique id to be used as identifier for the modal contianer\n */\n modalId?: string;\n /**\n * ms before removing the component from the tree\n * @default 300\n */\n delay?: number;\n}\n\ninterface CloseModalData {\n delay: number;\n render: (args: ModalLauncherComponentRendererProps<any>) => void;\n currentConfig: ModalLauncherComponentRendererProps<any>;\n}\n\nconst getRoot = (rootElId: string): HTMLElement => {\n // Reuse the container if we find it\n let rootDom = document.getElementById(rootElId);\n if (rootDom !== null) {\n return rootDom;\n }\n\n // Otherwise create it\n rootDom = document.createElement('div');\n rootDom.setAttribute('id', rootElId);\n document.body.appendChild(rootDom);\n return rootDom;\n};\n\nconst openModalsIds: Map<string, CloseModalData> = new Map();\nfunction closeAll() {\n openModalsIds.forEach(async ({ render, currentConfig, delay }, rootElId) => {\n const config = { ...currentConfig, isShown: false };\n render(config);\n await new Promise((resolveDelay) => setTimeout(resolveDelay, delay));\n ReactDOM.unmountComponentAtNode(getRoot(rootElId));\n openModalsIds.delete(rootElId);\n });\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction open<T = any>(\n componentRenderer: (\n props: ModalLauncherComponentRendererProps<T>,\n ) => JSX.Element,\n options: ModalLauncherOpenOptions = {},\n): Promise<T> {\n options = { delay: 300, ...options };\n\n // Allow components to specify if they wish to reuse the modal container\n const rootElId = `modals-root${options.modalId || Date.now()}`;\n const rootDom = getRoot(rootElId);\n\n return new Promise((resolve) => {\n let currentConfig = { onClose, isShown: true };\n\n function render({\n onClose,\n isShown,\n }: ModalLauncherComponentRendererProps<T>) {\n ReactDOM.render(componentRenderer({ onClose, isShown }), rootDom);\n }\n\n async function onClose(arg?: T) {\n currentConfig = {\n ...currentConfig,\n isShown: false,\n };\n render(currentConfig);\n await new Promise((resolveDelay) =>\n setTimeout(resolveDelay, options.delay),\n );\n ReactDOM.unmountComponentAtNode(rootDom);\n rootDom.remove();\n openModalsIds.delete(rootElId);\n resolve(arg);\n }\n\n render(currentConfig);\n openModalsIds.set(rootElId, {\n render,\n currentConfig,\n delay: options.delay,\n });\n });\n}\n\nexport const ModalLauncher = {\n open,\n closeAll,\n};\n"]}
package/dist/index.js CHANGED
@@ -35,7 +35,7 @@ var yo__default = /*#__PURE__*/_interopDefault(yo);
35
35
  var m__default = /*#__PURE__*/_interopDefault(m);
36
36
  var q__default = /*#__PURE__*/_interopDefault(q);
37
37
 
38
- var ro=Object.defineProperty,ao=Object.defineProperties;var lo=Object.getOwnPropertyDescriptors;var E=Object.getOwnPropertySymbols;var Y=Object.prototype.hasOwnProperty,J=Object.prototype.propertyIsEnumerable;var G=(o,e,t)=>e in o?ro(o,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):o[e]=t,l=(o,e)=>{for(var t in e||(e={}))Y.call(e,t)&&G(o,t,e[t]);if(E)for(var t of E(e))J.call(e,t)&&G(o,t,e[t]);return o},u=(o,e)=>ao(o,lo(e));var h=(o,e)=>{var t={};for(var r in o)Y.call(o,r)&&e.indexOf(r)<0&&(t[r]=o[r]);if(o!=null&&E)for(var r of E(o))e.indexOf(r)<0&&J.call(o,r)&&(t[r]=o[r]);return t};var W=(o,e,t)=>new Promise((r,i)=>{var a=n=>{try{d(t.next(n));}catch(M){i(M);}},s=n=>{try{d(t.throw(n));}catch(M){i(M);}},d=n=>n.done?r(n.value):Promise.resolve(n.value).then(a,s);d((t=t.apply(o,e)).next());});function Q(){return {root:emotion.css({position:"relative",padding:`${m__default.default.spacingM} ${m__default.default.spacingM} ${m__default.default.spacingM} ${m__default.default.spacingL}`,borderRadius:`${m__default.default.borderRadiusMedium} ${m__default.default.borderRadiusMedium} 0 0`,borderBottom:`1px solid ${m__default.default.gray300}`}),buttonContainer:emotion.css({position:"relative",width:m__default.default.spacing2Xl,height:m__default.default.spacingL,button:{position:"absolute",top:`calc(-1 * ${m__default.default.spacing2Xs})`,right:0}})}}var H=s=>{var d=s,{onClose:o,title:e,subtitle:t,testId:r="cf-ui-modal-header",className:i}=d,a=h(d,["onClose","title","subtitle","testId","className"]);let n=Q();return x__namespace.default.createElement(f36Core.Flex,u(l({},a),{className:emotion.cx(n.root,i),testId:r,alignItems:"center",justifyContent:"space-between"}),x__namespace.default.createElement(f36Typography.Subheading,{as:"h2",isTruncated:!0,marginBottom:"none"},e,t&&x__namespace.default.createElement(f36Typography.Text,{marginLeft:"spacingXs",fontColor:"gray700"},t)),o&&x__namespace.default.createElement(f36Core.Flex,{alignItems:"center",className:n.buttonContainer},x__namespace.default.createElement(f36Button.Button,{variant:"transparent","aria-label":"Close",startIcon:x__namespace.default.createElement(f36Icons.CloseIcon,{size:"small"}),onClick:()=>{o();},size:"small"})))};H.displayName="ModalHeader";function V(){return {root:emotion.css({padding:`${m__default.default.spacingM} ${m__default.default.spacingL}`,color:m__default.default.gray700,fontSize:m__default.default.fontSizeM,fontFamily:m__default.default.fontStackPrimary,lineHeight:m__default.default.lineHeightM,overflowY:"auto",overflowX:"auto",boxSizing:"border-box"})}}var w=i=>{var a=i,{testId:o="cf-ui-modal-content",className:e,children:t}=a,r=h(a,["testId","className","children"]);let s=V();return x__namespace.default.createElement(f36Core.Box,u(l({},r),{as:"div",className:emotion.cx(s.root,e),testId:o}),t)};w.displayName="ModalContent";function Z(o){let e=emotion.cx(emotion.css({backgroundColor:m__default.default.colorWhite,borderRadius:o.size==="zen"?0:m__default.default.borderRadiusMedium,boxShadow:m__default.default.boxShadowHeavy,maxHeight:`calc(100vh - 1rem * (100 / ${m__default.default.fontBaseDefault}))`,maxWidth:`calc(100vw - 1rem * (100 / ${m__default.default.fontBaseDefault}))`,overflow:"hidden",display:"flex",flexDirection:"column"}),o.allowHeightOverflow?emotion.css({overflow:"auto",maxHeight:"none"}):null,o.size==="zen"?emotion.css({maxWidth:"none",maxHeight:"none",margin:0,height:"100%",width:"100%"}):null,o.size==="fullscreen"?emotion.css({maxWidth:`calc(100vw - ${m__default.default.spacingXl})`,maxHeight:`calc(100vh - ${m__default.default.spacingXl})`,margin:0,height:"100vh",width:"100vw"}):null,o.className);return {portal:emotion.css({display:"block"}),base:{root:emotion.cx(emotion.css({zIndex:m__default.default.zIndexModalContent,position:"relative",padding:0,display:"inline-block",margin:"0 auto",textAlign:"left",outline:"none",transform:o.size==="zen"?"scale(1)":"scale(0.85)",transition:`transform ${m__default.default.transitionDurationDefault} ${m__default.default.transitionEasingDefault}`}),o.size==="zen"?emotion.css({width:"100%",height:"100%"}):null),afterOpen:emotion.css({transform:"scale(1) !important"}),beforeClose:emotion.css({transform:o.size==="zen"?"scale(1)":"scale(0.85) !important"})},modalOverlay:{root:emotion.cx(emotion.css({display:"flex",alignItems:"baseline",flexWrap:"wrap",top:0,right:0,bottom:0,left:0,zIndex:m__default.default.zIndexModal,opacity:0,transition:`opacity ${m__default.default.transitionDurationDefault} ${m__default.default.transitionEasingDefault}`,position:"fixed",overflowY:"auto",backgroundColor:"rgba(12, 20, 28, 0.74902)",textAlign:"center",padding:m__default.default.spacing2Xl}),o.size==="fullscreen"?emotion.css({padding:0}):null,o.position==="center"?emotion.css({alignItems:"center",justifyContent:"center"}):null,o.overlayClassName),afterOpen:emotion.css({opacity:"1 !important"}),beforeClose:emotion.css({opacity:"0 !important"})},modal:e}}var xo={medium:"520px",small:"400px",large:"700px",fullWidth:"100vw",zen:"100vw",fullscreen:"100vw"};function Po(o){if(o&&o.querySelectorAll){let e=o.querySelectorAll("input, button");if(e.length>0){let t=e[0];typeof t.focus=="function"&&t.focus();}}}var j=M=>{var S=M,{allowHeightOverflow:o=!1,position:e="center",shouldCloseOnEscapePress:t=!0,shouldCloseOnOverlayClick:r=!0,size:i="medium",testId:a="cf-ui-modal",topOffset:s="50px",aria:d}=S,n=h(S,["allowHeightOverflow","position","shouldCloseOnEscapePress","shouldCloseOnOverlayClick","size","testId","topOffset","aria"]);var L,T;let z=x__namespace.useRef(null),P=u(l({},n),{allowHeightOverflow:o,position:e,shouldCloseOnEscapePress:t,shouldCloseOnOverlayClick:r,size:i,testId:a,topOffset:s}),c=Z({position:e,size:i,allowHeightOverflow:o,className:n.className,overlayClassName:(L=n.overlayProps)==null?void 0:L.className}),B=()=>{var O,I;let f=z.current;if(f){let N=document.activeElement;if(f!==N&&f.contains(N))return}let b=(O=P.initialFocusRef)==null?void 0:O.current;b?(I=b.focus)==null||I.call(b):f&&Po(f);},k=(...f)=>{P.onAfterOpen&&P.onAfterOpen(...f),B();},F=()=>x__namespace.createElement(x__namespace.Fragment,null,n.title&&x__namespace.createElement(H,l({title:n.title,subtitle:n.subtitle,onClose:P.onClose},n.modalHeaderProps)),x__namespace.createElement(w,l({},n.modalContentProps),n.children));return x__namespace.createElement(yo__default.default,{ariaHideApp:!1,aria:d,onRequestClose:P.onClose,isOpen:n.isShown,onAfterOpen:k,shouldCloseOnEsc:t,shouldCloseOnOverlayClick:r,shouldFocusAfterRender:!0,shouldReturnFocusAfterClose:!0,portalClassName:c.portal,style:{content:{top:e==="center"?0:s},overlay:(T=n.overlayProps)==null?void 0:T.style},className:{base:c.base.root,afterOpen:c.base.afterOpen,beforeClose:c.base.beforeClose},overlayClassName:{base:c.modalOverlay.root,afterOpen:c.modalOverlay.afterOpen,beforeClose:c.modalOverlay.beforeClose},closeTimeoutMS:200,contentRef:f=>{z.current=f;}},x__namespace.createElement(f36Core.Box,{testId:a,style:{width:xo[i]||i},className:c.modal,"data-modal-root":!0},typeof n.children=="function"?n.children(P):F()))};j.displayName="Modal";function _(){return {root:emotion.css({borderBottomLeftRadius:m__default.default.borderRadiusMedium,borderBottomRightRadius:m__default.default.borderRadiusMedium,padding:`${m__default.default.spacingS} ${m__default.default.spacingM}`,width:"100%",boxSizing:"border-box"})}}var $=i=>{var a=i,{testId:o="cf-ui-modal-controls",className:e,children:t}=a,r=h(a,["testId","className","children"]);let s=_();return x__namespace.default.createElement(f36Core.Flex,u(l({},r),{className:emotion.cx(s.root,e),testId:o,flexDirection:"row",justifyContent:"flex-end"}),x__namespace.default.createElement(f36Button.ButtonGroup,{variant:"spaced",spacing:"spacingS"},t))};$.displayName="ModalControls";var g=j;g.Content=w;g.Header=H;g.Controls=$;var to=({allowHeightOverflow:o=!1,cancelLabel:e="Cancel",cancelTestId:t="cf-ui-modal-confirm-cancel-button",children:r,confirmLabel:i="Confirm",confirmTestId:a="cf-ui-modal-confirm-confirm-button",intent:s="positive",isConfirmDisabled:d=!1,isConfirmLoading:n=!1,isShown:M,modalContentProps:S,modalControlsProps:z,modalHeaderProps:P,onCancel:c,onConfirm:B,shouldCloseOnEscapePress:k=!0,shouldCloseOnOverlayClick:F=!0,size:L="medium",testId:T="cf-ui-modal-confirm",title:f="Are you sure?",initialFocusRef:b})=>{let O=x__namespace.default.useRef(null),I=i?x__namespace.default.createElement(f36Button.Button,{testId:a,isDisabled:d,isLoading:n,variant:s,size:"small",onClick:()=>B()},i):null,N=e?x__namespace.default.createElement(f36Button.Button,{testId:t,variant:"secondary",onClick:c,size:"small",ref:b||O},e):null;return x__namespace.default.createElement(g,{testId:T,isShown:M,onClose:c,size:L,shouldCloseOnOverlayClick:F,shouldCloseOnEscapePress:k,allowHeightOverflow:o,initialFocusRef:O},()=>x__namespace.default.createElement(x__namespace.default.Fragment,null,x__namespace.default.createElement(g.Header,l({title:f||""},P)),x__namespace.default.createElement(g.Content,l({},S),r),x__namespace.default.createElement(g.Controls,l({},z),N,I)))};to.displayName="ModalConfirm";var no=o=>{let e=document.getElementById(o);return e!==null||(e=document.createElement("div"),e.setAttribute("id",o),document.body.appendChild(e)),e},D=new Map;function Ro(){D.forEach((i,a)=>W(this,[i,a],function*({render:o,currentConfig:e,delay:t},r){let s=u(l({},e),{isShown:!1});o(s),yield new Promise(d=>setTimeout(d,t)),q__default.default.unmountComponentAtNode(no(r)),D.delete(r);}));}function wo(o,e={}){e=l({delay:300},e);let t=`modals-root${e.modalId||Date.now()}`,r=no(t);return new Promise(i=>{let a={onClose:d,isShown:!0};function s({onClose:n,isShown:M}){q__default.default.render(o({onClose:n,isShown:M}),r);}function d(n){return W(this,null,function*(){a=u(l({},a),{isShown:!1}),s(a),yield new Promise(M=>setTimeout(M,e.delay)),q__default.default.unmountComponentAtNode(r),r.remove(),D.delete(t),i(n);})}s(a),D.set(t,{render:s,currentConfig:a,delay:e.delay});})}var Oo={open:wo,closeAll:Ro};
38
+ var ro=Object.defineProperty,ao=Object.defineProperties;var lo=Object.getOwnPropertyDescriptors;var E=Object.getOwnPropertySymbols;var Y=Object.prototype.hasOwnProperty,J=Object.prototype.propertyIsEnumerable;var G=(o,e,t)=>e in o?ro(o,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):o[e]=t,l=(o,e)=>{for(var t in e||(e={}))Y.call(e,t)&&G(o,t,e[t]);if(E)for(var t of E(e))J.call(e,t)&&G(o,t,e[t]);return o},c=(o,e)=>ao(o,lo(e));var h=(o,e)=>{var t={};for(var r in o)Y.call(o,r)&&e.indexOf(r)<0&&(t[r]=o[r]);if(o!=null&&E)for(var r of E(o))e.indexOf(r)<0&&J.call(o,r)&&(t[r]=o[r]);return t};var W=(o,e,t)=>new Promise((r,i)=>{var a=n=>{try{d(t.next(n));}catch(M){i(M);}},s=n=>{try{d(t.throw(n));}catch(M){i(M);}},d=n=>n.done?r(n.value):Promise.resolve(n.value).then(a,s);d((t=t.apply(o,e)).next());});function Q(){return {root:emotion.css({position:"relative",padding:`${m__default.default.spacingM} ${m__default.default.spacingM} ${m__default.default.spacingM} ${m__default.default.spacingL}`,borderRadius:`${m__default.default.borderRadiusMedium} ${m__default.default.borderRadiusMedium} 0 0`,borderBottom:`1px solid ${m__default.default.gray300}`}),buttonContainer:emotion.css({position:"relative",width:m__default.default.spacing2Xl,height:m__default.default.spacingL,button:{position:"absolute",top:`calc(-1 * ${m__default.default.spacing2Xs})`,right:0}})}}var H=s=>{var d=s,{onClose:o,title:e,subtitle:t,testId:r="cf-ui-modal-header",className:i}=d,a=h(d,["onClose","title","subtitle","testId","className"]);let n=Q();return x__namespace.default.createElement(f36Core.Flex,c(l({},a),{className:emotion.cx(n.root,i),testId:r,alignItems:"center",justifyContent:"space-between"}),x__namespace.default.createElement(f36Typography.Subheading,{as:"h2",isTruncated:!0,marginBottom:"none"},e,t&&x__namespace.default.createElement(f36Typography.Text,{marginLeft:"spacingXs",fontColor:"gray700"},t)),o&&x__namespace.default.createElement(f36Core.Flex,{alignItems:"center",className:n.buttonContainer},x__namespace.default.createElement(f36Button.IconButton,{variant:"transparent","aria-label":"Close",size:"small",icon:x__namespace.default.createElement(f36Icons.CloseIcon,{size:"small"}),onClick:()=>{o();}})))};H.displayName="ModalHeader";function V(){return {root:emotion.css({padding:`${m__default.default.spacingM} ${m__default.default.spacingL}`,color:m__default.default.gray700,fontSize:m__default.default.fontSizeM,fontFamily:m__default.default.fontStackPrimary,lineHeight:m__default.default.lineHeightM,overflowY:"auto",overflowX:"auto",boxSizing:"border-box"})}}var w=i=>{var a=i,{testId:o="cf-ui-modal-content",className:e,children:t}=a,r=h(a,["testId","className","children"]);let s=V();return x__namespace.default.createElement(f36Core.Box,c(l({},r),{as:"div",className:emotion.cx(s.root,e),testId:o}),t)};w.displayName="ModalContent";function Z(o){let e=emotion.cx(emotion.css({backgroundColor:m__default.default.colorWhite,borderRadius:o.size==="zen"?0:m__default.default.borderRadiusMedium,boxShadow:m__default.default.boxShadowHeavy,maxHeight:`calc(100vh - 1rem * (100 / ${m__default.default.fontBaseDefault}))`,maxWidth:`calc(100vw - 1rem * (100 / ${m__default.default.fontBaseDefault}))`,overflow:"hidden",display:"flex",flexDirection:"column"}),o.allowHeightOverflow?emotion.css({overflow:"auto",maxHeight:"none"}):null,o.size==="zen"?emotion.css({maxWidth:"none",maxHeight:"none",margin:0,height:"100%",width:"100%"}):null,o.size==="fullscreen"?emotion.css({maxWidth:`calc(100vw - ${m__default.default.spacingXl})`,maxHeight:`calc(100vh - ${m__default.default.spacingXl})`,margin:0,height:"100vh",width:"100vw"}):null,o.className);return {portal:emotion.css({display:"block"}),base:{root:emotion.cx(emotion.css({zIndex:m__default.default.zIndexModalContent,position:"relative",padding:0,display:"inline-block",margin:"0 auto",textAlign:"left",outline:"none",transform:o.size==="zen"?"scale(1)":"scale(0.85)",transition:`transform ${m__default.default.transitionDurationDefault} ${m__default.default.transitionEasingDefault}`}),o.size==="zen"?emotion.css({width:"100%",height:"100%"}):null),afterOpen:emotion.css({transform:"scale(1) !important"}),beforeClose:emotion.css({transform:o.size==="zen"?"scale(1)":"scale(0.85) !important"})},modalOverlay:{root:emotion.cx(emotion.css({display:"flex",alignItems:"baseline",flexWrap:"wrap",top:0,right:0,bottom:0,left:0,zIndex:m__default.default.zIndexModal,opacity:0,transition:`opacity ${m__default.default.transitionDurationDefault} ${m__default.default.transitionEasingDefault}`,position:"fixed",overflowY:"auto",backgroundColor:"rgba(12, 20, 28, 0.74902)",textAlign:"center",padding:m__default.default.spacing2Xl}),o.size==="fullscreen"?emotion.css({padding:0}):null,o.position==="center"?emotion.css({alignItems:"center",justifyContent:"center"}):null,o.overlayClassName),afterOpen:emotion.css({opacity:"1 !important"}),beforeClose:emotion.css({opacity:"0 !important"})},modal:e}}var xo={medium:"520px",small:"400px",large:"700px",fullWidth:"100vw",zen:"100vw",fullscreen:"100vw"};function Po(o){if(o&&o.querySelectorAll){let e=o.querySelectorAll("input, button");if(e.length>0){let t=e[0];typeof t.focus=="function"&&t.focus();}}}var j=M=>{var S=M,{allowHeightOverflow:o=!1,position:e="center",shouldCloseOnEscapePress:t=!0,shouldCloseOnOverlayClick:r=!0,size:i="medium",testId:a="cf-ui-modal",topOffset:s="50px",aria:d}=S,n=h(S,["allowHeightOverflow","position","shouldCloseOnEscapePress","shouldCloseOnOverlayClick","size","testId","topOffset","aria"]);var L,T;let z=x__namespace.useRef(null),P=c(l({},n),{allowHeightOverflow:o,position:e,shouldCloseOnEscapePress:t,shouldCloseOnOverlayClick:r,size:i,testId:a,topOffset:s}),f=Z({position:e,size:i,allowHeightOverflow:o,className:n.className,overlayClassName:(L=n.overlayProps)==null?void 0:L.className}),B=()=>{var O,I;let u=z.current;if(u){let N=document.activeElement;if(u!==N&&u.contains(N))return}let b=(O=P.initialFocusRef)==null?void 0:O.current;b?(I=b.focus)==null||I.call(b):u&&Po(u);},k=(...u)=>{P.onAfterOpen&&P.onAfterOpen(...u),B();},F=()=>x__namespace.createElement(x__namespace.Fragment,null,n.title&&x__namespace.createElement(H,l({title:n.title,subtitle:n.subtitle,onClose:P.onClose},n.modalHeaderProps)),x__namespace.createElement(w,l({},n.modalContentProps),n.children));return x__namespace.createElement(yo__default.default,{ariaHideApp:!1,aria:d,onRequestClose:P.onClose,isOpen:n.isShown,onAfterOpen:k,shouldCloseOnEsc:t,shouldCloseOnOverlayClick:r,shouldFocusAfterRender:!0,shouldReturnFocusAfterClose:!0,portalClassName:f.portal,style:{content:{top:e==="center"?0:s},overlay:(T=n.overlayProps)==null?void 0:T.style},className:{base:f.base.root,afterOpen:f.base.afterOpen,beforeClose:f.base.beforeClose},overlayClassName:{base:f.modalOverlay.root,afterOpen:f.modalOverlay.afterOpen,beforeClose:f.modalOverlay.beforeClose},closeTimeoutMS:200,contentRef:u=>{z.current=u;}},x__namespace.createElement(f36Core.Box,{testId:a,style:{width:xo[i]||i},className:f.modal,"data-modal-root":!0},typeof n.children=="function"?n.children(P):F()))};j.displayName="Modal";function _(){return {root:emotion.css({borderBottomLeftRadius:m__default.default.borderRadiusMedium,borderBottomRightRadius:m__default.default.borderRadiusMedium,padding:`${m__default.default.spacingS} ${m__default.default.spacingM}`,width:"100%",boxSizing:"border-box"})}}var $=i=>{var a=i,{testId:o="cf-ui-modal-controls",className:e,children:t}=a,r=h(a,["testId","className","children"]);let s=_();return x__namespace.default.createElement(f36Core.Flex,c(l({},r),{className:emotion.cx(s.root,e),testId:o,flexDirection:"row",justifyContent:"flex-end"}),x__namespace.default.createElement(f36Button.ButtonGroup,{variant:"spaced",spacing:"spacingS"},t))};$.displayName="ModalControls";var g=j;g.Content=w;g.Header=H;g.Controls=$;var to=({allowHeightOverflow:o=!1,cancelLabel:e="Cancel",cancelTestId:t="cf-ui-modal-confirm-cancel-button",children:r,confirmLabel:i="Confirm",confirmTestId:a="cf-ui-modal-confirm-confirm-button",intent:s="positive",isConfirmDisabled:d=!1,isConfirmLoading:n=!1,isShown:M,modalContentProps:S,modalControlsProps:z,modalHeaderProps:P,onCancel:f,onConfirm:B,shouldCloseOnEscapePress:k=!0,shouldCloseOnOverlayClick:F=!0,size:L="medium",testId:T="cf-ui-modal-confirm",title:u="Are you sure?",initialFocusRef:b})=>{let O=x__namespace.default.useRef(null),I=i?x__namespace.default.createElement(f36Button.Button,{testId:a,isDisabled:d,isLoading:n,variant:s,size:"small",onClick:()=>B()},i):null,N=e?x__namespace.default.createElement(f36Button.Button,{testId:t,variant:"secondary",onClick:f,size:"small",ref:b||O},e):null;return x__namespace.default.createElement(g,{testId:T,isShown:M,onClose:f,size:L,shouldCloseOnOverlayClick:F,shouldCloseOnEscapePress:k,allowHeightOverflow:o,initialFocusRef:O},()=>x__namespace.default.createElement(x__namespace.default.Fragment,null,x__namespace.default.createElement(g.Header,c(l({title:u||""},P),{onClose:f})),x__namespace.default.createElement(g.Content,l({},S),r),x__namespace.default.createElement(g.Controls,l({},z),N,I)))};to.displayName="ModalConfirm";var no=o=>{let e=document.getElementById(o);return e!==null||(e=document.createElement("div"),e.setAttribute("id",o),document.body.appendChild(e)),e},D=new Map;function Ro(){D.forEach((i,a)=>W(this,[i,a],function*({render:o,currentConfig:e,delay:t},r){let s=c(l({},e),{isShown:!1});o(s),yield new Promise(d=>setTimeout(d,t)),q__default.default.unmountComponentAtNode(no(r)),D.delete(r);}));}function wo(o,e={}){e=l({delay:300},e);let t=`modals-root${e.modalId||Date.now()}`,r=no(t);return new Promise(i=>{let a={onClose:d,isShown:!0};function s({onClose:n,isShown:M}){q__default.default.render(o({onClose:n,isShown:M}),r);}function d(n){return W(this,null,function*(){a=c(l({},a),{isShown:!1}),s(a),yield new Promise(M=>setTimeout(M,e.delay)),q__default.default.unmountComponentAtNode(r),r.remove(),D.delete(t),i(n);})}s(a),D.set(t,{render:s,currentConfig:a,delay:e.delay});})}var Oo={open:wo,closeAll:Ro};
39
39
 
40
40
  exports.Modal = g;
41
41
  exports.ModalConfirm = to;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/Modal.tsx","../src/ModalHeader/ModalHeader.tsx","../src/ModalHeader/ModalHeader.styles.ts","../src/ModalContent/ModalContent.tsx","../src/ModalContent/ModalContent.styles.ts","../src/Modal.styles.ts","../src/ModalControls/ModalControls.tsx","../src/ModalControls/ModalControls.styles.tsx","../src/CompoundModal.tsx","../src/ModalConfirm/ModalConfirm.tsx","../src/ModalLauncher/ModalLauncher.tsx"],"names":["React","ReactModal","Box","cx","CloseIcon","Flex","Button","Text","Subheading","tokens","css","getModalHeaderStyles","ModalHeader","_a","_b","onClose","title","subtitle","testId","className","otherProps","__objRest","styles","__spreadProps","__spreadValues","getModalContentStyles","ModalContent","children","getModalStyles","props","modal","ModalSizesMapper","focusFirstWithinNode","node","elements","firstElement","Modal","allowHeightOverflow","position","shouldCloseOnEscapePress","shouldCloseOnOverlayClick","size","topOffset","aria","contentRef","onInitialFocus","contentEl","activeEl","initialFocusEl","onAfterOpen","args","renderDefault","ref","ButtonGroup","getModalControlStyles","ModalControls","ModalConfirm","cancelLabel","cancelTestId","confirmLabel","confirmTestId","intent","isConfirmDisabled","isConfirmLoading","isShown","modalContentProps","modalControlsProps","modalHeaderProps","onCancel","onConfirm","initialFocusRef","cancelRef","confirmButton","cancelButton","ReactDOM","getRoot","rootElId","rootDom","openModalsIds","closeAll","_0","_1","__async","render","currentConfig","delay","config","resolveDelay","open","componentRenderer","options","resolve","arg","ModalLauncher"],"mappings":"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","sourcesContent":["import * as React from 'react';\nimport ReactModal from 'react-modal';\n\nimport { Box, type CommonProps, type ExpandProps } from '@contentful/f36-core';\n\nimport { ModalHeader, ModalHeaderProps } from './ModalHeader/ModalHeader';\nimport { ModalContent, ModalContentProps } from './ModalContent/ModalContent';\nimport { getModalStyles } from './Modal.styles';\nimport type { ModalSizeType, ModalPositionType } from './types';\n\nconst ModalSizesMapper: { [key in ModalSizeType]: string } = {\n medium: '520px',\n small: '400px',\n large: '700px',\n fullWidth: '100vw',\n zen: '100vw',\n fullscreen: '100vw',\n};\n\nexport interface ModalProps extends CommonProps {\n /**\n * When true, the dialog is shown.\n */\n isShown: boolean;\n\n /**\n * Function that will be run when the modal is requested to be closed, prior to actually closing.\n */\n onClose: ReactModal.Props['onRequestClose'];\n\n /**\n * Function that will be run after the modal has opened.\n */\n onAfterOpen?: ReactModal.Props['onAfterOpen'];\n\n /**\n * Additional aria attributes\n */\n aria?: ReactModal.Props['aria'];\n\n /**\n * Boolean indicating if clicking the overlay should close the overlay.\n * @default true\n */\n shouldCloseOnOverlayClick?: boolean;\n /**\n * Boolean indicating if pressing the esc key should close the overlay.\n * @default true\n */\n shouldCloseOnEscapePress?: boolean;\n /**\n * Indicating if modal is centered or linked to the top\n * @default center\n */\n position?: ModalPositionType;\n /**\n * Top offset if position is 'top'\n * @default 50px\n */\n topOffset?: number | string;\n /**\n * Modal title that is used in header\n */\n title?: string;\n /**\n * Modal subtitle that is used in header\n */\n subtitle?: string;\n /**\n * Size of the modal window\n * @default medium\n */\n size?: ModalSizeType | string | number;\n /**\n * Are modals higher than viewport allowed\n * @default false\n */\n allowHeightOverflow?: boolean;\n\n /**\n * Optional props to override overlay behaviour\n */\n overlayProps?: Pick<CommonProps, 'className' | 'style'>;\n\n /**\n * Optional props to override ModalHeader behaviour\n */\n modalHeaderProps?: Partial<ModalHeaderProps>;\n\n /**\n * Optional props to override ModalContent behaviour\n */\n modalContentProps?: Partial<ModalContentProps>;\n\n /**\n * Optional property to set initial focus\n */\n initialFocusRef?: React.RefObject<HTMLElement>;\n\n children: React.ReactNode | RenderModal;\n}\n\ntype RenderModal = (modalProps: ModalProps) => React.ReactNode;\n\nfunction focusFirstWithinNode(node: HTMLElement) {\n if (node && node.querySelectorAll) {\n const elements = node.querySelectorAll('input, button');\n if (elements.length > 0) {\n const firstElement = elements[0];\n // @ts-expect-error focus might be missing\n if (typeof firstElement.focus === 'function') {\n // @ts-expect-error focus might be missing\n firstElement.focus();\n }\n }\n }\n}\n\nexport const Modal = ({\n allowHeightOverflow = false,\n position = 'center',\n shouldCloseOnEscapePress = true,\n shouldCloseOnOverlayClick = true,\n size = 'medium',\n testId = 'cf-ui-modal',\n topOffset = '50px',\n aria,\n ...otherProps\n}: ExpandProps<ModalProps>) => {\n const contentRef = React.useRef<HTMLDivElement>(null);\n\n const props = {\n ...otherProps,\n allowHeightOverflow,\n position,\n shouldCloseOnEscapePress,\n shouldCloseOnOverlayClick,\n size,\n testId,\n topOffset,\n };\n\n const styles = getModalStyles({\n position,\n size,\n allowHeightOverflow,\n className: otherProps.className,\n overlayClassName: otherProps.overlayProps?.className,\n });\n\n const onInitialFocus = () => {\n const contentEl = contentRef.current;\n if (contentEl) {\n const activeEl = document.activeElement;\n const isContentContainsActive =\n contentEl !== activeEl && contentEl.contains(activeEl);\n\n if (isContentContainsActive) {\n return;\n }\n }\n\n const initialFocusEl = props.initialFocusRef?.current;\n if (initialFocusEl) {\n initialFocusEl.focus?.();\n } else if (contentEl) {\n focusFirstWithinNode(contentEl);\n }\n };\n\n const onAfterOpen: ModalProps['onAfterOpen'] = (...args) => {\n if (props.onAfterOpen) {\n props.onAfterOpen(...args);\n }\n onInitialFocus();\n };\n\n const renderDefault = () => {\n return (\n <>\n {otherProps.title && (\n <ModalHeader\n title={otherProps.title}\n subtitle={otherProps.subtitle}\n onClose={props.onClose}\n {...otherProps.modalHeaderProps}\n />\n )}\n <ModalContent {...otherProps.modalContentProps}>\n {otherProps.children}\n </ModalContent>\n </>\n );\n };\n\n return (\n <ReactModal\n ariaHideApp={false}\n aria={aria}\n onRequestClose={props.onClose}\n isOpen={otherProps.isShown}\n onAfterOpen={onAfterOpen}\n shouldCloseOnEsc={shouldCloseOnEscapePress}\n shouldCloseOnOverlayClick={shouldCloseOnOverlayClick}\n shouldFocusAfterRender\n shouldReturnFocusAfterClose\n portalClassName={styles.portal}\n style={{\n content: {\n top: position === 'center' ? 0 : topOffset,\n },\n overlay: otherProps.overlayProps?.style,\n }}\n className={{\n base: styles.base.root,\n afterOpen: styles.base.afterOpen,\n beforeClose: styles.base.beforeClose,\n }}\n overlayClassName={{\n base: styles.modalOverlay.root,\n afterOpen: styles.modalOverlay.afterOpen,\n beforeClose: styles.modalOverlay.beforeClose,\n }}\n closeTimeoutMS={200}\n contentRef={(ref) => {\n contentRef.current = ref;\n }}\n >\n <Box\n testId={testId}\n style={{\n width: ModalSizesMapper[size] || size,\n }}\n className={styles.modal}\n data-modal-root\n >\n {typeof otherProps.children === 'function'\n ? otherProps.children(props)\n : renderDefault()}\n </Box>\n </ReactModal>\n );\n};\n\nModal.displayName = 'Modal';\n","import React from 'react';\nimport { cx } from 'emotion';\nimport { CloseIcon } from '@contentful/f36-icons';\nimport {\n Flex,\n type PropsWithHTMLElement,\n type CommonProps,\n} from '@contentful/f36-core';\nimport { Button } from '@contentful/f36-button';\nimport { Text, Subheading } from '@contentful/f36-typography';\n\nimport { getModalHeaderStyles } from './ModalHeader.styles';\n\ninterface ModalHeaderInternalProps extends CommonProps {\n title: string;\n subtitle?: string;\n onClose?: Function;\n}\n\nexport type ModalHeaderProps = PropsWithHTMLElement<\n ModalHeaderInternalProps,\n 'div'\n>;\n\nexport const ModalHeader = ({\n onClose,\n title,\n subtitle,\n testId = 'cf-ui-modal-header',\n className,\n ...otherProps\n}: ModalHeaderProps): React.ReactElement => {\n const styles = getModalHeaderStyles();\n\n return (\n <Flex\n {...otherProps}\n className={cx(styles.root, className)}\n testId={testId}\n alignItems=\"center\"\n justifyContent=\"space-between\"\n >\n <Subheading as=\"h2\" isTruncated marginBottom=\"none\">\n {title}\n {subtitle && (\n <Text marginLeft=\"spacingXs\" fontColor=\"gray700\">\n {subtitle}\n </Text>\n )}\n </Subheading>\n {onClose && (\n <Flex alignItems=\"center\" className={styles.buttonContainer}>\n <Button\n variant=\"transparent\"\n aria-label=\"Close\"\n startIcon={<CloseIcon size=\"small\" />}\n onClick={() => {\n onClose();\n }}\n size=\"small\"\n />\n </Flex>\n )}\n </Flex>\n );\n};\n\nModalHeader.displayName = 'ModalHeader';\n","import tokens from '@contentful/f36-tokens';\nimport { css } from 'emotion';\n\nexport function getModalHeaderStyles() {\n return {\n root: css({\n position: 'relative',\n padding: `${tokens.spacingM} ${tokens.spacingM} ${tokens.spacingM} ${tokens.spacingL}`,\n borderRadius: `${tokens.borderRadiusMedium} ${tokens.borderRadiusMedium} 0 0`,\n borderBottom: `1px solid ${tokens.gray300}`,\n }),\n buttonContainer: css({\n position: 'relative',\n width: tokens.spacing2Xl,\n height: tokens.spacingL,\n button: {\n position: 'absolute',\n top: `calc(-1 * ${tokens.spacing2Xs})`,\n right: 0,\n },\n }),\n };\n}\n","import React from 'react';\nimport { cx } from 'emotion';\nimport {\n Box,\n type PropsWithHTMLElement,\n type CommonProps,\n} from '@contentful/f36-core';\nimport { getModalContentStyles } from './ModalContent.styles';\n\ninterface ModalContentInternalProps extends CommonProps {\n children: React.ReactNode;\n}\n\nexport type ModalContentProps = PropsWithHTMLElement<\n ModalContentInternalProps,\n 'div'\n>;\n\nexport const ModalContent = ({\n testId = 'cf-ui-modal-content',\n className,\n children,\n ...otherProps\n}: ModalContentProps) => {\n const styles = getModalContentStyles();\n return (\n <Box\n {...otherProps}\n as=\"div\"\n className={cx(styles.root, className)}\n testId={testId}\n >\n {children}\n </Box>\n );\n};\n\nModalContent.displayName = 'ModalContent';\n","import { css } from 'emotion';\nimport tokens from '@contentful/f36-tokens';\n\nexport function getModalContentStyles() {\n return {\n root: css({\n padding: `${tokens.spacingM} ${tokens.spacingL}`,\n color: tokens.gray700,\n fontSize: tokens.fontSizeM,\n fontFamily: tokens.fontStackPrimary,\n lineHeight: tokens.lineHeightM,\n overflowY: 'auto',\n overflowX: 'auto',\n boxSizing: 'border-box',\n }),\n };\n}\n","import tokens from '@contentful/f36-tokens';\nimport { css, cx } from 'emotion';\n\nimport type { ModalProps } from './Modal';\n\nexport function getModalStyles(props: {\n size: ModalProps['size'];\n position: ModalProps['position'];\n allowHeightOverflow?: boolean;\n className?: string;\n overlayClassName?: string;\n}) {\n const modal = cx(\n css({\n backgroundColor: tokens.colorWhite,\n borderRadius: props.size === 'zen' ? 0 : tokens.borderRadiusMedium,\n boxShadow: tokens.boxShadowHeavy,\n maxHeight: `calc(100vh - 1rem * (100 / ${tokens.fontBaseDefault}))`,\n maxWidth: `calc(100vw - 1rem * (100 / ${tokens.fontBaseDefault}))`,\n overflow: 'hidden',\n display: 'flex',\n flexDirection: 'column',\n }),\n props.allowHeightOverflow\n ? css({\n overflow: 'auto',\n maxHeight: 'none',\n })\n : null,\n props.size === 'zen'\n ? css({\n maxWidth: 'none',\n maxHeight: 'none',\n margin: 0,\n height: '100%',\n width: '100%',\n })\n : null,\n props.size === 'fullscreen'\n ? css({\n maxWidth: `calc(100vw - ${tokens.spacingXl})`,\n maxHeight: `calc(100vh - ${tokens.spacingXl})`,\n margin: 0,\n height: '100vh',\n width: '100vw',\n })\n : null,\n props.className,\n );\n\n return {\n portal: css({\n display: 'block',\n }),\n base: {\n root: cx(\n css({\n zIndex: tokens.zIndexModalContent,\n position: 'relative',\n padding: 0,\n display: 'inline-block',\n margin: '0 auto',\n textAlign: 'left',\n outline: 'none',\n transform: props.size === 'zen' ? 'scale(1)' : 'scale(0.85)',\n transition: `transform ${tokens.transitionDurationDefault} ${tokens.transitionEasingDefault}`,\n }),\n props.size === 'zen'\n ? css({\n width: '100%',\n height: '100%',\n })\n : null,\n ),\n afterOpen: css({\n transform: 'scale(1) !important',\n }),\n beforeClose: css({\n transform: props.size === 'zen' ? 'scale(1)' : 'scale(0.85) !important',\n }),\n },\n modalOverlay: {\n root: cx(\n css({\n display: 'flex',\n alignItems: 'baseline',\n flexWrap: 'wrap',\n top: 0,\n right: 0,\n bottom: 0,\n left: 0,\n zIndex: tokens.zIndexModal,\n opacity: 0,\n transition: `opacity ${tokens.transitionDurationDefault} ${tokens.transitionEasingDefault}`,\n position: 'fixed',\n overflowY: 'auto',\n backgroundColor: 'rgba(12, 20, 28, 0.74902)',\n textAlign: 'center',\n padding: tokens.spacing2Xl,\n }),\n props.size === 'fullscreen'\n ? css({\n padding: 0,\n })\n : null,\n props.position === 'center'\n ? css({\n alignItems: 'center',\n justifyContent: 'center',\n })\n : null,\n props.overlayClassName,\n ),\n afterOpen: css({\n opacity: '1 !important',\n }),\n beforeClose: css({\n opacity: '0 !important',\n }),\n },\n modal,\n };\n}\n","import React from 'react';\n\nimport {\n Flex,\n type PropsWithHTMLElement,\n type CommonProps,\n} from '@contentful/f36-core';\nimport { ButtonGroup } from '@contentful/f36-button';\nimport { getModalControlStyles } from './ModalControls.styles';\nimport { cx } from 'emotion';\n\ninterface ModalControlsInternalProps extends CommonProps {\n children: React.ReactElement[] | React.ReactElement;\n}\n\nexport type ModalControlsProps = PropsWithHTMLElement<\n ModalControlsInternalProps,\n 'div'\n>;\n\nexport const ModalControls = ({\n testId = 'cf-ui-modal-controls',\n className,\n children,\n ...otherProps\n}: ModalControlsProps): React.ReactElement => {\n const styles = getModalControlStyles();\n\n return (\n <Flex\n {...otherProps}\n className={cx(styles.root, className)}\n testId={testId}\n flexDirection=\"row\"\n justifyContent=\"flex-end\"\n >\n <ButtonGroup variant=\"spaced\" spacing=\"spacingS\">\n {children}\n </ButtonGroup>\n </Flex>\n );\n};\n\nModalControls.displayName = 'ModalControls';\n","import { css } from 'emotion';\nimport tokens from '@contentful/f36-tokens';\n\nexport function getModalControlStyles() {\n return {\n root: css({\n borderBottomLeftRadius: tokens.borderRadiusMedium,\n borderBottomRightRadius: tokens.borderRadiusMedium,\n padding: `${tokens.spacingS} ${tokens.spacingM}`,\n width: `100%`,\n // This is required in places where it is not set globally (e.g. dialogs via the app framework)\n boxSizing: 'border-box',\n }),\n };\n}\n","import { Modal as OriginalModal } from './Modal';\nimport { ModalContent } from './ModalContent/ModalContent';\nimport { ModalHeader } from './ModalHeader/ModalHeader';\nimport { ModalControls } from './ModalControls/ModalControls';\n\ntype CompoundModal = typeof OriginalModal & {\n Content: typeof ModalContent;\n Header: typeof ModalHeader;\n Controls: typeof ModalControls;\n};\n\nexport const Modal = OriginalModal as CompoundModal;\nModal.Content = ModalContent;\nModal.Header = ModalHeader;\nModal.Controls = ModalControls;\n","import React from 'react';\n\nimport { Modal } from '../CompoundModal';\nimport type { ModalProps } from '../Modal';\nimport type { ModalHeaderProps } from '../ModalHeader/ModalHeader';\nimport type { ModalContentProps } from '../ModalContent/ModalContent';\nimport type { ModalControlsProps } from '../ModalControls/ModalControls';\nimport { Button } from '@contentful/f36-button';\n\nexport interface ModalConfirmProps {\n /**\n * When true, the dialog is shown.\n */\n isShown: boolean;\n /**\n * Function that will be called when the confirm button is clicked. This does not close the ModalConfirm.\n */\n onConfirm(): void;\n /**\n * Function that will be called when the cancel button is clicked. This does not close the ModalConfirm.\n */\n onCancel: ModalProps['onClose'];\n /**\n Modal title that is used in header\n */\n title?: string;\n /**\n * Label of the confirm button\n */\n confirmLabel?: string | false;\n /**\n * Label of the cancel button\n */\n cancelLabel?: string | false;\n /**\n * The intent of the ModalConfirm. Used for the Button.\n */\n intent?: 'primary' | 'positive' | 'negative';\n /**\n * Size of the modal window\n */\n size?: ModalProps['size'];\n /**\n * Boolean indicating if clicking the overlay should close the overlay.\n */\n shouldCloseOnOverlayClick?: boolean;\n /**\n * Boolean indicating if pressing the esc key should close the overlay.\n */\n shouldCloseOnEscapePress?: boolean;\n /**\n * When true, the confirm button is set to disabled.\n */\n isConfirmDisabled?: boolean;\n /**\n * When true, the confirm button is set to loading.\n */\n isConfirmLoading?: boolean;\n /**\n * Are modals higher than viewport allowed\n */\n allowHeightOverflow?: boolean;\n\n /**\n * Optional props to override ModalHeader behaviour\n */\n modalHeaderProps?: Partial<ModalHeaderProps>;\n\n /**\n * Optional props to override ModalContent behaviour\n */\n modalContentProps?: Partial<ModalContentProps>;\n\n /**\n * Optional props to override ModalControl behaviour\n */\n modalControlsProps?: Partial<ModalControlsProps>;\n\n /**\n * Optional property to set initial focus\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- we don't know the type of element to give initial focus\n initialFocusRef?: React.RefObject<any>;\n\n testId?: string;\n confirmTestId?: string;\n cancelTestId?: string;\n children: React.ReactNode;\n}\n\nexport const ModalConfirm = ({\n allowHeightOverflow = false,\n cancelLabel = 'Cancel',\n cancelTestId = 'cf-ui-modal-confirm-cancel-button',\n children,\n confirmLabel = 'Confirm',\n confirmTestId = 'cf-ui-modal-confirm-confirm-button',\n intent = 'positive',\n isConfirmDisabled = false,\n isConfirmLoading = false,\n isShown,\n modalContentProps,\n modalControlsProps,\n modalHeaderProps,\n onCancel,\n onConfirm,\n shouldCloseOnEscapePress = true,\n shouldCloseOnOverlayClick = true,\n size = 'medium',\n testId = 'cf-ui-modal-confirm',\n title = 'Are you sure?',\n initialFocusRef,\n}: ModalConfirmProps) => {\n const cancelRef = React.useRef(null);\n\n const confirmButton = confirmLabel ? (\n <Button\n testId={confirmTestId}\n isDisabled={isConfirmDisabled}\n isLoading={isConfirmLoading}\n variant={intent}\n size=\"small\"\n onClick={() => onConfirm()}\n >\n {confirmLabel}\n </Button>\n ) : null;\n\n const cancelButton = cancelLabel ? (\n <Button\n testId={cancelTestId}\n variant=\"secondary\"\n onClick={onCancel}\n size=\"small\"\n ref={initialFocusRef || cancelRef}\n >\n {cancelLabel}\n </Button>\n ) : null;\n\n return (\n <Modal\n testId={testId}\n isShown={isShown}\n onClose={onCancel}\n size={size}\n shouldCloseOnOverlayClick={shouldCloseOnOverlayClick}\n shouldCloseOnEscapePress={shouldCloseOnEscapePress}\n allowHeightOverflow={allowHeightOverflow}\n initialFocusRef={cancelRef}\n >\n {() => {\n return (\n <React.Fragment>\n <Modal.Header title={title || ''} {...modalHeaderProps} />\n <Modal.Content {...modalContentProps}>{children}</Modal.Content>\n <Modal.Controls {...modalControlsProps}>\n {cancelButton}\n {confirmButton}\n </Modal.Controls>\n </React.Fragment>\n );\n }}\n </Modal>\n );\n};\n\nModalConfirm.displayName = 'ModalConfirm';\n","/* global Promise */\nimport ReactDOM from 'react-dom';\n\n// @todo: change any to unknown\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport interface ModalLauncherComponentRendererProps<T = any> {\n isShown: boolean;\n onClose: (result?: T) => void;\n}\n\nexport interface ModalLauncherOpenOptions {\n /**\n * Unique id to be used as identifier for the modal contianer\n */\n modalId?: string;\n /**\n * ms before removing the component from the tree\n * @default 300\n */\n delay?: number;\n}\n\ninterface CloseModalData {\n delay: number;\n render: (args: ModalLauncherComponentRendererProps<any>) => void;\n currentConfig: ModalLauncherComponentRendererProps<any>;\n}\n\nconst getRoot = (rootElId: string): HTMLElement => {\n // Reuse the container if we find it\n let rootDom = document.getElementById(rootElId);\n if (rootDom !== null) {\n return rootDom;\n }\n\n // Otherwise create it\n rootDom = document.createElement('div');\n rootDom.setAttribute('id', rootElId);\n document.body.appendChild(rootDom);\n return rootDom;\n};\n\nconst openModalsIds: Map<string, CloseModalData> = new Map();\nfunction closeAll() {\n openModalsIds.forEach(async ({ render, currentConfig, delay }, rootElId) => {\n const config = { ...currentConfig, isShown: false };\n render(config);\n await new Promise((resolveDelay) => setTimeout(resolveDelay, delay));\n ReactDOM.unmountComponentAtNode(getRoot(rootElId));\n openModalsIds.delete(rootElId);\n });\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction open<T = any>(\n componentRenderer: (\n props: ModalLauncherComponentRendererProps<T>,\n ) => JSX.Element,\n options: ModalLauncherOpenOptions = {},\n): Promise<T> {\n options = { delay: 300, ...options };\n\n // Allow components to specify if they wish to reuse the modal container\n const rootElId = `modals-root${options.modalId || Date.now()}`;\n const rootDom = getRoot(rootElId);\n\n return new Promise((resolve) => {\n let currentConfig = { onClose, isShown: true };\n\n function render({\n onClose,\n isShown,\n }: ModalLauncherComponentRendererProps<T>) {\n ReactDOM.render(componentRenderer({ onClose, isShown }), rootDom);\n }\n\n async function onClose(arg?: T) {\n currentConfig = {\n ...currentConfig,\n isShown: false,\n };\n render(currentConfig);\n await new Promise((resolveDelay) =>\n setTimeout(resolveDelay, options.delay),\n );\n ReactDOM.unmountComponentAtNode(rootDom);\n rootDom.remove();\n openModalsIds.delete(rootElId);\n resolve(arg);\n }\n\n render(currentConfig);\n openModalsIds.set(rootElId, {\n render,\n currentConfig,\n delay: options.delay,\n });\n });\n}\n\nexport const ModalLauncher = {\n open,\n closeAll,\n};\n"]}
1
+ {"version":3,"sources":["../src/Modal.tsx","../src/ModalHeader/ModalHeader.tsx","../src/ModalHeader/ModalHeader.styles.ts","../src/ModalContent/ModalContent.tsx","../src/ModalContent/ModalContent.styles.ts","../src/Modal.styles.ts","../src/ModalControls/ModalControls.tsx","../src/ModalControls/ModalControls.styles.tsx","../src/CompoundModal.tsx","../src/ModalConfirm/ModalConfirm.tsx","../src/ModalLauncher/ModalLauncher.tsx"],"names":["React","ReactModal","Box","cx","CloseIcon","Flex","IconButton","Text","Subheading","tokens","css","getModalHeaderStyles","ModalHeader","_a","_b","onClose","title","subtitle","testId","className","otherProps","__objRest","styles","__spreadProps","__spreadValues","getModalContentStyles","ModalContent","children","getModalStyles","props","modal","ModalSizesMapper","focusFirstWithinNode","node","elements","firstElement","Modal","allowHeightOverflow","position","shouldCloseOnEscapePress","shouldCloseOnOverlayClick","size","topOffset","aria","contentRef","onInitialFocus","contentEl","activeEl","initialFocusEl","onAfterOpen","args","renderDefault","ref","ButtonGroup","getModalControlStyles","ModalControls","Button","ModalConfirm","cancelLabel","cancelTestId","confirmLabel","confirmTestId","intent","isConfirmDisabled","isConfirmLoading","isShown","modalContentProps","modalControlsProps","modalHeaderProps","onCancel","onConfirm","initialFocusRef","cancelRef","confirmButton","cancelButton","ReactDOM","getRoot","rootElId","rootDom","openModalsIds","closeAll","_0","_1","__async","render","currentConfig","delay","config","resolveDelay","open","componentRenderer","options","resolve","arg","ModalLauncher"],"mappings":"kyBAAA,UAAYA,MAAW,QACvB,OAAOC,OAAgB,cAEvB,OAAS,OAAAC,OAA+C,uBCHxD,OAAOF,MAAW,QAClB,OAAS,MAAAG,OAAU,UACnB,OAAS,aAAAC,OAAiB,wBAC1B,OACE,QAAAC,MAGK,uBACP,OAAS,cAAAC,OAAkB,yBAC3B,OAAS,QAAAC,GAAM,cAAAC,OAAkB,6BCTjC,OAAOC,MAAY,yBACnB,OAAS,OAAAC,MAAW,UAEb,SAASC,GAAuB,CACrC,MAAO,CACL,KAAMD,EAAI,CACR,SAAU,WACV,QAAS,GAAGD,EAAO,QAAQ,IAAIA,EAAO,QAAQ,IAAIA,EAAO,QAAQ,IAAIA,EAAO,QAAQ,GACpF,aAAc,GAAGA,EAAO,kBAAkB,IAAIA,EAAO,kBAAkB,OACvE,aAAc,aAAaA,EAAO,OAAO,EAC3C,CAAC,EACD,gBAAiBC,EAAI,CACnB,SAAU,WACV,MAAOD,EAAO,WACd,OAAQA,EAAO,SACf,OAAQ,CACN,SAAU,WACV,IAAK,aAAaA,EAAO,UAAU,IACnC,MAAO,CACT,CACF,CAAC,CACH,CACF,CDEO,IAAMG,EAAeC,GAOgB,CAPhB,IAAAC,EAAAD,EAC1B,SAAAE,EACA,MAAAC,EACA,SAAAC,EACA,OAAAC,EAAS,qBACT,UAAAC,CA7BF,EAwB4BL,EAMvBM,EAAAC,EANuBP,EAMvB,CALH,UACA,QACA,WACA,SACA,cAGA,IAAMQ,EAASX,EAAqB,EAEpC,OACEX,EAAA,cAACK,EAAAkB,EAAAC,EAAA,GACKJ,GADL,CAEC,UAAWjB,GAAGmB,EAAO,KAAMH,CAAS,EACpC,OAAQD,EACR,WAAW,SACX,eAAe,kBAEflB,EAAA,cAACQ,GAAA,CAAW,GAAG,KAAK,YAAW,GAAC,aAAa,QAC1CQ,EACAC,GACCjB,EAAA,cAACO,GAAA,CAAK,WAAW,YAAY,UAAU,WACpCU,CACH,CAEJ,EACCF,GACCf,EAAA,cAACK,EAAA,CAAK,WAAW,SAAS,UAAWiB,EAAO,iBAC1CtB,EAAA,cAACM,GAAA,CACC,QAAQ,cACR,aAAW,QACX,KAAK,QACL,KAAMN,EAAA,cAACI,GAAA,CAAU,KAAK,QAAQ,EAC9B,QAAS,IAAM,CACbW,EAAQ,CACV,EACF,CACF,CAEJ,CAEJ,EAEAH,EAAY,YAAc,cEnE1B,OAAOZ,OAAW,QAClB,OAAS,MAAAG,OAAU,UACnB,OACE,OAAAD,OAGK,uBCNP,OAAS,OAAAQ,OAAW,UACpB,OAAOD,MAAY,yBAEZ,SAASgB,GAAwB,CACtC,MAAO,CACL,KAAMf,GAAI,CACR,QAAS,GAAGD,EAAO,QAAQ,IAAIA,EAAO,QAAQ,GAC9C,MAAOA,EAAO,QACd,SAAUA,EAAO,UACjB,WAAYA,EAAO,iBACnB,WAAYA,EAAO,YACnB,UAAW,OACX,UAAW,OACX,UAAW,YACb,CAAC,CACH,CACF,CDEO,IAAMiB,EAAgBb,GAKJ,CALI,IAAAC,EAAAD,EAC3B,QAAAK,EAAS,sBACT,UAAAC,EACA,SAAAQ,CArBF,EAkB6Bb,EAIxBM,EAAAC,EAJwBP,EAIxB,CAHH,SACA,YACA,aAGA,IAAMQ,EAASG,EAAsB,EACrC,OACEzB,GAAA,cAACE,GAAAqB,EAAAC,EAAA,GACKJ,GADL,CAEC,GAAG,MACH,UAAWjB,GAAGmB,EAAO,KAAMH,CAAS,EACpC,OAAQD,IAEPS,CACH,CAEJ,EAEAD,EAAa,YAAc,eErC3B,OAAOjB,MAAY,yBACnB,OAAS,OAAAC,EAAK,MAAAP,MAAU,UAIjB,SAASyB,EAAeC,EAM5B,CACD,IAAMC,EAAQ3B,EACZO,EAAI,CACF,gBAAiBD,EAAO,WACxB,aAAcoB,EAAM,OAAS,MAAQ,EAAIpB,EAAO,mBAChD,UAAWA,EAAO,eAClB,UAAW,8BAA8BA,EAAO,eAAe,KAC/D,SAAU,8BAA8BA,EAAO,eAAe,KAC9D,SAAU,SACV,QAAS,OACT,cAAe,QACjB,CAAC,EACDoB,EAAM,oBACFnB,EAAI,CACF,SAAU,OACV,UAAW,MACb,CAAC,EACD,KACJmB,EAAM,OAAS,MACXnB,EAAI,CACF,SAAU,OACV,UAAW,OACX,OAAQ,EACR,OAAQ,OACR,MAAO,MACT,CAAC,EACD,KACJmB,EAAM,OAAS,aACXnB,EAAI,CACF,SAAU,gBAAgBD,EAAO,SAAS,IAC1C,UAAW,gBAAgBA,EAAO,SAAS,IAC3C,OAAQ,EACR,OAAQ,QACR,MAAO,OACT,CAAC,EACD,KACJoB,EAAM,SACR,EAEA,MAAO,CACL,OAAQnB,EAAI,CACV,QAAS,OACX,CAAC,EACD,KAAM,CACJ,KAAMP,EACJO,EAAI,CACF,OAAQD,EAAO,mBACf,SAAU,WACV,QAAS,EACT,QAAS,eACT,OAAQ,SACR,UAAW,OACX,QAAS,OACT,UAAWoB,EAAM,OAAS,MAAQ,WAAa,cAC/C,WAAY,aAAapB,EAAO,yBAAyB,IAAIA,EAAO,uBAAuB,EAC7F,CAAC,EACDoB,EAAM,OAAS,MACXnB,EAAI,CACF,MAAO,OACP,OAAQ,MACV,CAAC,EACD,IACN,EACA,UAAWA,EAAI,CACb,UAAW,qBACb,CAAC,EACD,YAAaA,EAAI,CACf,UAAWmB,EAAM,OAAS,MAAQ,WAAa,wBACjD,CAAC,CACH,EACA,aAAc,CACZ,KAAM1B,EACJO,EAAI,CACF,QAAS,OACT,WAAY,WACZ,SAAU,OACV,IAAK,EACL,MAAO,EACP,OAAQ,EACR,KAAM,EACN,OAAQD,EAAO,YACf,QAAS,EACT,WAAY,WAAWA,EAAO,yBAAyB,IAAIA,EAAO,uBAAuB,GACzF,SAAU,QACV,UAAW,OACX,gBAAiB,4BACjB,UAAW,SACX,QAASA,EAAO,UAClB,CAAC,EACDoB,EAAM,OAAS,aACXnB,EAAI,CACF,QAAS,CACX,CAAC,EACD,KACJmB,EAAM,WAAa,SACfnB,EAAI,CACF,WAAY,SACZ,eAAgB,QAClB,CAAC,EACD,KACJmB,EAAM,gBACR,EACA,UAAWnB,EAAI,CACb,QAAS,cACX,CAAC,EACD,YAAaA,EAAI,CACf,QAAS,cACX,CAAC,CACH,EACA,MAAAoB,CACF,CACF,CLhHA,IAAMC,GAAuD,CAC3D,OAAQ,QACR,MAAO,QACP,MAAO,QACP,UAAW,QACX,IAAK,QACL,WAAY,OACd,EAuFA,SAASC,GAAqBC,EAAmB,CAC/C,GAAIA,GAAQA,EAAK,iBAAkB,CACjC,IAAMC,EAAWD,EAAK,iBAAiB,eAAe,EACtD,GAAIC,EAAS,OAAS,EAAG,CACvB,IAAMC,EAAeD,EAAS,CAAC,EAE3B,OAAOC,EAAa,OAAU,YAEhCA,EAAa,MAAM,CAEvB,CACF,CACF,CAEO,IAAMC,EAASvB,GAUS,CAVT,IAAAC,EAAAD,EACpB,qBAAAwB,EAAsB,GACtB,SAAAC,EAAW,SACX,yBAAAC,EAA2B,GAC3B,0BAAAC,EAA4B,GAC5B,KAAAC,EAAO,SACP,OAAAvB,EAAS,cACT,UAAAwB,EAAY,OACZ,KAAAC,CA9HF,EAsHsB7B,EASjBM,EAAAC,EATiBP,EASjB,CARH,sBACA,WACA,2BACA,4BACA,OACA,SACA,YACA,SA9HF,IAAAD,EAAAC,EAiIE,IAAM8B,EAAmB,SAAuB,IAAI,EAE9Cf,EAAQN,EAAAC,EAAA,GACTJ,GADS,CAEZ,oBAAAiB,EACA,SAAAC,EACA,yBAAAC,EACA,0BAAAC,EACA,KAAAC,EACA,OAAAvB,EACA,UAAAwB,CACF,GAEMpB,EAASM,EAAe,CAC5B,SAAAU,EACA,KAAAG,EACA,oBAAAJ,EACA,UAAWjB,EAAW,UACtB,kBAAkBP,EAAAO,EAAW,eAAX,YAAAP,EAAyB,SAC7C,CAAC,EAEKgC,EAAiB,IAAM,CAtJ/B,IAAAhC,EAAAC,EAuJI,IAAMgC,EAAYF,EAAW,QAC7B,GAAIE,EAAW,CACb,IAAMC,EAAW,SAAS,cAI1B,GAFED,IAAcC,GAAYD,EAAU,SAASC,CAAQ,EAGrD,MAEJ,CAEA,IAAMC,GAAiBnC,EAAAgB,EAAM,kBAAN,YAAAhB,EAAuB,QAC1CmC,GACFlC,EAAAkC,EAAe,QAAf,MAAAlC,EAAA,KAAAkC,GACSF,GACTd,GAAqBc,CAAS,CAElC,EAEMG,EAAyC,IAAIC,IAAS,CACtDrB,EAAM,aACRA,EAAM,YAAY,GAAGqB,CAAI,EAE3BL,EAAe,CACjB,EAEMM,EAAgB,IAElB,gCACG/B,EAAW,OACV,gBAACR,EAAAY,EAAA,CACC,MAAOJ,EAAW,MAClB,SAAUA,EAAW,SACrB,QAASS,EAAM,SACXT,EAAW,iBACjB,EAEF,gBAACM,EAAAF,EAAA,GAAiBJ,EAAW,mBAC1BA,EAAW,QACd,CACF,EAIJ,OACE,gBAACnB,GAAA,CACC,YAAa,GACb,KAAM0C,EACN,eAAgBd,EAAM,QACtB,OAAQT,EAAW,QACnB,YAAa6B,EACb,iBAAkBV,EAClB,0BAA2BC,EAC3B,uBAAsB,GACtB,4BAA2B,GAC3B,gBAAiBlB,EAAO,OACxB,MAAO,CACL,QAAS,CACP,IAAKgB,IAAa,SAAW,EAAII,CACnC,EACA,SAAS5B,EAAAM,EAAW,eAAX,YAAAN,EAAyB,KACpC,EACA,UAAW,CACT,KAAMQ,EAAO,KAAK,KAClB,UAAWA,EAAO,KAAK,UACvB,YAAaA,EAAO,KAAK,WAC3B,EACA,iBAAkB,CAChB,KAAMA,EAAO,aAAa,KAC1B,UAAWA,EAAO,aAAa,UAC/B,YAAaA,EAAO,aAAa,WACnC,EACA,eAAgB,IAChB,WAAa8B,GAAQ,CACnBR,EAAW,QAAUQ,CACvB,GAEA,gBAAClD,GAAA,CACC,OAAQgB,EACR,MAAO,CACL,MAAOa,GAAiBU,CAAI,GAAKA,CACnC,EACA,UAAWnB,EAAO,MAClB,kBAAe,IAEd,OAAOF,EAAW,UAAa,WAC5BA,EAAW,SAASS,CAAK,EACzBsB,EAAc,CACpB,CACF,CAEJ,EAEAf,EAAM,YAAc,QMpPpB,OAAOpC,OAAW,QAElB,OACE,QAAAK,OAGK,uBACP,OAAS,eAAAgD,OAAmB,yBCP5B,OAAS,OAAA3C,OAAW,UACpB,OAAOD,MAAY,yBAEZ,SAAS6C,GAAwB,CACtC,MAAO,CACL,KAAM5C,GAAI,CACR,uBAAwBD,EAAO,mBAC/B,wBAAyBA,EAAO,mBAChC,QAAS,GAAGA,EAAO,QAAQ,IAAIA,EAAO,QAAQ,GAC9C,MAAO,OAEP,UAAW,YACb,CAAC,CACH,CACF,CDLA,OAAS,MAAAN,OAAU,UAWZ,IAAMoD,EAAiB1C,GAKgB,CALhB,IAAAC,EAAAD,EAC5B,QAAAK,EAAS,uBACT,UAAAC,EACA,SAAAQ,CAvBF,EAoB8Bb,EAIzBM,EAAAC,EAJyBP,EAIzB,CAHH,SACA,YACA,aAGA,IAAMQ,EAASgC,EAAsB,EAErC,OACEtD,GAAA,cAACK,GAAAkB,EAAAC,EAAA,GACKJ,GADL,CAEC,UAAWjB,GAAGmB,EAAO,KAAMH,CAAS,EACpC,OAAQD,EACR,cAAc,MACd,eAAe,aAEflB,GAAA,cAACqD,GAAA,CAAY,QAAQ,SAAS,QAAQ,YACnC1B,CACH,CACF,CAEJ,EAEA4B,EAAc,YAAc,gBEhCrB,IAAMnB,EAAQA,EACrBA,EAAM,QAAUV,EAChBU,EAAM,OAASxB,EACfwB,EAAM,SAAWmB,ECdjB,OAAOvD,MAAW,QAOlB,OAAS,UAAAwD,OAAc,yBAmFhB,IAAMC,GAAe,CAAC,CAC3B,oBAAApB,EAAsB,GACtB,YAAAqB,EAAc,SACd,aAAAC,EAAe,oCACf,SAAAhC,EACA,aAAAiC,EAAe,UACf,cAAAC,EAAgB,qCAChB,OAAAC,EAAS,WACT,kBAAAC,EAAoB,GACpB,iBAAAC,EAAmB,GACnB,QAAAC,EACA,kBAAAC,EACA,mBAAAC,EACA,iBAAAC,EACA,SAAAC,EACA,UAAAC,EACA,yBAAA/B,EAA2B,GAC3B,0BAAAC,EAA4B,GAC5B,KAAAC,EAAO,SACP,OAAAvB,EAAS,sBACT,MAAAF,EAAQ,gBACR,gBAAAuD,CACF,IAAyB,CACvB,IAAMC,EAAYxE,EAAM,OAAO,IAAI,EAE7ByE,EAAgBb,EACpB5D,EAAA,cAACwD,GAAA,CACC,OAAQK,EACR,WAAYE,EACZ,UAAWC,EACX,QAASF,EACT,KAAK,QACL,QAAS,IAAMQ,EAAU,GAExBV,CACH,EACE,KAEEc,EAAehB,EACnB1D,EAAA,cAACwD,GAAA,CACC,OAAQG,EACR,QAAQ,YACR,QAASU,EACT,KAAK,QACL,IAAKE,GAAmBC,GAEvBd,CACH,EACE,KAEJ,OACE1D,EAAA,cAACoC,EAAA,CACC,OAAQlB,EACR,QAAS+C,EACT,QAASI,EACT,KAAM5B,EACN,0BAA2BD,EAC3B,yBAA0BD,EAC1B,oBAAqBF,EACrB,gBAAiBmC,GAEhB,IAEGxE,EAAA,cAACA,EAAM,SAAN,KACCA,EAAA,cAACoC,EAAM,OAANb,EAAAC,EAAA,CACC,MAAOR,GAAS,IACZoD,GAFL,CAGC,QAASC,GACX,EACArE,EAAA,cAACoC,EAAM,QAANZ,EAAA,GAAkB0C,GAAoBvC,CAAS,EAChD3B,EAAA,cAACoC,EAAM,SAANZ,EAAA,GAAmB2C,GACjBO,EACAD,CACH,CACF,CAGN,CAEJ,EAEAhB,GAAa,YAAc,eC1K3B,OAAOkB,MAAc,YA2BrB,IAAMC,GAAWC,GAAkC,CAEjD,IAAIC,EAAU,SAAS,eAAeD,CAAQ,EAC9C,OAAIC,IAAY,OAKhBA,EAAU,SAAS,cAAc,KAAK,EACtCA,EAAQ,aAAa,KAAMD,CAAQ,EACnC,SAAS,KAAK,YAAYC,CAAO,GAC1BA,CACT,EAEMC,EAA6C,IAAI,IACvD,SAASC,IAAW,CAClBD,EAAc,QAAQ,CAAOE,EAAkCC,IAAaC,EAAA,MAA/CF,EAAkCC,GAAa,UAA/C,CAAE,OAAAE,EAAQ,cAAAC,EAAe,MAAAC,CAAM,EAAGT,EAAa,CAC1E,IAAMU,EAAShE,EAAAC,EAAA,GAAK6D,GAAL,CAAoB,QAAS,EAAM,GAClDD,EAAOG,CAAM,EACb,MAAM,IAAI,QAASC,GAAiB,WAAWA,EAAcF,CAAK,CAAC,EACnEX,EAAS,uBAAuBC,GAAQC,CAAQ,CAAC,EACjDE,EAAc,OAAOF,CAAQ,CAC/B,EAAC,CACH,CAGA,SAASY,GACPC,EAGAC,EAAoC,CAAC,EACzB,CACZA,EAAUnE,EAAA,CAAE,MAAO,KAAQmE,GAG3B,IAAMd,EAAW,cAAcc,EAAQ,SAAW,KAAK,IAAI,CAAC,GACtDb,EAAUF,GAAQC,CAAQ,EAEhC,OAAO,IAAI,QAASe,GAAY,CAC9B,IAAIP,EAAgB,CAAE,QAAAtE,EAAS,QAAS,EAAK,EAE7C,SAASqE,EAAO,CACd,QAAArE,EACA,QAAAkD,CACF,EAA2C,CACzCU,EAAS,OAAOe,EAAkB,CAAE,QAAA3E,EAAS,QAAAkD,CAAQ,CAAC,EAAGa,CAAO,CAClE,CAEA,SAAe/D,EAAQ8E,EAAS,QAAAV,EAAA,sBAC9BE,EAAgB9D,EAAAC,EAAA,GACX6D,GADW,CAEd,QAAS,EACX,GACAD,EAAOC,CAAa,EACpB,MAAM,IAAI,QAASG,GACjB,WAAWA,EAAcG,EAAQ,KAAK,CACxC,EACAhB,EAAS,uBAAuBG,CAAO,EACvCA,EAAQ,OAAO,EACfC,EAAc,OAAOF,CAAQ,EAC7Be,EAAQC,CAAG,CACb,GAEAT,EAAOC,CAAa,EACpBN,EAAc,IAAIF,EAAU,CAC1B,OAAAO,EACA,cAAAC,EACA,MAAOM,EAAQ,KACjB,CAAC,CACH,CAAC,CACH,CAEO,IAAMG,GAAgB,CAC3B,KAAAL,GACA,SAAAT,EACF","sourcesContent":["import * as React from 'react';\nimport ReactModal from 'react-modal';\n\nimport { Box, type CommonProps, type ExpandProps } from '@contentful/f36-core';\n\nimport { ModalHeader, ModalHeaderProps } from './ModalHeader/ModalHeader';\nimport { ModalContent, ModalContentProps } from './ModalContent/ModalContent';\nimport { getModalStyles } from './Modal.styles';\nimport type { ModalSizeType, ModalPositionType } from './types';\n\nconst ModalSizesMapper: { [key in ModalSizeType]: string } = {\n medium: '520px',\n small: '400px',\n large: '700px',\n fullWidth: '100vw',\n zen: '100vw',\n fullscreen: '100vw',\n};\n\nexport interface ModalProps extends CommonProps {\n /**\n * When true, the dialog is shown.\n */\n isShown: boolean;\n\n /**\n * Function that will be run when the modal is requested to be closed, prior to actually closing.\n */\n onClose: ReactModal.Props['onRequestClose'];\n\n /**\n * Function that will be run after the modal has opened.\n */\n onAfterOpen?: ReactModal.Props['onAfterOpen'];\n\n /**\n * Additional aria attributes\n */\n aria?: ReactModal.Props['aria'];\n\n /**\n * Boolean indicating if clicking the overlay should close the overlay.\n * @default true\n */\n shouldCloseOnOverlayClick?: boolean;\n /**\n * Boolean indicating if pressing the esc key should close the overlay.\n * @default true\n */\n shouldCloseOnEscapePress?: boolean;\n /**\n * Indicating if modal is centered or linked to the top\n * @default center\n */\n position?: ModalPositionType;\n /**\n * Top offset if position is 'top'\n * @default 50px\n */\n topOffset?: number | string;\n /**\n * Modal title that is used in header\n */\n title?: string;\n /**\n * Modal subtitle that is used in header\n */\n subtitle?: string;\n /**\n * Size of the modal window\n * @default medium\n */\n size?: ModalSizeType | string | number;\n /**\n * Are modals higher than viewport allowed\n * @default false\n */\n allowHeightOverflow?: boolean;\n\n /**\n * Optional props to override overlay behaviour\n */\n overlayProps?: Pick<CommonProps, 'className' | 'style'>;\n\n /**\n * Optional props to override ModalHeader behaviour\n */\n modalHeaderProps?: Partial<ModalHeaderProps>;\n\n /**\n * Optional props to override ModalContent behaviour\n */\n modalContentProps?: Partial<ModalContentProps>;\n\n /**\n * Optional property to set initial focus\n */\n initialFocusRef?: React.RefObject<HTMLElement>;\n\n children: React.ReactNode | RenderModal;\n}\n\ntype RenderModal = (modalProps: ModalProps) => React.ReactNode;\n\nfunction focusFirstWithinNode(node: HTMLElement) {\n if (node && node.querySelectorAll) {\n const elements = node.querySelectorAll('input, button');\n if (elements.length > 0) {\n const firstElement = elements[0];\n // @ts-expect-error focus might be missing\n if (typeof firstElement.focus === 'function') {\n // @ts-expect-error focus might be missing\n firstElement.focus();\n }\n }\n }\n}\n\nexport const Modal = ({\n allowHeightOverflow = false,\n position = 'center',\n shouldCloseOnEscapePress = true,\n shouldCloseOnOverlayClick = true,\n size = 'medium',\n testId = 'cf-ui-modal',\n topOffset = '50px',\n aria,\n ...otherProps\n}: ExpandProps<ModalProps>) => {\n const contentRef = React.useRef<HTMLDivElement>(null);\n\n const props = {\n ...otherProps,\n allowHeightOverflow,\n position,\n shouldCloseOnEscapePress,\n shouldCloseOnOverlayClick,\n size,\n testId,\n topOffset,\n };\n\n const styles = getModalStyles({\n position,\n size,\n allowHeightOverflow,\n className: otherProps.className,\n overlayClassName: otherProps.overlayProps?.className,\n });\n\n const onInitialFocus = () => {\n const contentEl = contentRef.current;\n if (contentEl) {\n const activeEl = document.activeElement;\n const isContentContainsActive =\n contentEl !== activeEl && contentEl.contains(activeEl);\n\n if (isContentContainsActive) {\n return;\n }\n }\n\n const initialFocusEl = props.initialFocusRef?.current;\n if (initialFocusEl) {\n initialFocusEl.focus?.();\n } else if (contentEl) {\n focusFirstWithinNode(contentEl);\n }\n };\n\n const onAfterOpen: ModalProps['onAfterOpen'] = (...args) => {\n if (props.onAfterOpen) {\n props.onAfterOpen(...args);\n }\n onInitialFocus();\n };\n\n const renderDefault = () => {\n return (\n <>\n {otherProps.title && (\n <ModalHeader\n title={otherProps.title}\n subtitle={otherProps.subtitle}\n onClose={props.onClose}\n {...otherProps.modalHeaderProps}\n />\n )}\n <ModalContent {...otherProps.modalContentProps}>\n {otherProps.children}\n </ModalContent>\n </>\n );\n };\n\n return (\n <ReactModal\n ariaHideApp={false}\n aria={aria}\n onRequestClose={props.onClose}\n isOpen={otherProps.isShown}\n onAfterOpen={onAfterOpen}\n shouldCloseOnEsc={shouldCloseOnEscapePress}\n shouldCloseOnOverlayClick={shouldCloseOnOverlayClick}\n shouldFocusAfterRender\n shouldReturnFocusAfterClose\n portalClassName={styles.portal}\n style={{\n content: {\n top: position === 'center' ? 0 : topOffset,\n },\n overlay: otherProps.overlayProps?.style,\n }}\n className={{\n base: styles.base.root,\n afterOpen: styles.base.afterOpen,\n beforeClose: styles.base.beforeClose,\n }}\n overlayClassName={{\n base: styles.modalOverlay.root,\n afterOpen: styles.modalOverlay.afterOpen,\n beforeClose: styles.modalOverlay.beforeClose,\n }}\n closeTimeoutMS={200}\n contentRef={(ref) => {\n contentRef.current = ref;\n }}\n >\n <Box\n testId={testId}\n style={{\n width: ModalSizesMapper[size] || size,\n }}\n className={styles.modal}\n data-modal-root\n >\n {typeof otherProps.children === 'function'\n ? otherProps.children(props)\n : renderDefault()}\n </Box>\n </ReactModal>\n );\n};\n\nModal.displayName = 'Modal';\n","import React from 'react';\nimport { cx } from 'emotion';\nimport { CloseIcon } from '@contentful/f36-icons';\nimport {\n Flex,\n type PropsWithHTMLElement,\n type CommonProps,\n} from '@contentful/f36-core';\nimport { IconButton } from '@contentful/f36-button';\nimport { Text, Subheading } from '@contentful/f36-typography';\n\nimport { getModalHeaderStyles } from './ModalHeader.styles';\n\ninterface ModalHeaderInternalProps extends CommonProps {\n title: string;\n subtitle?: string;\n onClose?: Function;\n}\n\nexport type ModalHeaderProps = PropsWithHTMLElement<\n ModalHeaderInternalProps,\n 'div'\n>;\n\nexport const ModalHeader = ({\n onClose,\n title,\n subtitle,\n testId = 'cf-ui-modal-header',\n className,\n ...otherProps\n}: ModalHeaderProps): React.ReactElement => {\n const styles = getModalHeaderStyles();\n\n return (\n <Flex\n {...otherProps}\n className={cx(styles.root, className)}\n testId={testId}\n alignItems=\"center\"\n justifyContent=\"space-between\"\n >\n <Subheading as=\"h2\" isTruncated marginBottom=\"none\">\n {title}\n {subtitle && (\n <Text marginLeft=\"spacingXs\" fontColor=\"gray700\">\n {subtitle}\n </Text>\n )}\n </Subheading>\n {onClose && (\n <Flex alignItems=\"center\" className={styles.buttonContainer}>\n <IconButton\n variant=\"transparent\"\n aria-label=\"Close\"\n size=\"small\"\n icon={<CloseIcon size=\"small\" />}\n onClick={() => {\n onClose();\n }}\n />\n </Flex>\n )}\n </Flex>\n );\n};\n\nModalHeader.displayName = 'ModalHeader';\n","import tokens from '@contentful/f36-tokens';\nimport { css } from 'emotion';\n\nexport function getModalHeaderStyles() {\n return {\n root: css({\n position: 'relative',\n padding: `${tokens.spacingM} ${tokens.spacingM} ${tokens.spacingM} ${tokens.spacingL}`,\n borderRadius: `${tokens.borderRadiusMedium} ${tokens.borderRadiusMedium} 0 0`,\n borderBottom: `1px solid ${tokens.gray300}`,\n }),\n buttonContainer: css({\n position: 'relative',\n width: tokens.spacing2Xl,\n height: tokens.spacingL,\n button: {\n position: 'absolute',\n top: `calc(-1 * ${tokens.spacing2Xs})`,\n right: 0,\n },\n }),\n };\n}\n","import React from 'react';\nimport { cx } from 'emotion';\nimport {\n Box,\n type PropsWithHTMLElement,\n type CommonProps,\n} from '@contentful/f36-core';\nimport { getModalContentStyles } from './ModalContent.styles';\n\ninterface ModalContentInternalProps extends CommonProps {\n children: React.ReactNode;\n}\n\nexport type ModalContentProps = PropsWithHTMLElement<\n ModalContentInternalProps,\n 'div'\n>;\n\nexport const ModalContent = ({\n testId = 'cf-ui-modal-content',\n className,\n children,\n ...otherProps\n}: ModalContentProps) => {\n const styles = getModalContentStyles();\n return (\n <Box\n {...otherProps}\n as=\"div\"\n className={cx(styles.root, className)}\n testId={testId}\n >\n {children}\n </Box>\n );\n};\n\nModalContent.displayName = 'ModalContent';\n","import { css } from 'emotion';\nimport tokens from '@contentful/f36-tokens';\n\nexport function getModalContentStyles() {\n return {\n root: css({\n padding: `${tokens.spacingM} ${tokens.spacingL}`,\n color: tokens.gray700,\n fontSize: tokens.fontSizeM,\n fontFamily: tokens.fontStackPrimary,\n lineHeight: tokens.lineHeightM,\n overflowY: 'auto',\n overflowX: 'auto',\n boxSizing: 'border-box',\n }),\n };\n}\n","import tokens from '@contentful/f36-tokens';\nimport { css, cx } from 'emotion';\n\nimport type { ModalProps } from './Modal';\n\nexport function getModalStyles(props: {\n size: ModalProps['size'];\n position: ModalProps['position'];\n allowHeightOverflow?: boolean;\n className?: string;\n overlayClassName?: string;\n}) {\n const modal = cx(\n css({\n backgroundColor: tokens.colorWhite,\n borderRadius: props.size === 'zen' ? 0 : tokens.borderRadiusMedium,\n boxShadow: tokens.boxShadowHeavy,\n maxHeight: `calc(100vh - 1rem * (100 / ${tokens.fontBaseDefault}))`,\n maxWidth: `calc(100vw - 1rem * (100 / ${tokens.fontBaseDefault}))`,\n overflow: 'hidden',\n display: 'flex',\n flexDirection: 'column',\n }),\n props.allowHeightOverflow\n ? css({\n overflow: 'auto',\n maxHeight: 'none',\n })\n : null,\n props.size === 'zen'\n ? css({\n maxWidth: 'none',\n maxHeight: 'none',\n margin: 0,\n height: '100%',\n width: '100%',\n })\n : null,\n props.size === 'fullscreen'\n ? css({\n maxWidth: `calc(100vw - ${tokens.spacingXl})`,\n maxHeight: `calc(100vh - ${tokens.spacingXl})`,\n margin: 0,\n height: '100vh',\n width: '100vw',\n })\n : null,\n props.className,\n );\n\n return {\n portal: css({\n display: 'block',\n }),\n base: {\n root: cx(\n css({\n zIndex: tokens.zIndexModalContent,\n position: 'relative',\n padding: 0,\n display: 'inline-block',\n margin: '0 auto',\n textAlign: 'left',\n outline: 'none',\n transform: props.size === 'zen' ? 'scale(1)' : 'scale(0.85)',\n transition: `transform ${tokens.transitionDurationDefault} ${tokens.transitionEasingDefault}`,\n }),\n props.size === 'zen'\n ? css({\n width: '100%',\n height: '100%',\n })\n : null,\n ),\n afterOpen: css({\n transform: 'scale(1) !important',\n }),\n beforeClose: css({\n transform: props.size === 'zen' ? 'scale(1)' : 'scale(0.85) !important',\n }),\n },\n modalOverlay: {\n root: cx(\n css({\n display: 'flex',\n alignItems: 'baseline',\n flexWrap: 'wrap',\n top: 0,\n right: 0,\n bottom: 0,\n left: 0,\n zIndex: tokens.zIndexModal,\n opacity: 0,\n transition: `opacity ${tokens.transitionDurationDefault} ${tokens.transitionEasingDefault}`,\n position: 'fixed',\n overflowY: 'auto',\n backgroundColor: 'rgba(12, 20, 28, 0.74902)',\n textAlign: 'center',\n padding: tokens.spacing2Xl,\n }),\n props.size === 'fullscreen'\n ? css({\n padding: 0,\n })\n : null,\n props.position === 'center'\n ? css({\n alignItems: 'center',\n justifyContent: 'center',\n })\n : null,\n props.overlayClassName,\n ),\n afterOpen: css({\n opacity: '1 !important',\n }),\n beforeClose: css({\n opacity: '0 !important',\n }),\n },\n modal,\n };\n}\n","import React from 'react';\n\nimport {\n Flex,\n type PropsWithHTMLElement,\n type CommonProps,\n} from '@contentful/f36-core';\nimport { ButtonGroup } from '@contentful/f36-button';\nimport { getModalControlStyles } from './ModalControls.styles';\nimport { cx } from 'emotion';\n\ninterface ModalControlsInternalProps extends CommonProps {\n children: React.ReactElement[] | React.ReactElement;\n}\n\nexport type ModalControlsProps = PropsWithHTMLElement<\n ModalControlsInternalProps,\n 'div'\n>;\n\nexport const ModalControls = ({\n testId = 'cf-ui-modal-controls',\n className,\n children,\n ...otherProps\n}: ModalControlsProps): React.ReactElement => {\n const styles = getModalControlStyles();\n\n return (\n <Flex\n {...otherProps}\n className={cx(styles.root, className)}\n testId={testId}\n flexDirection=\"row\"\n justifyContent=\"flex-end\"\n >\n <ButtonGroup variant=\"spaced\" spacing=\"spacingS\">\n {children}\n </ButtonGroup>\n </Flex>\n );\n};\n\nModalControls.displayName = 'ModalControls';\n","import { css } from 'emotion';\nimport tokens from '@contentful/f36-tokens';\n\nexport function getModalControlStyles() {\n return {\n root: css({\n borderBottomLeftRadius: tokens.borderRadiusMedium,\n borderBottomRightRadius: tokens.borderRadiusMedium,\n padding: `${tokens.spacingS} ${tokens.spacingM}`,\n width: `100%`,\n // This is required in places where it is not set globally (e.g. dialogs via the app framework)\n boxSizing: 'border-box',\n }),\n };\n}\n","import { Modal as OriginalModal } from './Modal';\nimport { ModalContent } from './ModalContent/ModalContent';\nimport { ModalHeader } from './ModalHeader/ModalHeader';\nimport { ModalControls } from './ModalControls/ModalControls';\n\ntype CompoundModal = typeof OriginalModal & {\n Content: typeof ModalContent;\n Header: typeof ModalHeader;\n Controls: typeof ModalControls;\n};\n\nexport const Modal = OriginalModal as CompoundModal;\nModal.Content = ModalContent;\nModal.Header = ModalHeader;\nModal.Controls = ModalControls;\n","import React from 'react';\n\nimport { Modal } from '../CompoundModal';\nimport type { ModalProps } from '../Modal';\nimport type { ModalHeaderProps } from '../ModalHeader/ModalHeader';\nimport type { ModalContentProps } from '../ModalContent/ModalContent';\nimport type { ModalControlsProps } from '../ModalControls/ModalControls';\nimport { Button } from '@contentful/f36-button';\n\nexport interface ModalConfirmProps {\n /**\n * When true, the dialog is shown.\n */\n isShown: boolean;\n /**\n * Function that will be called when the confirm button is clicked. This does not close the ModalConfirm.\n */\n onConfirm(): void;\n /**\n * Function that will be called when the cancel button is clicked. This does not close the ModalConfirm.\n */\n onCancel: ModalProps['onClose'];\n /**\n Modal title that is used in header\n */\n title?: string;\n /**\n * Label of the confirm button\n */\n confirmLabel?: string | false;\n /**\n * Label of the cancel button\n */\n cancelLabel?: string | false;\n /**\n * The intent of the ModalConfirm. Used for the Button.\n */\n intent?: 'primary' | 'positive' | 'negative';\n /**\n * Size of the modal window\n */\n size?: ModalProps['size'];\n /**\n * Boolean indicating if clicking the overlay should close the overlay.\n */\n shouldCloseOnOverlayClick?: boolean;\n /**\n * Boolean indicating if pressing the esc key should close the overlay.\n */\n shouldCloseOnEscapePress?: boolean;\n /**\n * When true, the confirm button is set to disabled.\n */\n isConfirmDisabled?: boolean;\n /**\n * When true, the confirm button is set to loading.\n */\n isConfirmLoading?: boolean;\n /**\n * Are modals higher than viewport allowed\n */\n allowHeightOverflow?: boolean;\n\n /**\n * Optional props to override ModalHeader behaviour\n */\n modalHeaderProps?: Partial<ModalHeaderProps>;\n\n /**\n * Optional props to override ModalContent behaviour\n */\n modalContentProps?: Partial<ModalContentProps>;\n\n /**\n * Optional props to override ModalControl behaviour\n */\n modalControlsProps?: Partial<ModalControlsProps>;\n\n /**\n * Optional property to set initial focus\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- we don't know the type of element to give initial focus\n initialFocusRef?: React.RefObject<any>;\n\n testId?: string;\n confirmTestId?: string;\n cancelTestId?: string;\n children: React.ReactNode;\n}\n\nexport const ModalConfirm = ({\n allowHeightOverflow = false,\n cancelLabel = 'Cancel',\n cancelTestId = 'cf-ui-modal-confirm-cancel-button',\n children,\n confirmLabel = 'Confirm',\n confirmTestId = 'cf-ui-modal-confirm-confirm-button',\n intent = 'positive',\n isConfirmDisabled = false,\n isConfirmLoading = false,\n isShown,\n modalContentProps,\n modalControlsProps,\n modalHeaderProps,\n onCancel,\n onConfirm,\n shouldCloseOnEscapePress = true,\n shouldCloseOnOverlayClick = true,\n size = 'medium',\n testId = 'cf-ui-modal-confirm',\n title = 'Are you sure?',\n initialFocusRef,\n}: ModalConfirmProps) => {\n const cancelRef = React.useRef(null);\n\n const confirmButton = confirmLabel ? (\n <Button\n testId={confirmTestId}\n isDisabled={isConfirmDisabled}\n isLoading={isConfirmLoading}\n variant={intent}\n size=\"small\"\n onClick={() => onConfirm()}\n >\n {confirmLabel}\n </Button>\n ) : null;\n\n const cancelButton = cancelLabel ? (\n <Button\n testId={cancelTestId}\n variant=\"secondary\"\n onClick={onCancel}\n size=\"small\"\n ref={initialFocusRef || cancelRef}\n >\n {cancelLabel}\n </Button>\n ) : null;\n\n return (\n <Modal\n testId={testId}\n isShown={isShown}\n onClose={onCancel}\n size={size}\n shouldCloseOnOverlayClick={shouldCloseOnOverlayClick}\n shouldCloseOnEscapePress={shouldCloseOnEscapePress}\n allowHeightOverflow={allowHeightOverflow}\n initialFocusRef={cancelRef}\n >\n {() => {\n return (\n <React.Fragment>\n <Modal.Header\n title={title || ''}\n {...modalHeaderProps}\n onClose={onCancel}\n />\n <Modal.Content {...modalContentProps}>{children}</Modal.Content>\n <Modal.Controls {...modalControlsProps}>\n {cancelButton}\n {confirmButton}\n </Modal.Controls>\n </React.Fragment>\n );\n }}\n </Modal>\n );\n};\n\nModalConfirm.displayName = 'ModalConfirm';\n","/* global Promise */\nimport ReactDOM from 'react-dom';\n\n// @todo: change any to unknown\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport interface ModalLauncherComponentRendererProps<T = any> {\n isShown: boolean;\n onClose: (result?: T) => void;\n}\n\nexport interface ModalLauncherOpenOptions {\n /**\n * Unique id to be used as identifier for the modal contianer\n */\n modalId?: string;\n /**\n * ms before removing the component from the tree\n * @default 300\n */\n delay?: number;\n}\n\ninterface CloseModalData {\n delay: number;\n render: (args: ModalLauncherComponentRendererProps<any>) => void;\n currentConfig: ModalLauncherComponentRendererProps<any>;\n}\n\nconst getRoot = (rootElId: string): HTMLElement => {\n // Reuse the container if we find it\n let rootDom = document.getElementById(rootElId);\n if (rootDom !== null) {\n return rootDom;\n }\n\n // Otherwise create it\n rootDom = document.createElement('div');\n rootDom.setAttribute('id', rootElId);\n document.body.appendChild(rootDom);\n return rootDom;\n};\n\nconst openModalsIds: Map<string, CloseModalData> = new Map();\nfunction closeAll() {\n openModalsIds.forEach(async ({ render, currentConfig, delay }, rootElId) => {\n const config = { ...currentConfig, isShown: false };\n render(config);\n await new Promise((resolveDelay) => setTimeout(resolveDelay, delay));\n ReactDOM.unmountComponentAtNode(getRoot(rootElId));\n openModalsIds.delete(rootElId);\n });\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction open<T = any>(\n componentRenderer: (\n props: ModalLauncherComponentRendererProps<T>,\n ) => JSX.Element,\n options: ModalLauncherOpenOptions = {},\n): Promise<T> {\n options = { delay: 300, ...options };\n\n // Allow components to specify if they wish to reuse the modal container\n const rootElId = `modals-root${options.modalId || Date.now()}`;\n const rootDom = getRoot(rootElId);\n\n return new Promise((resolve) => {\n let currentConfig = { onClose, isShown: true };\n\n function render({\n onClose,\n isShown,\n }: ModalLauncherComponentRendererProps<T>) {\n ReactDOM.render(componentRenderer({ onClose, isShown }), rootDom);\n }\n\n async function onClose(arg?: T) {\n currentConfig = {\n ...currentConfig,\n isShown: false,\n };\n render(currentConfig);\n await new Promise((resolveDelay) =>\n setTimeout(resolveDelay, options.delay),\n );\n ReactDOM.unmountComponentAtNode(rootDom);\n rootDom.remove();\n openModalsIds.delete(rootElId);\n resolve(arg);\n }\n\n render(currentConfig);\n openModalsIds.set(rootElId, {\n render,\n currentConfig,\n delay: options.delay,\n });\n });\n}\n\nexport const ModalLauncher = {\n open,\n closeAll,\n};\n"]}
package/package.json CHANGED
@@ -1,16 +1,16 @@
1
1
  {
2
2
  "name": "@contentful/f36-modal",
3
- "version": "4.59.3",
3
+ "version": "4.60.1",
4
4
  "description": "Forma 36: Modal component",
5
5
  "scripts": {
6
6
  "build": "tsup"
7
7
  },
8
8
  "dependencies": {
9
- "@contentful/f36-button": "^4.59.3",
10
- "@contentful/f36-core": "^4.59.3",
9
+ "@contentful/f36-button": "^4.60.1",
10
+ "@contentful/f36-core": "^4.60.1",
11
11
  "@contentful/f36-icons": "^4.27.0",
12
12
  "@contentful/f36-tokens": "^4.0.4",
13
- "@contentful/f36-typography": "^4.59.3",
13
+ "@contentful/f36-typography": "^4.60.1",
14
14
  "@types/react-modal": "^3.13.1",
15
15
  "emotion": "^10.0.17",
16
16
  "react-modal": "^3.16.1"