@saas-ui/modals 0.3.3 → 0.4.0-next.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,50 @@
1
1
  # @saas-ui/modals
2
2
 
3
+ ## 0.4.0-next.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 9391c44: BREAKING: Removed yup dependency from forms and fixed peer dependency issues.
8
+
9
+ <Form> doesn't accept a Yup `schema` any more by default.
10
+
11
+ Use a schema resolver to use schema support. All hookform resolvers are supported.
12
+
13
+ ```
14
+ import {yupResolver} from '@hookform/resolvers/yup'
15
+
16
+ <Form resolver={yupResolver(schema)} />
17
+ ```
18
+
19
+ AutoForm only supports Yup for now and has a new API.
20
+
21
+ ```
22
+ import { yupForm } from '@saas-ui/forms/yup'
23
+
24
+ <AutoForm {...yupForm(schema)} />
25
+ ```
26
+
27
+ ### Patch Changes
28
+
29
+ - Updated dependencies [9391c44]
30
+ - @saas-ui/button@0.4.0-next.0
31
+ - @saas-ui/forms@0.6.0-next.0
32
+
33
+ ## 0.3.5
34
+
35
+ ### Patch Changes
36
+
37
+ - 99f3e33: Custom modal components can now be directly passed to modals.open
38
+
39
+ ## 0.3.4
40
+
41
+ ### Patch Changes
42
+
43
+ - 70340f0: useModal now has the correct types
44
+ - 6c78c30: FormDialog type is now generic and accepts FieldValues / form context ref
45
+ - Updated dependencies [9245460]
46
+ - @saas-ui/forms@0.5.3
47
+
3
48
  ## 0.3.3
4
49
 
5
50
  ### Patch Changes
package/dist/form.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as React from 'react';
2
- import { FormProps } from '@saas-ui/forms';
2
+ import { FormProps, FieldValues, FieldResolver, UseFormReturn } from '@saas-ui/forms';
3
3
  import { BaseModalProps } from './modal';
4
- export interface FormDialogProps extends Omit<BaseModalProps, 'children'>, Pick<FormProps, 'schema' | 'defaultValues' | 'onSubmit' | 'resolver' | 'mode' | 'reValidateMode' | 'shouldFocusError' | 'shouldUnregister' | 'shouldUseNativeValidation' | 'criteriaMode' | 'delayError'> {
4
+ export interface FormDialogProps<TFieldValues extends FieldValues = FieldValues> extends Omit<BaseModalProps, 'children'>, Pick<FormProps<TFieldValues>, 'schema' | 'defaultValues' | 'onSubmit' | 'onError' | 'resolver' | 'mode' | 'reValidateMode' | 'shouldFocusError' | 'shouldUnregister' | 'shouldUseNativeValidation' | 'criteriaMode' | 'delayError'> {
5
5
  /**
6
6
  * The modal footer, will be wrapped with `ModalFooter`.
7
7
  * Defaults to a cancel and submit button.
@@ -21,6 +21,12 @@ export interface FormDialogProps extends Omit<BaseModalProps, 'children'>, Pick<
21
21
  * If no children are passed, this will auto render fields based on the supplied schema.
22
22
  */
23
23
  children?: React.ReactNode;
24
+ /**
25
+ * A schema field resolver used to auto generate form fields.
26
+ */
27
+ fieldResolver?: FieldResolver;
24
28
  }
25
- export declare const FormDialog: React.FC<FormDialogProps>;
29
+ export declare const FormDialog: <TFieldValues extends FieldValues>(props: FormDialogProps<TFieldValues> & {
30
+ ref?: React.ForwardedRef<UseFormReturn<TFieldValues, object>> | undefined;
31
+ }) => React.ReactElement;
26
32
  //# sourceMappingURL=form.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"form.d.ts","sourceRoot":"","sources":["../src/form.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAI9B,OAAO,EAA8B,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAGtE,OAAO,EAAa,cAAc,EAAE,MAAM,SAAS,CAAA;AAEnD,MAAM,WAAW,eACf,SAAQ,IAAI,CAAC,cAAc,EAAE,UAAU,CAAC,EACtC,IAAI,CACF,SAAS,EACP,QAAQ,GACR,eAAe,GACf,UAAU,GACV,UAAU,GACV,MAAM,GACN,gBAAgB,GAChB,kBAAkB,GAClB,kBAAkB,GAClB,2BAA2B,GAC3B,cAAc,GACd,YAAY,CACf;IACH;;;OAGG;IACH,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IACxB;;;OAGG;IACH,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAC7B;;;OAGG;IACH,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAC7B;;OAEG;IACH,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CAC3B;AAED,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CAyDhD,CAAA"}
1
+ {"version":3,"file":"form.d.ts","sourceRoot":"","sources":["../src/form.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAI9B,OAAO,EAIL,SAAS,EACT,WAAW,EACX,aAAa,EACb,aAAa,EACd,MAAM,gBAAgB,CAAA;AAGvB,OAAO,EAAa,cAAc,EAAE,MAAM,SAAS,CAAA;AAEnD,MAAM,WAAW,eAAe,CAAC,YAAY,SAAS,WAAW,GAAG,WAAW,CAC7E,SAAQ,IAAI,CAAC,cAAc,EAAE,UAAU,CAAC,EACtC,IAAI,CACF,SAAS,CAAC,YAAY,CAAC,EACrB,QAAQ,GACR,eAAe,GACf,UAAU,GACV,SAAS,GACT,UAAU,GACV,MAAM,GACN,gBAAgB,GAChB,kBAAkB,GAClB,kBAAkB,GAClB,2BAA2B,GAC3B,cAAc,GACd,YAAY,CACf;IACH;;;OAGG;IACH,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IACxB;;;OAGG;IACH,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAC7B;;;OAGG;IACH,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAC7B;;OAEG;IACH,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAC1B;;OAEG;IACH,aAAa,CAAC,EAAE,aAAa,CAAA;CAC9B;AAED,eAAO,MAAM,UAAU;;MA2ElB,MAAM,YAAY,CAAA"}
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- var e=require("react"),r=require("@chakra-ui/react"),t=require("@saas-ui/button"),n=require("@saas-ui/forms");function o(e){if(e&&e.__esModule)return e;var r=Object.create(null);return e&&Object.keys(e).forEach(function(t){if("default"!==t){var n=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(r,t,n.get?n:{enumerable:!0,get:function(){return e[t]}})}}),r.default=e,r}var l=/*#__PURE__*/o(e);function a(){return a=Object.assign||function(e){for(var r=1;r<arguments.length;r++){var t=arguments[r];for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])}return e},a.apply(this,arguments)}function i(e,r){if(null==e)return{};var t,n,o={},l=Object.keys(e);for(n=0;n<l.length;n++)r.indexOf(t=l[n])>=0||(o[t]=e[t]);return o}var u=["title","cancelLabel","confirmLabel","cancelProps","confirmProps","buttonGroupProps","isOpen","closeOnCancel","closeOnConfirm","leastDestructiveFocus","onClose","onCancel","onConfirm","children"],c=function(e){var n=e.title,o=e.cancelProps,c=e.confirmProps,s=e.buttonGroupProps,d=e.isOpen,f=e.closeOnCancel,m=void 0===f||f,p=e.closeOnConfirm,v=void 0===p||p,h=e.leastDestructiveFocus,C=void 0===h?"cancel":h,E=e.onClose,y=e.onCancel,O=e.onConfirm,M=e.children,b=i(e,u),D=l.useRef(null),g=l.useRef(null);/*#__PURE__*/return l.createElement(r.AlertDialog,a({isOpen:d,onClose:E},b,{leastDestructiveRef:"cancel"===C?D:g}),/*#__PURE__*/l.createElement(r.AlertDialogOverlay,null,/*#__PURE__*/l.createElement(r.AlertDialogContent,null,/*#__PURE__*/l.createElement(r.AlertDialogHeader,null,n),/*#__PURE__*/l.createElement(r.AlertDialogBody,null,M),/*#__PURE__*/l.createElement(r.AlertDialogFooter,null,/*#__PURE__*/l.createElement(t.ButtonGroup,s,/*#__PURE__*/l.createElement(t.Button,a({ref:D},o,{onClick:function(){null==y||y(),m&&E()}}),"Cancel"),/*#__PURE__*/l.createElement(t.Button,a({ref:g},c,{onClick:function(){null==O||O(),v&&E()}}),"Confirm"))))))},s=["title","children","isOpen","onClose","hideCloseButton","hideOverlay"],d=["footer","children"],f=function(e){var t=e.title,n=e.children,o=e.isOpen,u=e.onClose,c=e.hideCloseButton,d=e.hideOverlay,f=i(e,s);/*#__PURE__*/return l.createElement(r.Drawer,a({isOpen:o,onClose:u},f),!d&&/*#__PURE__*/l.createElement(r.DrawerOverlay,null),/*#__PURE__*/l.createElement(r.DrawerContent,null,/*#__PURE__*/l.createElement(r.DrawerHeader,null,t),!c&&/*#__PURE__*/l.createElement(r.DrawerCloseButton,null),n))},m=function(e){var t=e.footer,n=e.children,o=i(e,d);/*#__PURE__*/return l.createElement(f,o,/*#__PURE__*/l.createElement(r.DrawerBody,null,n),t&&/*#__PURE__*/l.createElement(r.DrawerFooter,null,t))},p=["title","footer","children","isOpen","onClose","hideCloseButton","hideOverlay"],v=["children","footer"],h=function(e){var t=e.title,n=e.footer,o=e.children,u=e.isOpen,c=e.onClose,s=e.hideCloseButton,d=e.hideOverlay,f=i(e,p);/*#__PURE__*/return l.createElement(r.Modal,a({isOpen:u,onClose:c},f),!d&&/*#__PURE__*/l.createElement(r.ModalOverlay,null),/*#__PURE__*/l.createElement(r.ModalContent,null,t&&/*#__PURE__*/l.createElement(r.ModalHeader,null,t),!s&&/*#__PURE__*/l.createElement(r.ModalCloseButton,null),o,n&&/*#__PURE__*/l.createElement(r.ModalFooter,null,n)))},C=function(e){var t=e.children,n=i(e,v);/*#__PURE__*/return l.createElement(h,n,/*#__PURE__*/l.createElement(r.ModalBody,null,t))},E=["children","footer","isOpen","onClose"],y=["descendants"],O=["rootProps"],M=function(e){var t=e.children,n=e.footer,o=e.isOpen,u=e.onClose,c=i(e,E),s=r.useMultiStyleConfig("Menu",e),d=r.useTheme(),f=r.useMenu({onClose:u,autoSelect:!0,defaultIsOpen:!0,closeOnBlur:!1,direction:d.direction}),m=f.descendants,p=i(f,y),v=l.useMemo(function(){return p},[p]);return l.useEffect(function(){p.openAndFocusFirstItem()},[e.isOpen]),/*#__PURE__*/l.createElement(h,a({isOpen:o,onClose:u,initialFocusRef:p.menuRef},c),/*#__PURE__*/l.createElement(r.MenuDescendantsProvider,{value:m},/*#__PURE__*/l.createElement(r.MenuProvider,{value:v},/*#__PURE__*/l.createElement(r.StylesProvider,{value:s},t))),n&&/*#__PURE__*/l.createElement(r.ModalFooter,null,n))};M.defaultProps={variant:"dialog"};var b=r.forwardRef(function(e,t){var n=i(e,O),o=r.useMenuList(n,t),u=r.useStyles();/*#__PURE__*/return l.createElement(r.chakra.div,a({},o,{__css:a({outline:0,maxHeight:"80vh",overflowY:"auto"},u.list,{boxShadow:"none",border:0})}))}),D=["children","schema","defaultValues","onSubmit","reValidateMode","shouldFocusError","shouldUnregister","shouldUseNativeValidation","criteriaMode","delayError","cancelLabel","submitLabel","footer","isOpen","onClose"],g=function(e){var o=e.children,u=e.schema,c=e.defaultValues,s=e.onSubmit,d=e.reValidateMode,f=e.shouldFocusError,m=void 0===f||f,p=e.shouldUnregister,v=e.shouldUseNativeValidation,C=e.criteriaMode,E=e.delayError,y=e.cancelLabel,O=e.submitLabel,M=e.footer,b=e.isOpen,g=e.onClose,P=i(e,D),x={schema:u,defaultValues:c,onSubmit:s,reValidateMode:d,shouldFocusError:m,shouldUnregister:p,shouldUseNativeValidation:v,criteriaMode:C,delayError:E},w=l.useRef(null);/*#__PURE__*/return l.createElement(h,a({isOpen:b,onClose:g,initialFocusRef:w},P),/*#__PURE__*/l.createElement(n.Form,x,/*#__PURE__*/l.createElement(r.ModalBody,null,o||/*#__PURE__*/l.createElement(n.Fields,{schema:u})),M||/*#__PURE__*/l.createElement(r.ModalFooter,null,/*#__PURE__*/l.createElement(t.Button,{variant:"ghost",mr:3,onClick:g},y||"Cancel"),/*#__PURE__*/l.createElement(n.SubmitButton,{ref:w},O||"Submit"))))},P=["id","type","scope"],x=["title","body","children"],w=l.createContext({}),B={id:null,props:null,type:"modal"},F={alert:c,confirm:c,drawer:m,modal:C,menu:M,form:g},S=function(){return l.useContext(w)};exports.BaseDrawer=f,exports.BaseModal=h,exports.ConfirmDialog=c,exports.Drawer=m,exports.FormDialog=g,exports.MenuDialog=M,exports.MenuDialogList=b,exports.Modal=C,exports.ModalsContext=w,exports.ModalsProvider=function(e){var r=e.children,t=e.modals,n=l.useMemo(function(){return new Set},[]),o=l.useState({modal:B}),u=o[0],c=o[1],s=l.useMemo(function(){var e=a({},F,t);return function(r){return void 0===r&&(r="modal"),e[r]||e.modal}},[t]),d=function(e,r){if(!r)return c({modal:e});c(function(t){var n;return a({},t,((n={})[r]=e,n))})},f=function(e){var r=e.id,t=void 0===r?n.size+1:r,o=e.type,l=void 0===o?"modal":o,a=e.scope,u=void 0===a?"modal":a,c={id:t,props:i(e,P),type:l,scope:u};return n.add(c),d(c,u),t},m=function(e,r){try{var t,o=[].concat(Array.from(n)),l=o.filter(function(r){return r.id===e})[0];return l?Promise.resolve(null==(t=l.props)||null==t.onClose?void 0:t.onClose({force:r})).then(function(e){if(!1!==e){n.delete(l);var r=o.filter(function(e){return e.scope===l.scope});d(r[r.length-2]||{id:null,props:null,type:l.type},l.scope)}}):Promise.resolve()}catch(e){return Promise.reject(e)}},p={open:f,drawer:function(e){return f(a({},e,{type:"drawer"}))},alert:function(e){return f(a({},e,{scope:"alert",type:"alert",cancelProps:{display:"none"},confirmProps:{label:"OK"},leastDestructiveFocus:"confirm"}))},confirm:function(e){return f(a({},e,{scope:"alert",type:"confirm"}))},menu:function(e){return f(a({},e,{type:"menu"}))},form:function(e){return f(a({},e,{type:"form"}))},close:m,closeAll:function(){n.forEach(function(e){var r;return null==(r=e.props)||null==r.onClose?void 0:r.onClose({force:!0})}),n.clear(),d(B)}},v=Object.entries(u).map(function(e){var r=e[0],t=e[1],o=s(t.type),u=t.props||{},c=u.title,d=u.body,f=u.children,p=i(u,x);/*#__PURE__*/return l.createElement(o,a({key:r,title:c,children:d||f},p,{isOpen:!(!t.id||!n.size),onClose:function(){return m(t.id)}}))});/*#__PURE__*/return l.createElement(w.Provider,{value:p},v,r)},exports.useModals=function(){return S()},exports.useModalsContext=S;
1
+ var e=require("react"),r=require("@chakra-ui/react"),n=require("@saas-ui/button"),t=require("@saas-ui/forms");function o(e){if(e&&e.__esModule)return e;var r=Object.create(null);return e&&Object.keys(e).forEach(function(n){if("default"!==n){var t=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(r,n,t.get?t:{enumerable:!0,get:function(){return e[n]}})}}),r.default=e,r}var l=/*#__PURE__*/o(e);function a(){return a=Object.assign||function(e){for(var r=1;r<arguments.length;r++){var n=arguments[r];for(var t in n)Object.prototype.hasOwnProperty.call(n,t)&&(e[t]=n[t])}return e},a.apply(this,arguments)}function i(e,r){if(null==e)return{};var n,t,o={},l=Object.keys(e);for(t=0;t<l.length;t++)r.indexOf(n=l[t])>=0||(o[n]=e[n]);return o}var u=["title","cancelLabel","confirmLabel","cancelProps","confirmProps","buttonGroupProps","isOpen","closeOnCancel","closeOnConfirm","leastDestructiveFocus","onClose","onCancel","onConfirm","children"],c=function(e){var t=e.title,o=e.cancelProps,c=e.confirmProps,s=e.buttonGroupProps,d=e.isOpen,f=e.closeOnCancel,m=void 0===f||f,p=e.closeOnConfirm,v=void 0===p||p,h=e.leastDestructiveFocus,E=void 0===h?"cancel":h,C=e.onClose,y=e.onCancel,O=e.onConfirm,M=e.children,b=i(e,u),D=l.useRef(null),g=l.useRef(null);/*#__PURE__*/return l.createElement(r.AlertDialog,a({isOpen:d,onClose:C},b,{leastDestructiveRef:"cancel"===E?D:g}),/*#__PURE__*/l.createElement(r.AlertDialogOverlay,null,/*#__PURE__*/l.createElement(r.AlertDialogContent,null,/*#__PURE__*/l.createElement(r.AlertDialogHeader,null,t),/*#__PURE__*/l.createElement(r.AlertDialogBody,null,M),/*#__PURE__*/l.createElement(r.AlertDialogFooter,null,/*#__PURE__*/l.createElement(n.ButtonGroup,s,/*#__PURE__*/l.createElement(n.Button,a({ref:D},o,{onClick:function(){null==y||y(),m&&C()}}),"Cancel"),/*#__PURE__*/l.createElement(n.Button,a({ref:g},c,{onClick:function(){null==O||O(),v&&C()}}),"Confirm"))))))},s=["title","children","isOpen","onClose","hideCloseButton","hideOverlay"],d=["footer","children"],f=function(e){var n=e.title,t=e.children,o=e.isOpen,u=e.onClose,c=e.hideCloseButton,d=e.hideOverlay,f=i(e,s);/*#__PURE__*/return l.createElement(r.Drawer,a({isOpen:o,onClose:u},f),!d&&/*#__PURE__*/l.createElement(r.DrawerOverlay,null),/*#__PURE__*/l.createElement(r.DrawerContent,null,/*#__PURE__*/l.createElement(r.DrawerHeader,null,n),!c&&/*#__PURE__*/l.createElement(r.DrawerCloseButton,null),t))},m=function(e){var n=e.footer,t=e.children,o=i(e,d);/*#__PURE__*/return l.createElement(f,o,/*#__PURE__*/l.createElement(r.DrawerBody,null,t),n&&/*#__PURE__*/l.createElement(r.DrawerFooter,null,n))},p=["title","footer","children","isOpen","onClose","hideCloseButton","hideOverlay"],v=["children","footer"],h=function(e){var n=e.title,t=e.footer,o=e.children,u=e.isOpen,c=e.onClose,s=e.hideCloseButton,d=e.hideOverlay,f=i(e,p);/*#__PURE__*/return l.createElement(r.Modal,a({isOpen:u,onClose:c},f),!d&&/*#__PURE__*/l.createElement(r.ModalOverlay,null),/*#__PURE__*/l.createElement(r.ModalContent,null,n&&/*#__PURE__*/l.createElement(r.ModalHeader,null,n),!s&&/*#__PURE__*/l.createElement(r.ModalCloseButton,null),o,t&&/*#__PURE__*/l.createElement(r.ModalFooter,null,t)))},E=function(e){var n=e.children,t=i(e,v);/*#__PURE__*/return l.createElement(h,t,/*#__PURE__*/l.createElement(r.ModalBody,null,n))},C=["children","footer","isOpen","onClose"],y=["descendants"],O=["rootProps"],M=function(e){var n=e.children,t=e.footer,o=e.isOpen,u=e.onClose,c=i(e,C),s=r.useMultiStyleConfig("Menu",e),d=r.useTheme(),f=r.useMenu({onClose:u,autoSelect:!0,defaultIsOpen:!0,closeOnBlur:!1,direction:d.direction}),m=f.descendants,p=i(f,y),v=l.useMemo(function(){return p},[p]);return l.useEffect(function(){p.openAndFocusFirstItem()},[e.isOpen]),/*#__PURE__*/l.createElement(h,a({isOpen:o,onClose:u,initialFocusRef:p.menuRef},c),/*#__PURE__*/l.createElement(r.MenuDescendantsProvider,{value:m},/*#__PURE__*/l.createElement(r.MenuProvider,{value:v},/*#__PURE__*/l.createElement(r.StylesProvider,{value:s},n))),t&&/*#__PURE__*/l.createElement(r.ModalFooter,null,t))};M.defaultProps={variant:"dialog"};var b=r.forwardRef(function(e,n){var t=i(e,O),o=r.useMenuList(t,n),u=r.useStyles();/*#__PURE__*/return l.createElement(r.chakra.div,a({},o,{__css:a({outline:0,maxHeight:"80vh",overflowY:"auto"},u.list,{boxShadow:"none",border:0})}))}),D=["children","schema","resolver","fieldResolver","defaultValues","onSubmit","onError","reValidateMode","shouldFocusError","shouldUnregister","shouldUseNativeValidation","criteriaMode","delayError","cancelLabel","submitLabel","footer","isOpen","onClose"],g=r.forwardRef(function(e,o){var u=e.children,c=e.schema,s=e.fieldResolver,d=e.defaultValues,f=e.onSubmit,m=e.onError,p=e.reValidateMode,v=e.shouldFocusError,E=void 0===v||v,C=e.shouldUnregister,y=e.shouldUseNativeValidation,O=e.criteriaMode,M=e.delayError,b=e.cancelLabel,g=e.submitLabel,P=e.footer,w=e.isOpen,x=e.onClose,B=i(e,D),F={ref:o,schema:c,defaultValues:d,onSubmit:f,onError:m,reValidateMode:p,shouldFocusError:E,shouldUnregister:C,shouldUseNativeValidation:y,criteriaMode:O,delayError:M},R=l.useRef(null);/*#__PURE__*/return l.createElement(h,a({isOpen:w,onClose:x,initialFocusRef:R},B),/*#__PURE__*/l.createElement(t.Form,F,/*#__PURE__*/l.createElement(r.ModalBody,null,u||/*#__PURE__*/l.createElement(t.Fields,{schema:c,fieldResolver:s})),P||/*#__PURE__*/l.createElement(r.ModalFooter,null,/*#__PURE__*/l.createElement(n.Button,{variant:"ghost",mr:3,onClick:x},b||"Cancel"),/*#__PURE__*/l.createElement(t.SubmitButton,{ref:R},g||"Submit"))))}),P=["id","type","scope","component"],w=["title","body","children"],x=l.createContext(null),B={id:null,props:null,type:"modal"},F={alert:c,confirm:c,drawer:m,modal:E,menu:M,form:g},R=function(){return l.useContext(x)};exports.BaseDrawer=f,exports.BaseModal=h,exports.ConfirmDialog=c,exports.Drawer=m,exports.FormDialog=g,exports.MenuDialog=M,exports.MenuDialogList=b,exports.Modal=E,exports.ModalsContext=x,exports.ModalsProvider=function(e){var r=e.children,n=e.modals,t=l.useMemo(function(){return new Set},[]),o=l.useState({modal:B}),u=o[0],c=o[1],s=l.useMemo(function(){var e=a({},F,n);return function(r){return void 0===r&&(r="modal"),e[r]||e.modal}},[n]),d=function(e,r){if(!r)return c({modal:e});c(function(n){var t;return a({},n,((t={})[r]=e,t))})},f=function(e){"function"==typeof e&&(e={component:e});var r=e.id,n=void 0===r?t.size+1:r,o=e.type,l=void 0===o?"modal":o,a=e.scope,u=void 0===a?"modal":a,c=e.component,s={id:n,props:i(e,P),type:l,scope:u,component:c};return t.add(s),d(s,u),n},m=function(e,r){try{var n,o=[].concat(Array.from(t)),l=o.filter(function(r){return r.id===e})[0];return l?Promise.resolve(null==(n=l.props)||null==n.onClose?void 0:n.onClose({force:r})).then(function(e){if(!1!==e){t.delete(l);var r=o.filter(function(e){return e.scope===l.scope});d(r[r.length-2]||{id:null,props:null,type:l.type},l.scope)}}):Promise.resolve()}catch(e){return Promise.reject(e)}},p={open:f,drawer:function(e){return f(a({},e,{type:"drawer"}))},alert:function(e){return f(a({},e,{scope:"alert",type:"alert",cancelProps:{display:"none"},confirmProps:{label:"OK"},leastDestructiveFocus:"confirm"}))},confirm:function(e){return f(a({},e,{scope:"alert",type:"confirm"}))},menu:function(e){return f(a({},e,{type:"menu"}))},form:function(e){return f(a({},e,{type:"form"}))},close:m,closeAll:function(){t.forEach(function(e){var r;return null==(r=e.props)||null==r.onClose?void 0:r.onClose({force:!0})}),t.clear(),d(B)}},v=Object.entries(u).map(function(e){var r=e[0],n=e[1],o=n.component||s(n.type),u=n.props||{},c=u.title,d=u.body,f=u.children,p=i(u,w);/*#__PURE__*/return l.createElement(o,a({key:r,title:c,children:d||f},p,{isOpen:!(!n.id||!t.size),onClose:function(){return m(n.id)}}))});/*#__PURE__*/return l.createElement(x.Provider,{value:p},v,r)},exports.useModals=function(){return R()},exports.useModalsContext=R;
2
2
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/dialog.tsx","../src/drawer.tsx","../src/modal.tsx","../src/menu.tsx","../src/form.tsx","../src/provider.tsx"],"sourcesContent":["import * as React from 'react'\n\nimport {\n AlertDialog,\n AlertDialogBody,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogContent,\n AlertDialogOverlay,\n AlertDialogProps,\n} from '@chakra-ui/react'\n\nimport {\n ButtonGroup,\n ButtonGroupProps,\n Button,\n ButtonProps,\n} from '@saas-ui/button'\n\nexport interface ConfirmDialogProps\n extends Omit<AlertDialogProps, 'leastDestructiveRef'> {\n /**\n * The dialog title\n */\n title?: React.ReactNode\n /**\n * The cancel button label\n */\n cancelLabel?: React.ReactNode\n /**\n * The confirm button label\n */\n confirmLabel?: React.ReactNode\n /**\n * The cancel button props\n */\n cancelProps?: ButtonProps\n /**\n * The confirm button props\n */\n confirmProps?: ButtonProps\n /**\n * The button group props\n */\n buttonGroupProps?: ButtonGroupProps\n /**\n * Close the dialog on cancel\n * @default true\n */\n closeOnCancel?: boolean\n /**\n * Close the dialog on confirm\n * @default true\n */\n closeOnConfirm?: boolean\n /**\n * Defines which button gets initial focus\n * https://www.w3.org/TR/wai-aria-practices/#alertdialog\n */\n leastDestructiveFocus?: 'cancel' | 'confirm'\n /**\n * Function that's called when cancel is clicked\n */\n onCancel?: () => void\n /**\n * Function that's called when confirm is clicked\n */\n onConfirm?: () => void\n}\n\nexport const ConfirmDialog: React.FC<ConfirmDialogProps> = (props) => {\n const {\n title,\n cancelLabel = 'Cancel',\n confirmLabel = 'Confirm',\n cancelProps,\n confirmProps,\n buttonGroupProps,\n isOpen,\n closeOnCancel = true,\n closeOnConfirm = true,\n leastDestructiveFocus = 'cancel',\n onClose,\n onCancel,\n onConfirm,\n children,\n ...rest\n } = props\n\n const cancelRef = React.useRef(null)\n const confirmRef = React.useRef(null)\n\n return (\n <AlertDialog\n isOpen={isOpen}\n onClose={onClose}\n {...rest}\n leastDestructiveRef={\n leastDestructiveFocus === 'cancel' ? cancelRef : confirmRef\n }\n >\n <AlertDialogOverlay>\n <AlertDialogContent>\n <AlertDialogHeader>{title}</AlertDialogHeader>\n\n <AlertDialogBody>{children}</AlertDialogBody>\n\n <AlertDialogFooter>\n <ButtonGroup {...buttonGroupProps}>\n <Button\n ref={cancelRef}\n {...cancelProps}\n onClick={() => {\n onCancel?.()\n\n closeOnCancel && onClose()\n }}\n >\n Cancel\n </Button>\n <Button\n ref={confirmRef}\n {...confirmProps}\n onClick={() => {\n onConfirm?.()\n\n closeOnConfirm && onClose()\n }}\n >\n Confirm\n </Button>\n </ButtonGroup>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialogOverlay>\n </AlertDialog>\n )\n}\n","import * as React from 'react'\n\nimport {\n Drawer as ChakraDrawer,\n DrawerOverlay,\n DrawerContent,\n DrawerHeader,\n DrawerFooter,\n DrawerBody,\n DrawerCloseButton,\n DrawerProps as ChakraDrawerProps,\n} from '@chakra-ui/react'\n\nexport interface BaseDrawerProps extends Omit<ChakraDrawerProps, 'children'> {\n /**\n * The drawer title\n */\n title: React.ReactNode\n /**\n * Hide the close button\n */\n hideCloseButton?: boolean\n /**\n * Hide the overflow\n */\n hideOverlay?: boolean\n children?: React.ReactNode\n}\n\nexport const BaseDrawer: React.FC<BaseDrawerProps> = (props) => {\n const {\n title,\n children,\n isOpen,\n onClose,\n hideCloseButton,\n hideOverlay,\n ...rest\n } = props\n return (\n <ChakraDrawer isOpen={isOpen} onClose={onClose} {...rest}>\n {!hideOverlay && <DrawerOverlay />}\n <DrawerContent>\n <DrawerHeader>{title}</DrawerHeader>\n {!hideCloseButton && <DrawerCloseButton />}\n {children}\n </DrawerContent>\n </ChakraDrawer>\n )\n}\n\nexport interface DrawerProps extends BaseDrawerProps {\n /**\n * Drawer footer content, wrapped with `DrawerFooter`\n */\n footer?: React.ReactNode\n}\n\nexport const Drawer: React.FC<DrawerProps> = (props) => {\n const { footer, children, ...rest } = props\n return (\n <BaseDrawer {...rest}>\n <DrawerBody>{children}</DrawerBody>\n\n {footer && <DrawerFooter>{footer}</DrawerFooter>}\n </BaseDrawer>\n )\n}\n","import * as React from 'react'\n\nimport {\n Modal as ChakraModal,\n ModalOverlay,\n ModalContent,\n ModalHeader,\n ModalFooter,\n ModalBody,\n ModalCloseButton,\n ModalProps as ChakraModalProps,\n} from '@chakra-ui/react'\n\nexport interface BaseModalProps extends ChakraModalProps {\n /**\n * The modal title\n */\n title?: React.ReactNode\n /**\n * The modal footer\n */\n footer?: React.ReactNode\n /**\n * Hide the close button\n */\n hideCloseButton?: boolean\n /**\n * Hide the overlay\n */\n hideOverlay?: boolean\n}\n\nexport const BaseModal: React.FC<BaseModalProps> = (props) => {\n const {\n title,\n footer,\n children,\n isOpen,\n onClose,\n hideCloseButton,\n hideOverlay,\n ...rest\n } = props\n return (\n <ChakraModal isOpen={isOpen} onClose={onClose} {...rest}>\n {!hideOverlay && <ModalOverlay />}\n <ModalContent>\n {title && <ModalHeader>{title}</ModalHeader>}\n {!hideCloseButton && <ModalCloseButton />}\n {children}\n {footer && <ModalFooter>{footer}</ModalFooter>}\n </ModalContent>\n </ChakraModal>\n )\n}\n\nexport const Modal: React.FC<BaseModalProps> = (props) => {\n const { children, footer, ...rest } = props\n return (\n <BaseModal {...rest}>\n <ModalBody>{children}</ModalBody>\n </BaseModal>\n )\n}\n","import * as React from 'react'\n\nimport {\n ModalFooter,\n MenuDescendantsProvider,\n MenuProvider,\n MenuListProps,\n useMenu,\n useMenuList,\n chakra,\n StylesProvider,\n useMultiStyleConfig,\n useTheme,\n useStyles,\n forwardRef,\n} from '@chakra-ui/react'\n\nimport { BaseModal, BaseModalProps } from './modal'\n\nexport interface MenuDialogProps extends BaseModalProps {\n /**\n * The modal footer, wrapped with `ModalFooter`\n */\n footer?: React.ReactNode\n}\n\nexport const MenuDialog: React.FC<MenuDialogProps> = (props) => {\n const { children, footer, isOpen, onClose, ...rest } = props\n\n const styles = useMultiStyleConfig('Menu', props)\n const { direction } = useTheme()\n const { descendants, ...ctx } = useMenu({\n onClose,\n autoSelect: true,\n defaultIsOpen: true,\n closeOnBlur: false,\n direction,\n })\n const context = React.useMemo(() => ctx, [ctx])\n\n React.useEffect(() => {\n ctx.openAndFocusFirstItem()\n }, [props.isOpen])\n\n return (\n <BaseModal\n isOpen={isOpen}\n onClose={onClose}\n initialFocusRef={ctx.menuRef}\n {...rest}\n >\n <MenuDescendantsProvider value={descendants}>\n <MenuProvider value={context}>\n <StylesProvider value={styles}>{children}</StylesProvider>\n </MenuProvider>\n </MenuDescendantsProvider>\n\n {footer && <ModalFooter>{footer}</ModalFooter>}\n </BaseModal>\n )\n}\n\nMenuDialog.defaultProps = {\n variant: 'dialog',\n}\n\nexport const MenuDialogList = forwardRef<MenuListProps, 'div'>((props, ref) => {\n const { rootProps, ...rest } = props\n\n const ownProps = useMenuList(rest, ref) as any\n\n const styles = useStyles()\n\n return (\n <chakra.div\n {...ownProps}\n __css={{\n outline: 0,\n maxHeight: '80vh', // can override this in theme\n overflowY: 'auto', // can override this in theme\n ...styles.list,\n boxShadow: 'none',\n border: 0,\n }}\n />\n )\n})\n","import * as React from 'react'\n\nimport { ModalBody, ModalFooter } from '@chakra-ui/react'\n\nimport { Form, Fields, SubmitButton, FormProps } from '@saas-ui/forms'\nimport { Button } from '@saas-ui/button'\n\nimport { BaseModal, BaseModalProps } from './modal'\n\nexport interface FormDialogProps\n extends Omit<BaseModalProps, 'children'>,\n Pick<\n FormProps,\n | 'schema'\n | 'defaultValues'\n | 'onSubmit'\n | 'resolver'\n | 'mode'\n | 'reValidateMode'\n | 'shouldFocusError'\n | 'shouldUnregister'\n | 'shouldUseNativeValidation'\n | 'criteriaMode'\n | 'delayError'\n > {\n /**\n * The modal footer, will be wrapped with `ModalFooter`.\n * Defaults to a cancel and submit button.\n */\n footer?: React.ReactNode\n /**\n * The cancel button label\n * @default \"Cancel\"\n */\n cancelLabel?: React.ReactNode\n /**\n * The submit button label\n * @default \"Submit\"\n */\n submitLabel?: React.ReactNode\n /**\n * If no children are passed, this will auto render fields based on the supplied schema.\n */\n children?: React.ReactNode\n}\n\nexport const FormDialog: React.FC<FormDialogProps> = (props) => {\n const {\n children,\n schema,\n defaultValues,\n onSubmit,\n reValidateMode,\n shouldFocusError = true,\n shouldUnregister,\n shouldUseNativeValidation,\n criteriaMode,\n delayError,\n cancelLabel,\n submitLabel,\n footer,\n isOpen,\n onClose,\n ...rest\n } = props\n\n const formProps = {\n schema,\n defaultValues,\n onSubmit,\n reValidateMode,\n shouldFocusError,\n shouldUnregister,\n shouldUseNativeValidation,\n criteriaMode,\n delayError,\n }\n\n const initialRef = React.useRef<HTMLButtonElement | null>(null)\n\n return (\n <BaseModal\n isOpen={isOpen}\n onClose={onClose}\n initialFocusRef={initialRef}\n {...rest}\n >\n <Form {...formProps}>\n <ModalBody>{children || <Fields schema={schema} />}</ModalBody>\n\n {footer || (\n <ModalFooter>\n <Button variant=\"ghost\" mr={3} onClick={onClose}>\n {cancelLabel || 'Cancel'}\n </Button>\n <SubmitButton ref={initialRef}>\n {submitLabel || 'Submit'}\n </SubmitButton>\n </ModalFooter>\n )}\n </Form>\n </BaseModal>\n )\n}\n","import * as React from 'react'\n\nimport { Modal, BaseModalProps } from './modal'\nimport { Drawer, DrawerProps } from './drawer'\nimport { ConfirmDialog, ConfirmDialogProps } from './dialog'\nimport { MenuDialog, MenuDialogProps } from './menu'\nimport { FormDialog, FormDialogProps } from './form'\n\nexport interface ModalsContextValue {\n open?: (options: OpenOptions) => ModalId\n drawer?: (options: DrawerOptions) => ModalId\n alert?: (options: ConfirmDialogOptions) => ModalId\n confirm?: (options: ConfirmDialogOptions) => ModalId\n menu?: (options: MenuDialogOptions) => ModalId\n form?: (options: FormDialogOptions) => ModalId\n close?: (id: ModalId) => void\n closeAll?: () => void\n}\n\nexport const ModalsContext = React.createContext<ModalsContextValue>({})\n\ninterface ModalsProviderProps {\n children: React.ReactNode\n modals?: Record<string, React.FC<any>>\n}\n\nexport type ModalId = string | number\n\ninterface ModalOptions\n extends Omit<BaseModalProps, 'onClose' | 'isOpen' | 'children'> {\n onClose?: (args: { force?: boolean }) => Promise<boolean | undefined> | void\n body?: React.ReactNode\n children?: React.ReactNode\n [key: string]: any\n}\n\nexport interface DrawerOptions\n extends ModalOptions,\n Omit<DrawerProps, 'onClose' | 'isOpen' | 'children' | 'title' | 'size'> {}\n\nexport interface ConfirmDialogOptions\n extends ModalOptions,\n Omit<ConfirmDialogProps, 'onClose' | 'isOpen' | 'children'> {}\n\nexport interface MenuDialogOptions\n extends ModalOptions,\n Omit<MenuDialogProps, 'onClose' | 'isOpen' | 'children'> {}\n\nexport interface FormDialogOptions\n extends ModalOptions,\n Omit<FormDialogProps, 'onClose' | 'isOpen' | 'children'> {}\n\nexport interface OpenOptions extends ModalOptions {\n type?: ModalTypes | string\n scope?: ModalScopes\n}\n\nexport type ModalScopes = 'modal' | 'alert'\n\nexport type ModalTypes = 'modal' | 'drawer' | 'alert' | 'confirm' | 'menu'\n\nexport interface ModalConfig<\n TModalOptions extends ModalOptions = ModalOptions\n> {\n /**\n * The modal id, autogenerated when not set.\n * Can be used to close modals.\n */\n id?: ModalId | null\n /**\n * The modal props\n */\n props?: TModalOptions | null\n /**\n * The modal scope\n * Modals can only have one level per scope.\n * The default scopes are 'modal' and 'alert', alerts can be openend above modals.\n */\n scope?: ModalScopes | string\n /**\n * The modal type to open.\n * Build in types are 'modal', 'drawer', 'alert', 'confirm'\n *\n * Custom types can be configured using the `modals` prop of `ModalProvider`\n */\n type?: ModalTypes | string\n}\n\nconst initialModalState: ModalConfig = {\n id: null,\n props: null,\n type: 'modal',\n}\n\nconst defaultModals = {\n alert: ConfirmDialog,\n confirm: ConfirmDialog,\n drawer: Drawer,\n modal: Modal,\n menu: MenuDialog,\n form: FormDialog,\n}\n\nexport function ModalsProvider({ children, modals }: ModalsProviderProps) {\n // Note that updating the Set doesn't trigger a re-render,\n // use in conjuction with setActiveModals\n const _instances = React.useMemo(() => new Set<ModalConfig>(), [])\n\n const [activeModals, setActiveModals] = React.useState<\n Record<string, ModalConfig>\n >({\n modal: initialModalState,\n })\n\n const getModalComponent = React.useMemo(() => {\n const _modals = {\n ...defaultModals,\n ...modals,\n }\n\n return (type = 'modal') => {\n const component = _modals[type] || _modals.modal\n\n return component\n }\n }, [modals])\n\n const setActiveModal = (modal: ModalConfig, scope?: string) => {\n if (!scope) {\n return setActiveModals({\n modal,\n })\n }\n setActiveModals((prevState) => ({\n ...prevState,\n [scope]: modal,\n }))\n }\n\n const open = <T extends ModalOptions>(options: T): ModalId => {\n const {\n id = _instances.size + 1,\n type = 'modal',\n scope = 'modal',\n ...props\n } = options\n\n const modal: ModalConfig<T> = {\n id,\n props: props as T,\n type,\n scope,\n }\n\n _instances.add(modal)\n setActiveModal(modal, scope)\n\n return id\n }\n\n const drawer = (options: DrawerOptions): ModalId => {\n return open<DrawerOptions>({\n ...options,\n type: 'drawer',\n })\n }\n\n const alert = (options: ConfirmDialogOptions): ModalId => {\n return open({\n ...options,\n scope: 'alert',\n type: 'alert',\n cancelProps: {\n display: 'none',\n },\n confirmProps: {\n label: 'OK',\n },\n leastDestructiveFocus: 'confirm',\n })\n }\n\n const confirm = (options: ConfirmDialogOptions): ModalId => {\n return open<ConfirmDialogOptions>({\n ...options,\n scope: 'alert',\n type: 'confirm',\n })\n }\n\n const menu = (options: MenuDialogOptions): ModalId => {\n return open<MenuDialogOptions>({\n ...options,\n type: 'menu',\n })\n }\n\n const form = (options: FormDialogOptions): ModalId => {\n return open<FormDialogOptions>({\n ...options,\n type: 'form',\n })\n }\n\n const close = async (id?: ModalId | null, force?: boolean) => {\n const modals = [...Array.from(_instances)]\n const modal = modals.filter((modal) => modal.id === id)[0]\n\n if (!modal) {\n return\n }\n\n const shouldClose = await modal.props?.onClose?.({ force })\n if (shouldClose === false) {\n return\n }\n\n _instances.delete(modal)\n\n const scoped = modals.filter(({ scope }) => scope === modal.scope)\n\n setActiveModal(\n scoped[scoped.length - 2] || {\n id: null,\n props: null,\n type: modal.type, // Keep type same as last modal type to make sure the animation isn't interrupted\n },\n modal.scope\n )\n }\n\n const closeAll = () => {\n _instances.forEach((modal) => modal.props?.onClose?.({ force: true }))\n _instances.clear()\n\n setActiveModal(initialModalState)\n }\n\n const context = {\n open,\n drawer,\n alert,\n confirm,\n menu,\n form,\n close,\n closeAll,\n }\n\n const content = Object.entries(activeModals).map(([scope, config]) => {\n const Component = getModalComponent(config.type)\n\n const { title, body, children, ...props } = config.props || {}\n\n return (\n <Component\n key={scope}\n title={title}\n children={body || children}\n {...props}\n isOpen={!!(config.id && _instances.size)}\n onClose={() => close(config.id)}\n />\n )\n })\n\n return (\n <ModalsContext.Provider value={context}>\n {content}\n {children}\n </ModalsContext.Provider>\n )\n}\n\nexport const useModalsContext = (): ModalsContextValue =>\n React.useContext(ModalsContext)\n\nexport const useModals = () => {\n return useModalsContext()\n}\n"],"names":["ConfirmDialog","props","title","cancelProps","confirmProps","buttonGroupProps","isOpen","closeOnCancel","closeOnConfirm","leastDestructiveFocus","onClose","onCancel","onConfirm","children","rest","cancelRef","React","useRef","confirmRef","AlertDialog","leastDestructiveRef","AlertDialogOverlay","AlertDialogContent","AlertDialogHeader","AlertDialogBody","AlertDialogFooter","ButtonGroup","Button","ref","onClick","BaseDrawer","hideCloseButton","hideOverlay","ChakraDrawer","DrawerOverlay","DrawerContent","DrawerHeader","DrawerCloseButton","Drawer","footer","DrawerBody","DrawerFooter","BaseModal","ChakraModal","ModalOverlay","ModalContent","ModalHeader","ModalCloseButton","ModalFooter","Modal","ModalBody","MenuDialog","styles","useMultiStyleConfig","useTheme","useMenu","autoSelect","defaultIsOpen","closeOnBlur","direction","descendants","ctx","context","useMemo","useEffect","openAndFocusFirstItem","initialFocusRef","menuRef","MenuDescendantsProvider","value","MenuProvider","StylesProvider","defaultProps","variant","MenuDialogList","forwardRef","rootProps","ownProps","useMenuList","useStyles","chakra","div","__css","outline","maxHeight","overflowY","list","boxShadow","border","FormDialog","schema","defaultValues","onSubmit","reValidateMode","shouldFocusError","shouldUnregister","shouldUseNativeValidation","criteriaMode","delayError","cancelLabel","submitLabel","formProps","initialRef","Form","Fields","mr","SubmitButton","ModalsContext","createContext","initialModalState","id","type","defaultModals","alert","confirm","drawer","modal","menu","form","useModalsContext","useContext","modals","_instances","Set","useState","activeModals","setActiveModals","getModalComponent","_modals","setActiveModal","scope","prevState","open","options","size","add","close","force","Array","from","filter","_modal$props","shouldClose","scoped","length","display","label","closeAll","forEach","_modal$props2","clear","content","Object","entries","map","config","Component","body","key","Provider"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/dialog.tsx","../src/drawer.tsx","../src/modal.tsx","../src/menu.tsx","../src/form.tsx","../src/provider.tsx"],"sourcesContent":["import * as React from 'react'\n\nimport {\n AlertDialog,\n AlertDialogBody,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogContent,\n AlertDialogOverlay,\n AlertDialogProps,\n} from '@chakra-ui/react'\n\nimport {\n ButtonGroup,\n ButtonGroupProps,\n Button,\n ButtonProps,\n} from '@saas-ui/button'\n\nexport interface ConfirmDialogProps\n extends Omit<AlertDialogProps, 'leastDestructiveRef'> {\n /**\n * The dialog title\n */\n title?: React.ReactNode\n /**\n * The cancel button label\n */\n cancelLabel?: React.ReactNode\n /**\n * The confirm button label\n */\n confirmLabel?: React.ReactNode\n /**\n * The cancel button props\n */\n cancelProps?: ButtonProps\n /**\n * The confirm button props\n */\n confirmProps?: ButtonProps\n /**\n * The button group props\n */\n buttonGroupProps?: ButtonGroupProps\n /**\n * Close the dialog on cancel\n * @default true\n */\n closeOnCancel?: boolean\n /**\n * Close the dialog on confirm\n * @default true\n */\n closeOnConfirm?: boolean\n /**\n * Defines which button gets initial focus\n * https://www.w3.org/TR/wai-aria-practices/#alertdialog\n */\n leastDestructiveFocus?: 'cancel' | 'confirm'\n /**\n * Function that's called when cancel is clicked\n */\n onCancel?: () => void\n /**\n * Function that's called when confirm is clicked\n */\n onConfirm?: () => void\n}\n\nexport const ConfirmDialog: React.FC<ConfirmDialogProps> = (props) => {\n const {\n title,\n cancelLabel = 'Cancel',\n confirmLabel = 'Confirm',\n cancelProps,\n confirmProps,\n buttonGroupProps,\n isOpen,\n closeOnCancel = true,\n closeOnConfirm = true,\n leastDestructiveFocus = 'cancel',\n onClose,\n onCancel,\n onConfirm,\n children,\n ...rest\n } = props\n\n const cancelRef = React.useRef(null)\n const confirmRef = React.useRef(null)\n\n return (\n <AlertDialog\n isOpen={isOpen}\n onClose={onClose}\n {...rest}\n leastDestructiveRef={\n leastDestructiveFocus === 'cancel' ? cancelRef : confirmRef\n }\n >\n <AlertDialogOverlay>\n <AlertDialogContent>\n <AlertDialogHeader>{title}</AlertDialogHeader>\n\n <AlertDialogBody>{children}</AlertDialogBody>\n\n <AlertDialogFooter>\n <ButtonGroup {...buttonGroupProps}>\n <Button\n ref={cancelRef}\n {...cancelProps}\n onClick={() => {\n onCancel?.()\n\n closeOnCancel && onClose()\n }}\n >\n Cancel\n </Button>\n <Button\n ref={confirmRef}\n {...confirmProps}\n onClick={() => {\n onConfirm?.()\n\n closeOnConfirm && onClose()\n }}\n >\n Confirm\n </Button>\n </ButtonGroup>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialogOverlay>\n </AlertDialog>\n )\n}\n","import * as React from 'react'\n\nimport {\n Drawer as ChakraDrawer,\n DrawerOverlay,\n DrawerContent,\n DrawerHeader,\n DrawerFooter,\n DrawerBody,\n DrawerCloseButton,\n DrawerProps as ChakraDrawerProps,\n} from '@chakra-ui/react'\n\nexport interface BaseDrawerProps extends Omit<ChakraDrawerProps, 'children'> {\n /**\n * The drawer title\n */\n title: React.ReactNode\n /**\n * Hide the close button\n */\n hideCloseButton?: boolean\n /**\n * Hide the overflow\n */\n hideOverlay?: boolean\n children?: React.ReactNode\n}\n\nexport const BaseDrawer: React.FC<BaseDrawerProps> = (props) => {\n const {\n title,\n children,\n isOpen,\n onClose,\n hideCloseButton,\n hideOverlay,\n ...rest\n } = props\n return (\n <ChakraDrawer isOpen={isOpen} onClose={onClose} {...rest}>\n {!hideOverlay && <DrawerOverlay />}\n <DrawerContent>\n <DrawerHeader>{title}</DrawerHeader>\n {!hideCloseButton && <DrawerCloseButton />}\n {children}\n </DrawerContent>\n </ChakraDrawer>\n )\n}\n\nexport interface DrawerProps extends BaseDrawerProps {\n /**\n * Drawer footer content, wrapped with `DrawerFooter`\n */\n footer?: React.ReactNode\n}\n\nexport const Drawer: React.FC<DrawerProps> = (props) => {\n const { footer, children, ...rest } = props\n return (\n <BaseDrawer {...rest}>\n <DrawerBody>{children}</DrawerBody>\n\n {footer && <DrawerFooter>{footer}</DrawerFooter>}\n </BaseDrawer>\n )\n}\n","import * as React from 'react'\n\nimport {\n Modal as ChakraModal,\n ModalOverlay,\n ModalContent,\n ModalHeader,\n ModalFooter,\n ModalBody,\n ModalCloseButton,\n ModalProps as ChakraModalProps,\n} from '@chakra-ui/react'\n\nexport interface BaseModalProps extends ChakraModalProps {\n /**\n * The modal title\n */\n title?: React.ReactNode\n /**\n * The modal footer\n */\n footer?: React.ReactNode\n /**\n * Hide the close button\n */\n hideCloseButton?: boolean\n /**\n * Hide the overlay\n */\n hideOverlay?: boolean\n}\n\nexport const BaseModal: React.FC<BaseModalProps> = (props) => {\n const {\n title,\n footer,\n children,\n isOpen,\n onClose,\n hideCloseButton,\n hideOverlay,\n ...rest\n } = props\n return (\n <ChakraModal isOpen={isOpen} onClose={onClose} {...rest}>\n {!hideOverlay && <ModalOverlay />}\n <ModalContent>\n {title && <ModalHeader>{title}</ModalHeader>}\n {!hideCloseButton && <ModalCloseButton />}\n {children}\n {footer && <ModalFooter>{footer}</ModalFooter>}\n </ModalContent>\n </ChakraModal>\n )\n}\n\nexport const Modal: React.FC<BaseModalProps> = (props) => {\n const { children, footer, ...rest } = props\n return (\n <BaseModal {...rest}>\n <ModalBody>{children}</ModalBody>\n </BaseModal>\n )\n}\n","import * as React from 'react'\n\nimport {\n ModalFooter,\n MenuDescendantsProvider,\n MenuProvider,\n MenuListProps,\n useMenu,\n useMenuList,\n chakra,\n StylesProvider,\n useMultiStyleConfig,\n useTheme,\n useStyles,\n forwardRef,\n} from '@chakra-ui/react'\n\nimport { BaseModal, BaseModalProps } from './modal'\n\nexport interface MenuDialogProps extends BaseModalProps {\n /**\n * The modal footer, wrapped with `ModalFooter`\n */\n footer?: React.ReactNode\n}\n\nexport const MenuDialog: React.FC<MenuDialogProps> = (props) => {\n const { children, footer, isOpen, onClose, ...rest } = props\n\n const styles = useMultiStyleConfig('Menu', props)\n const { direction } = useTheme()\n const { descendants, ...ctx } = useMenu({\n onClose,\n autoSelect: true,\n defaultIsOpen: true,\n closeOnBlur: false,\n direction,\n })\n const context = React.useMemo(() => ctx, [ctx])\n\n React.useEffect(() => {\n ctx.openAndFocusFirstItem()\n }, [props.isOpen])\n\n return (\n <BaseModal\n isOpen={isOpen}\n onClose={onClose}\n initialFocusRef={ctx.menuRef}\n {...rest}\n >\n <MenuDescendantsProvider value={descendants}>\n <MenuProvider value={context}>\n <StylesProvider value={styles}>{children}</StylesProvider>\n </MenuProvider>\n </MenuDescendantsProvider>\n\n {footer && <ModalFooter>{footer}</ModalFooter>}\n </BaseModal>\n )\n}\n\nMenuDialog.defaultProps = {\n variant: 'dialog',\n}\n\nexport const MenuDialogList = forwardRef<MenuListProps, 'div'>((props, ref) => {\n const { rootProps, ...rest } = props\n\n const ownProps = useMenuList(rest, ref) as any\n\n const styles = useStyles()\n\n return (\n <chakra.div\n {...ownProps}\n __css={{\n outline: 0,\n maxHeight: '80vh', // can override this in theme\n overflowY: 'auto', // can override this in theme\n ...styles.list,\n boxShadow: 'none',\n border: 0,\n }}\n />\n )\n})\n","import * as React from 'react'\n\nimport { ModalBody, ModalFooter, forwardRef } from '@chakra-ui/react'\n\nimport {\n Form,\n Fields,\n SubmitButton,\n FormProps,\n FieldValues,\n FieldResolver,\n UseFormReturn,\n} from '@saas-ui/forms'\nimport { Button } from '@saas-ui/button'\n\nimport { BaseModal, BaseModalProps } from './modal'\n\nexport interface FormDialogProps<TFieldValues extends FieldValues = FieldValues>\n extends Omit<BaseModalProps, 'children'>,\n Pick<\n FormProps<TFieldValues>,\n | 'schema'\n | 'defaultValues'\n | 'onSubmit'\n | 'onError'\n | 'resolver'\n | 'mode'\n | 'reValidateMode'\n | 'shouldFocusError'\n | 'shouldUnregister'\n | 'shouldUseNativeValidation'\n | 'criteriaMode'\n | 'delayError'\n > {\n /**\n * The modal footer, will be wrapped with `ModalFooter`.\n * Defaults to a cancel and submit button.\n */\n footer?: React.ReactNode\n /**\n * The cancel button label\n * @default \"Cancel\"\n */\n cancelLabel?: React.ReactNode\n /**\n * The submit button label\n * @default \"Submit\"\n */\n submitLabel?: React.ReactNode\n /**\n * If no children are passed, this will auto render fields based on the supplied schema.\n */\n children?: React.ReactNode\n /**\n * A schema field resolver used to auto generate form fields.\n */\n fieldResolver?: FieldResolver\n}\n\nexport const FormDialog = forwardRef(\n <TFieldValues extends FieldValues = FieldValues>(\n props: FormDialogProps<TFieldValues>,\n ref: React.ForwardedRef<UseFormReturn<TFieldValues>>\n ) => {\n const {\n children,\n schema,\n resolver,\n fieldResolver,\n defaultValues,\n onSubmit,\n onError,\n reValidateMode,\n shouldFocusError = true,\n shouldUnregister,\n shouldUseNativeValidation,\n criteriaMode,\n delayError,\n cancelLabel,\n submitLabel,\n footer,\n isOpen,\n onClose,\n ...rest\n } = props\n\n const formProps = {\n ref,\n schema,\n defaultValues,\n onSubmit,\n onError,\n reValidateMode,\n shouldFocusError,\n shouldUnregister,\n shouldUseNativeValidation,\n criteriaMode,\n delayError,\n }\n\n const initialRef = React.useRef<HTMLButtonElement | null>(null)\n\n return (\n <BaseModal\n isOpen={isOpen}\n onClose={onClose}\n initialFocusRef={initialRef}\n {...rest}\n >\n <Form {...formProps}>\n <ModalBody>\n {children || (\n <Fields schema={schema} fieldResolver={fieldResolver} />\n )}\n </ModalBody>\n\n {footer || (\n <ModalFooter>\n <Button variant=\"ghost\" mr={3} onClick={onClose}>\n {cancelLabel || 'Cancel'}\n </Button>\n <SubmitButton ref={initialRef}>\n {submitLabel || 'Submit'}\n </SubmitButton>\n </ModalFooter>\n )}\n </Form>\n </BaseModal>\n )\n }\n) as <TFieldValues extends FieldValues>(\n props: FormDialogProps<TFieldValues> & {\n ref?: React.ForwardedRef<UseFormReturn<TFieldValues>>\n }\n) => React.ReactElement\n","import * as React from 'react'\n\nimport { Modal, BaseModalProps } from './modal'\nimport { Drawer, DrawerProps } from './drawer'\nimport { ConfirmDialog, ConfirmDialogProps } from './dialog'\nimport { MenuDialog, MenuDialogProps } from './menu'\nimport { FormDialog, FormDialogProps } from './form'\n\nexport interface ModalsContextValue {\n open: (options: OpenOptions) => ModalId\n drawer: (options: DrawerOptions) => ModalId\n alert: (options: ConfirmDialogOptions) => ModalId\n confirm: (options: ConfirmDialogOptions) => ModalId\n menu: (options: MenuDialogOptions) => ModalId\n form: (options: FormDialogOptions) => ModalId\n close: (id: ModalId) => void\n closeAll: () => void\n}\n\nexport const ModalsContext = React.createContext<ModalsContextValue | null>(\n null\n)\n\ninterface ModalsProviderProps {\n children: React.ReactNode\n modals?: Record<string, React.FC<any>>\n}\n\nexport type ModalId = string | number\n\ninterface ModalOptions\n extends Omit<BaseModalProps, 'onClose' | 'isOpen' | 'children'> {\n onClose?: (args: { force?: boolean }) => Promise<boolean | undefined> | void\n body?: React.ReactNode\n children?: React.ReactNode\n [key: string]: any\n}\n\nexport interface DrawerOptions\n extends ModalOptions,\n Omit<DrawerProps, 'onClose' | 'isOpen' | 'children' | 'title' | 'size'> {}\n\nexport interface ConfirmDialogOptions\n extends ModalOptions,\n Omit<ConfirmDialogProps, 'onClose' | 'isOpen' | 'children'> {}\n\nexport interface MenuDialogOptions\n extends ModalOptions,\n Omit<MenuDialogProps, 'onClose' | 'isOpen' | 'children'> {}\n\nexport interface FormDialogOptions\n extends ModalOptions,\n Omit<FormDialogProps, 'onClose' | 'isOpen' | 'children'> {}\n\nexport interface OpenOptions extends ModalOptions {\n type?: ModalTypes\n scope?: ModalScopes\n}\n\nexport type ModalScopes = 'modal' | 'alert'\n\nexport type ModalTypes =\n | 'modal'\n | 'drawer'\n | 'alert'\n | 'confirm'\n | 'menu'\n | string\n\nexport interface ModalConfig<\n TModalOptions extends ModalOptions = ModalOptions\n> {\n /**\n * The modal id, autogenerated when not set.\n * Can be used to close modals.\n */\n id?: ModalId | null\n /**\n * The modal props\n */\n props?: TModalOptions | null\n /**\n * The modal scope\n * Modals can only have one level per scope.\n * The default scopes are 'modal' and 'alert', alerts can be openend above modals.\n */\n scope?: ModalScopes | string\n /**\n * The modal type to open.\n * Build in types are 'modal', 'drawer', 'alert', 'confirm'\n *\n * Custom types can be configured using the `modals` prop of `ModalProvider`\n */\n type?: ModalTypes\n /**\n * Render a custom modal component.\n * This will ignore the `type` param.\n */\n component?: React.FC<BaseModalProps>\n}\n\nconst initialModalState: ModalConfig = {\n id: null,\n props: null,\n type: 'modal',\n}\n\nconst defaultModals = {\n alert: ConfirmDialog,\n confirm: ConfirmDialog,\n drawer: Drawer,\n modal: Modal,\n menu: MenuDialog,\n form: FormDialog,\n}\n\nexport function ModalsProvider({ children, modals }: ModalsProviderProps) {\n // Note that updating the Set doesn't trigger a re-render,\n // use in conjuction with setActiveModals\n const _instances = React.useMemo(() => new Set<ModalConfig>(), [])\n\n const [activeModals, setActiveModals] = React.useState<\n Record<string, ModalConfig>\n >({\n modal: initialModalState,\n })\n\n const getModalComponent = React.useMemo(() => {\n const _modals = {\n ...defaultModals,\n ...modals,\n }\n\n return (type: ModalTypes = 'modal') => {\n const component = _modals[type] || _modals.modal\n\n return component\n }\n }, [modals])\n\n const setActiveModal = (modal: ModalConfig, scope?: string) => {\n if (!scope) {\n return setActiveModals({\n modal,\n })\n }\n setActiveModals((prevState) => ({\n ...prevState,\n [scope]: modal,\n }))\n }\n\n const open = <T extends ModalOptions>(\n options: T | React.FC<BaseModalProps>\n ): ModalId => {\n if (typeof options === 'function') {\n const component: React.FC<BaseModalProps> = options\n options = {\n component,\n } as unknown as T\n }\n\n const {\n id = _instances.size + 1,\n type = 'modal',\n scope = 'modal',\n component,\n ...props\n } = options\n\n const modal: ModalConfig<T> = {\n id,\n props: props as T,\n type,\n scope,\n component,\n }\n\n _instances.add(modal)\n setActiveModal(modal, scope)\n\n return id\n }\n\n const drawer = (options: DrawerOptions): ModalId => {\n return open<DrawerOptions>({\n ...options,\n type: 'drawer',\n })\n }\n\n const alert = (options: ConfirmDialogOptions): ModalId => {\n return open({\n ...options,\n scope: 'alert',\n type: 'alert',\n cancelProps: {\n display: 'none',\n },\n confirmProps: {\n label: 'OK',\n },\n leastDestructiveFocus: 'confirm',\n })\n }\n\n const confirm = (options: ConfirmDialogOptions): ModalId => {\n return open<ConfirmDialogOptions>({\n ...options,\n scope: 'alert',\n type: 'confirm',\n })\n }\n\n const menu = (options: MenuDialogOptions): ModalId => {\n return open<MenuDialogOptions>({\n ...options,\n type: 'menu',\n })\n }\n\n const form = (options: FormDialogOptions): ModalId => {\n return open<FormDialogOptions>({\n ...options,\n type: 'form',\n })\n }\n\n const close = async (id?: ModalId | null, force?: boolean) => {\n const modals = [...Array.from(_instances)]\n const modal = modals.filter((modal) => modal.id === id)[0]\n\n if (!modal) {\n return\n }\n\n const shouldClose = await modal.props?.onClose?.({ force })\n if (shouldClose === false) {\n return\n }\n\n _instances.delete(modal)\n\n const scoped = modals.filter(({ scope }) => scope === modal.scope)\n\n setActiveModal(\n scoped[scoped.length - 2] || {\n id: null,\n props: null,\n type: modal.type, // Keep type same as last modal type to make sure the animation isn't interrupted\n },\n modal.scope\n )\n }\n\n const closeAll = () => {\n _instances.forEach((modal) => modal.props?.onClose?.({ force: true }))\n _instances.clear()\n\n setActiveModal(initialModalState)\n }\n\n const context = {\n open,\n drawer,\n alert,\n confirm,\n menu,\n form,\n close,\n closeAll,\n }\n\n const content = Object.entries(activeModals).map(([scope, config]) => {\n const Component = config.component || getModalComponent(config.type)\n\n const { title, body, children, ...props } = config.props || {}\n\n return (\n <Component\n key={scope}\n title={title}\n children={body || children}\n {...props}\n isOpen={!!(config.id && _instances.size)}\n onClose={() => close(config.id)}\n />\n )\n })\n\n return (\n <ModalsContext.Provider value={context}>\n {content}\n {children}\n </ModalsContext.Provider>\n )\n}\n\nexport const useModalsContext = () =>\n React.useContext(ModalsContext) as ModalsContextValue\n\nexport const useModals = () => {\n return useModalsContext()\n}\n"],"names":["ConfirmDialog","props","title","cancelProps","confirmProps","buttonGroupProps","isOpen","closeOnCancel","closeOnConfirm","leastDestructiveFocus","onClose","onCancel","onConfirm","children","rest","cancelRef","React","useRef","confirmRef","AlertDialog","leastDestructiveRef","AlertDialogOverlay","AlertDialogContent","AlertDialogHeader","AlertDialogBody","AlertDialogFooter","ButtonGroup","Button","ref","onClick","BaseDrawer","hideCloseButton","hideOverlay","ChakraDrawer","DrawerOverlay","DrawerContent","DrawerHeader","DrawerCloseButton","Drawer","footer","DrawerBody","DrawerFooter","BaseModal","ChakraModal","ModalOverlay","ModalContent","ModalHeader","ModalCloseButton","ModalFooter","Modal","ModalBody","MenuDialog","styles","useMultiStyleConfig","useTheme","useMenu","autoSelect","defaultIsOpen","closeOnBlur","direction","descendants","ctx","context","useMemo","useEffect","openAndFocusFirstItem","initialFocusRef","menuRef","MenuDescendantsProvider","value","MenuProvider","StylesProvider","defaultProps","variant","MenuDialogList","forwardRef","rootProps","ownProps","useMenuList","useStyles","chakra","div","__css","outline","maxHeight","overflowY","list","boxShadow","border","FormDialog","schema","fieldResolver","defaultValues","onSubmit","onError","reValidateMode","shouldFocusError","shouldUnregister","shouldUseNativeValidation","criteriaMode","delayError","cancelLabel","submitLabel","formProps","initialRef","Form","Fields","mr","SubmitButton","ModalsContext","createContext","initialModalState","id","type","defaultModals","alert","confirm","drawer","modal","menu","form","useModalsContext","useContext","modals","_instances","Set","useState","activeModals","setActiveModals","getModalComponent","_modals","setActiveModal","scope","prevState","open","options","component","size","add","close","force","Array","from","filter","_modal$props","shouldClose","scoped","length","display","label","closeAll","forEach","_modal$props2","clear","content","Object","entries","map","config","Component","body","key","Provider"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import*as e from"react";import{AlertDialog as l,AlertDialogOverlay as n,AlertDialogContent as t,AlertDialogHeader as r,AlertDialogBody as o,AlertDialogFooter as a,Drawer as c,DrawerOverlay as s,DrawerContent as i,DrawerHeader as u,DrawerCloseButton as m,DrawerBody as d,DrawerFooter as p,Modal as f,ModalOverlay as h,ModalContent as E,ModalHeader as C,ModalCloseButton as O,ModalFooter as v,ModalBody as y,forwardRef as b,useMenuList as P,useStyles as M,chakra as g,useMultiStyleConfig as F,useTheme as w,useMenu as V,MenuDescendantsProvider as L,MenuProvider as S,StylesProvider as R}from"@chakra-ui/react";import{ButtonGroup as k,Button as x}from"@saas-ui/button";import{Form as U,Fields as B,SubmitButton as D}from"@saas-ui/forms";function j(){return j=Object.assign||function(e){for(var l=1;l<arguments.length;l++){var n=arguments[l];for(var t in n)Object.prototype.hasOwnProperty.call(n,t)&&(e[t]=n[t])}return e},j.apply(this,arguments)}function A(e,l){if(null==e)return{};var n,t,r={},o=Object.keys(e);for(t=0;t<o.length;t++)l.indexOf(n=o[t])>=0||(r[n]=e[n]);return r}const N=["title","cancelLabel","confirmLabel","cancelProps","confirmProps","buttonGroupProps","isOpen","closeOnCancel","closeOnConfirm","leastDestructiveFocus","onClose","onCancel","onConfirm","children"],z=c=>{const{title:s,cancelLabel:i="Cancel",confirmLabel:u="Confirm",cancelProps:m,confirmProps:d,buttonGroupProps:p,isOpen:f,closeOnCancel:h=!0,closeOnConfirm:E=!0,leastDestructiveFocus:C="cancel",onClose:O,onCancel:v,onConfirm:y,children:b}=c,P=A(c,N),M=e.useRef(null),g=e.useRef(null);/*#__PURE__*/return e.createElement(l,j({isOpen:f,onClose:O},P,{leastDestructiveRef:"cancel"===C?M:g}),/*#__PURE__*/e.createElement(n,null,/*#__PURE__*/e.createElement(t,null,/*#__PURE__*/e.createElement(r,null,s),/*#__PURE__*/e.createElement(o,null,b),/*#__PURE__*/e.createElement(a,null,/*#__PURE__*/e.createElement(k,p,/*#__PURE__*/e.createElement(x,j({ref:M},m,{onClick:()=>{null==v||v(),h&&O()}}),"Cancel"),/*#__PURE__*/e.createElement(x,j({ref:g},d,{onClick:()=>{null==y||y(),E&&O()}}),"Confirm"))))))},G=["title","children","isOpen","onClose","hideCloseButton","hideOverlay"],I=["footer","children"],_=l=>{const{title:n,children:t,isOpen:r,onClose:o,hideCloseButton:a,hideOverlay:d}=l,p=A(l,G);/*#__PURE__*/return e.createElement(c,j({isOpen:r,onClose:o},p),!d&&/*#__PURE__*/e.createElement(s,null),/*#__PURE__*/e.createElement(i,null,/*#__PURE__*/e.createElement(u,null,n),!a&&/*#__PURE__*/e.createElement(m,null),t))},H=l=>{const{footer:n,children:t}=l,r=A(l,I);/*#__PURE__*/return e.createElement(_,r,/*#__PURE__*/e.createElement(d,null,t),n&&/*#__PURE__*/e.createElement(p,null,n))},K=["title","footer","children","isOpen","onClose","hideCloseButton","hideOverlay"],Y=["children","footer"],q=l=>{const{title:n,footer:t,children:r,isOpen:o,onClose:a,hideCloseButton:c,hideOverlay:s}=l,i=A(l,K);/*#__PURE__*/return e.createElement(f,j({isOpen:o,onClose:a},i),!s&&/*#__PURE__*/e.createElement(h,null),/*#__PURE__*/e.createElement(E,null,n&&/*#__PURE__*/e.createElement(C,null,n),!c&&/*#__PURE__*/e.createElement(O,null),r,t&&/*#__PURE__*/e.createElement(v,null,t)))},J=l=>{const{children:n}=l,t=A(l,Y);/*#__PURE__*/return e.createElement(q,t,/*#__PURE__*/e.createElement(y,null,n))},Q=["children","footer","isOpen","onClose"],T=["descendants"],W=["rootProps"],X=l=>{const{children:n,footer:t,isOpen:r,onClose:o}=l,a=A(l,Q),c=F("Menu",l),{direction:s}=w(),i=V({onClose:o,autoSelect:!0,defaultIsOpen:!0,closeOnBlur:!1,direction:s}),{descendants:u}=i,m=A(i,T),d=e.useMemo(()=>m,[m]);return e.useEffect(()=>{m.openAndFocusFirstItem()},[l.isOpen]),/*#__PURE__*/e.createElement(q,j({isOpen:r,onClose:o,initialFocusRef:m.menuRef},a),/*#__PURE__*/e.createElement(L,{value:u},/*#__PURE__*/e.createElement(S,{value:d},/*#__PURE__*/e.createElement(R,{value:c},n))),t&&/*#__PURE__*/e.createElement(v,null,t))};X.defaultProps={variant:"dialog"};const Z=b((l,n)=>{const t=A(l,W),r=P(t,n),o=M();/*#__PURE__*/return e.createElement(g.div,j({},r,{__css:j({outline:0,maxHeight:"80vh",overflowY:"auto"},o.list,{boxShadow:"none",border:0})}))}),$=["children","schema","defaultValues","onSubmit","reValidateMode","shouldFocusError","shouldUnregister","shouldUseNativeValidation","criteriaMode","delayError","cancelLabel","submitLabel","footer","isOpen","onClose"],ee=l=>{const{children:n,schema:t,defaultValues:r,onSubmit:o,reValidateMode:a,shouldFocusError:c=!0,shouldUnregister:s,shouldUseNativeValidation:i,criteriaMode:u,delayError:m,cancelLabel:d,submitLabel:p,footer:f,isOpen:h,onClose:E}=l,C=A(l,$),O={schema:t,defaultValues:r,onSubmit:o,reValidateMode:a,shouldFocusError:c,shouldUnregister:s,shouldUseNativeValidation:i,criteriaMode:u,delayError:m},b=e.useRef(null);/*#__PURE__*/return e.createElement(q,j({isOpen:h,onClose:E,initialFocusRef:b},C),/*#__PURE__*/e.createElement(U,O,/*#__PURE__*/e.createElement(y,null,n||/*#__PURE__*/e.createElement(B,{schema:t})),f||/*#__PURE__*/e.createElement(v,null,/*#__PURE__*/e.createElement(x,{variant:"ghost",mr:3,onClick:E},d||"Cancel"),/*#__PURE__*/e.createElement(D,{ref:b},p||"Submit"))))},le=["id","type","scope"],ne=["title","body","children"],te=e.createContext({}),re={id:null,props:null,type:"modal"},oe={alert:z,confirm:z,drawer:H,modal:J,menu:X,form:ee};function ae({children:l,modals:n}){const t=e.useMemo(()=>new Set,[]),[r,o]=e.useState({modal:re}),a=e.useMemo(()=>{const e=j({},oe,n);return(l="modal")=>e[l]||e.modal},[n]),c=(e,l)=>{if(!l)return o({modal:e});o(n=>j({},n,{[l]:e}))},s=e=>{const{id:l=t.size+1,type:n="modal",scope:r="modal"}=e,o={id:l,props:A(e,le),type:n,scope:r};return t.add(o),c(o,r),l},i=async(e,l)=>{var n;const r=[...Array.from(t)],o=r.filter(l=>l.id===e)[0];if(!o)return;if(!1===await(null==(n=o.props)||null==n.onClose?void 0:n.onClose({force:l})))return;t.delete(o);const a=r.filter(({scope:e})=>e===o.scope);c(a[a.length-2]||{id:null,props:null,type:o.type},o.scope)},u={open:s,drawer:e=>s(j({},e,{type:"drawer"})),alert:e=>s(j({},e,{scope:"alert",type:"alert",cancelProps:{display:"none"},confirmProps:{label:"OK"},leastDestructiveFocus:"confirm"})),confirm:e=>s(j({},e,{scope:"alert",type:"confirm"})),menu:e=>s(j({},e,{type:"menu"})),form:e=>s(j({},e,{type:"form"})),close:i,closeAll:()=>{t.forEach(e=>{var l;return null==(l=e.props)||null==l.onClose?void 0:l.onClose({force:!0})}),t.clear(),c(re)}},m=Object.entries(r).map(([l,n])=>{const r=a(n.type),o=n.props||{},{title:c,body:s,children:u}=o,m=A(o,ne);/*#__PURE__*/return e.createElement(r,j({key:l,title:c,children:s||u},m,{isOpen:!(!n.id||!t.size),onClose:()=>i(n.id)}))});/*#__PURE__*/return e.createElement(te.Provider,{value:u},m,l)}const ce=()=>e.useContext(te),se=()=>ce();export{_ as BaseDrawer,q as BaseModal,z as ConfirmDialog,H as Drawer,ee as FormDialog,X as MenuDialog,Z as MenuDialogList,J as Modal,te as ModalsContext,ae as ModalsProvider,se as useModals,ce as useModalsContext};
1
+ import*as e from"react";import{AlertDialog as n,AlertDialogOverlay as l,AlertDialogContent as t,AlertDialogHeader as o,AlertDialogBody as r,AlertDialogFooter as c,Drawer as a,DrawerOverlay as s,DrawerContent as i,DrawerHeader as u,DrawerCloseButton as m,DrawerBody as d,DrawerFooter as p,Modal as f,ModalOverlay as E,ModalContent as h,ModalHeader as C,ModalCloseButton as O,ModalFooter as v,ModalBody as y,forwardRef as b,useMenuList as P,useStyles as M,chakra as g,useMultiStyleConfig as F,useTheme as R,useMenu as w,MenuDescendantsProvider as V,MenuProvider as L,StylesProvider as S}from"@chakra-ui/react";import{ButtonGroup as k,Button as x}from"@saas-ui/button";import{Form as U,Fields as B,SubmitButton as D}from"@saas-ui/forms";function j(){return j=Object.assign||function(e){for(var n=1;n<arguments.length;n++){var l=arguments[n];for(var t in l)Object.prototype.hasOwnProperty.call(l,t)&&(e[t]=l[t])}return e},j.apply(this,arguments)}function A(e,n){if(null==e)return{};var l,t,o={},r=Object.keys(e);for(t=0;t<r.length;t++)n.indexOf(l=r[t])>=0||(o[l]=e[l]);return o}const N=["title","cancelLabel","confirmLabel","cancelProps","confirmProps","buttonGroupProps","isOpen","closeOnCancel","closeOnConfirm","leastDestructiveFocus","onClose","onCancel","onConfirm","children"],z=a=>{const{title:s,cancelLabel:i="Cancel",confirmLabel:u="Confirm",cancelProps:m,confirmProps:d,buttonGroupProps:p,isOpen:f,closeOnCancel:E=!0,closeOnConfirm:h=!0,leastDestructiveFocus:C="cancel",onClose:O,onCancel:v,onConfirm:y,children:b}=a,P=A(a,N),M=e.useRef(null),g=e.useRef(null);/*#__PURE__*/return e.createElement(n,j({isOpen:f,onClose:O},P,{leastDestructiveRef:"cancel"===C?M:g}),/*#__PURE__*/e.createElement(l,null,/*#__PURE__*/e.createElement(t,null,/*#__PURE__*/e.createElement(o,null,s),/*#__PURE__*/e.createElement(r,null,b),/*#__PURE__*/e.createElement(c,null,/*#__PURE__*/e.createElement(k,p,/*#__PURE__*/e.createElement(x,j({ref:M},m,{onClick:()=>{null==v||v(),E&&O()}}),"Cancel"),/*#__PURE__*/e.createElement(x,j({ref:g},d,{onClick:()=>{null==y||y(),h&&O()}}),"Confirm"))))))},G=["title","children","isOpen","onClose","hideCloseButton","hideOverlay"],I=["footer","children"],_=n=>{const{title:l,children:t,isOpen:o,onClose:r,hideCloseButton:c,hideOverlay:d}=n,p=A(n,G);/*#__PURE__*/return e.createElement(a,j({isOpen:o,onClose:r},p),!d&&/*#__PURE__*/e.createElement(s,null),/*#__PURE__*/e.createElement(i,null,/*#__PURE__*/e.createElement(u,null,l),!c&&/*#__PURE__*/e.createElement(m,null),t))},H=n=>{const{footer:l,children:t}=n,o=A(n,I);/*#__PURE__*/return e.createElement(_,o,/*#__PURE__*/e.createElement(d,null,t),l&&/*#__PURE__*/e.createElement(p,null,l))},K=["title","footer","children","isOpen","onClose","hideCloseButton","hideOverlay"],Y=["children","footer"],q=n=>{const{title:l,footer:t,children:o,isOpen:r,onClose:c,hideCloseButton:a,hideOverlay:s}=n,i=A(n,K);/*#__PURE__*/return e.createElement(f,j({isOpen:r,onClose:c},i),!s&&/*#__PURE__*/e.createElement(E,null),/*#__PURE__*/e.createElement(h,null,l&&/*#__PURE__*/e.createElement(C,null,l),!a&&/*#__PURE__*/e.createElement(O,null),o,t&&/*#__PURE__*/e.createElement(v,null,t)))},J=n=>{const{children:l}=n,t=A(n,Y);/*#__PURE__*/return e.createElement(q,t,/*#__PURE__*/e.createElement(y,null,l))},Q=["children","footer","isOpen","onClose"],T=["descendants"],W=["rootProps"],X=n=>{const{children:l,footer:t,isOpen:o,onClose:r}=n,c=A(n,Q),a=F("Menu",n),{direction:s}=R(),i=w({onClose:r,autoSelect:!0,defaultIsOpen:!0,closeOnBlur:!1,direction:s}),{descendants:u}=i,m=A(i,T),d=e.useMemo(()=>m,[m]);return e.useEffect(()=>{m.openAndFocusFirstItem()},[n.isOpen]),/*#__PURE__*/e.createElement(q,j({isOpen:o,onClose:r,initialFocusRef:m.menuRef},c),/*#__PURE__*/e.createElement(V,{value:u},/*#__PURE__*/e.createElement(L,{value:d},/*#__PURE__*/e.createElement(S,{value:a},l))),t&&/*#__PURE__*/e.createElement(v,null,t))};X.defaultProps={variant:"dialog"};const Z=b((n,l)=>{const t=A(n,W),o=P(t,l),r=M();/*#__PURE__*/return e.createElement(g.div,j({},o,{__css:j({outline:0,maxHeight:"80vh",overflowY:"auto"},r.list,{boxShadow:"none",border:0})}))}),$=["children","schema","resolver","fieldResolver","defaultValues","onSubmit","onError","reValidateMode","shouldFocusError","shouldUnregister","shouldUseNativeValidation","criteriaMode","delayError","cancelLabel","submitLabel","footer","isOpen","onClose"],ee=b((n,l)=>{const{children:t,schema:o,fieldResolver:r,defaultValues:c,onSubmit:a,onError:s,reValidateMode:i,shouldFocusError:u=!0,shouldUnregister:m,shouldUseNativeValidation:d,criteriaMode:p,delayError:f,cancelLabel:E,submitLabel:h,footer:C,isOpen:O,onClose:b}=n,P=A(n,$),M={ref:l,schema:o,defaultValues:c,onSubmit:a,onError:s,reValidateMode:i,shouldFocusError:u,shouldUnregister:m,shouldUseNativeValidation:d,criteriaMode:p,delayError:f},g=e.useRef(null);/*#__PURE__*/return e.createElement(q,j({isOpen:O,onClose:b,initialFocusRef:g},P),/*#__PURE__*/e.createElement(U,M,/*#__PURE__*/e.createElement(y,null,t||/*#__PURE__*/e.createElement(B,{schema:o,fieldResolver:r})),C||/*#__PURE__*/e.createElement(v,null,/*#__PURE__*/e.createElement(x,{variant:"ghost",mr:3,onClick:b},E||"Cancel"),/*#__PURE__*/e.createElement(D,{ref:g},h||"Submit"))))}),ne=["id","type","scope","component"],le=["title","body","children"],te=e.createContext(null),oe={id:null,props:null,type:"modal"},re={alert:z,confirm:z,drawer:H,modal:J,menu:X,form:ee};function ce({children:n,modals:l}){const t=e.useMemo(()=>new Set,[]),[o,r]=e.useState({modal:oe}),c=e.useMemo(()=>{const e=j({},re,l);return(n="modal")=>e[n]||e.modal},[l]),a=(e,n)=>{if(!n)return r({modal:e});r(l=>j({},l,{[n]:e}))},s=e=>{"function"==typeof e&&(e={component:e});const{id:n=t.size+1,type:l="modal",scope:o="modal",component:r}=e,c={id:n,props:A(e,ne),type:l,scope:o,component:r};return t.add(c),a(c,o),n},i=async(e,n)=>{var l;const o=[...Array.from(t)],r=o.filter(n=>n.id===e)[0];if(!r)return;if(!1===await(null==(l=r.props)||null==l.onClose?void 0:l.onClose({force:n})))return;t.delete(r);const c=o.filter(({scope:e})=>e===r.scope);a(c[c.length-2]||{id:null,props:null,type:r.type},r.scope)},u={open:s,drawer:e=>s(j({},e,{type:"drawer"})),alert:e=>s(j({},e,{scope:"alert",type:"alert",cancelProps:{display:"none"},confirmProps:{label:"OK"},leastDestructiveFocus:"confirm"})),confirm:e=>s(j({},e,{scope:"alert",type:"confirm"})),menu:e=>s(j({},e,{type:"menu"})),form:e=>s(j({},e,{type:"form"})),close:i,closeAll:()=>{t.forEach(e=>{var n;return null==(n=e.props)||null==n.onClose?void 0:n.onClose({force:!0})}),t.clear(),a(oe)}},m=Object.entries(o).map(([n,l])=>{const o=l.component||c(l.type),r=l.props||{},{title:a,body:s,children:u}=r,m=A(r,le);/*#__PURE__*/return e.createElement(o,j({key:n,title:a,children:s||u},m,{isOpen:!(!l.id||!t.size),onClose:()=>i(l.id)}))});/*#__PURE__*/return e.createElement(te.Provider,{value:u},m,n)}const ae=()=>e.useContext(te),se=()=>ae();export{_ as BaseDrawer,q as BaseModal,z as ConfirmDialog,H as Drawer,ee as FormDialog,X as MenuDialog,Z as MenuDialogList,J as Modal,te as ModalsContext,ce as ModalsProvider,se as useModals,ae as useModalsContext};
2
2
  //# sourceMappingURL=index.modern.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.modern.js","sources":["../src/dialog.tsx","../src/drawer.tsx","../src/modal.tsx","../src/menu.tsx","../src/form.tsx","../src/provider.tsx"],"sourcesContent":["import * as React from 'react'\n\nimport {\n AlertDialog,\n AlertDialogBody,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogContent,\n AlertDialogOverlay,\n AlertDialogProps,\n} from '@chakra-ui/react'\n\nimport {\n ButtonGroup,\n ButtonGroupProps,\n Button,\n ButtonProps,\n} from '@saas-ui/button'\n\nexport interface ConfirmDialogProps\n extends Omit<AlertDialogProps, 'leastDestructiveRef'> {\n /**\n * The dialog title\n */\n title?: React.ReactNode\n /**\n * The cancel button label\n */\n cancelLabel?: React.ReactNode\n /**\n * The confirm button label\n */\n confirmLabel?: React.ReactNode\n /**\n * The cancel button props\n */\n cancelProps?: ButtonProps\n /**\n * The confirm button props\n */\n confirmProps?: ButtonProps\n /**\n * The button group props\n */\n buttonGroupProps?: ButtonGroupProps\n /**\n * Close the dialog on cancel\n * @default true\n */\n closeOnCancel?: boolean\n /**\n * Close the dialog on confirm\n * @default true\n */\n closeOnConfirm?: boolean\n /**\n * Defines which button gets initial focus\n * https://www.w3.org/TR/wai-aria-practices/#alertdialog\n */\n leastDestructiveFocus?: 'cancel' | 'confirm'\n /**\n * Function that's called when cancel is clicked\n */\n onCancel?: () => void\n /**\n * Function that's called when confirm is clicked\n */\n onConfirm?: () => void\n}\n\nexport const ConfirmDialog: React.FC<ConfirmDialogProps> = (props) => {\n const {\n title,\n cancelLabel = 'Cancel',\n confirmLabel = 'Confirm',\n cancelProps,\n confirmProps,\n buttonGroupProps,\n isOpen,\n closeOnCancel = true,\n closeOnConfirm = true,\n leastDestructiveFocus = 'cancel',\n onClose,\n onCancel,\n onConfirm,\n children,\n ...rest\n } = props\n\n const cancelRef = React.useRef(null)\n const confirmRef = React.useRef(null)\n\n return (\n <AlertDialog\n isOpen={isOpen}\n onClose={onClose}\n {...rest}\n leastDestructiveRef={\n leastDestructiveFocus === 'cancel' ? cancelRef : confirmRef\n }\n >\n <AlertDialogOverlay>\n <AlertDialogContent>\n <AlertDialogHeader>{title}</AlertDialogHeader>\n\n <AlertDialogBody>{children}</AlertDialogBody>\n\n <AlertDialogFooter>\n <ButtonGroup {...buttonGroupProps}>\n <Button\n ref={cancelRef}\n {...cancelProps}\n onClick={() => {\n onCancel?.()\n\n closeOnCancel && onClose()\n }}\n >\n Cancel\n </Button>\n <Button\n ref={confirmRef}\n {...confirmProps}\n onClick={() => {\n onConfirm?.()\n\n closeOnConfirm && onClose()\n }}\n >\n Confirm\n </Button>\n </ButtonGroup>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialogOverlay>\n </AlertDialog>\n )\n}\n","import * as React from 'react'\n\nimport {\n Drawer as ChakraDrawer,\n DrawerOverlay,\n DrawerContent,\n DrawerHeader,\n DrawerFooter,\n DrawerBody,\n DrawerCloseButton,\n DrawerProps as ChakraDrawerProps,\n} from '@chakra-ui/react'\n\nexport interface BaseDrawerProps extends Omit<ChakraDrawerProps, 'children'> {\n /**\n * The drawer title\n */\n title: React.ReactNode\n /**\n * Hide the close button\n */\n hideCloseButton?: boolean\n /**\n * Hide the overflow\n */\n hideOverlay?: boolean\n children?: React.ReactNode\n}\n\nexport const BaseDrawer: React.FC<BaseDrawerProps> = (props) => {\n const {\n title,\n children,\n isOpen,\n onClose,\n hideCloseButton,\n hideOverlay,\n ...rest\n } = props\n return (\n <ChakraDrawer isOpen={isOpen} onClose={onClose} {...rest}>\n {!hideOverlay && <DrawerOverlay />}\n <DrawerContent>\n <DrawerHeader>{title}</DrawerHeader>\n {!hideCloseButton && <DrawerCloseButton />}\n {children}\n </DrawerContent>\n </ChakraDrawer>\n )\n}\n\nexport interface DrawerProps extends BaseDrawerProps {\n /**\n * Drawer footer content, wrapped with `DrawerFooter`\n */\n footer?: React.ReactNode\n}\n\nexport const Drawer: React.FC<DrawerProps> = (props) => {\n const { footer, children, ...rest } = props\n return (\n <BaseDrawer {...rest}>\n <DrawerBody>{children}</DrawerBody>\n\n {footer && <DrawerFooter>{footer}</DrawerFooter>}\n </BaseDrawer>\n )\n}\n","import * as React from 'react'\n\nimport {\n Modal as ChakraModal,\n ModalOverlay,\n ModalContent,\n ModalHeader,\n ModalFooter,\n ModalBody,\n ModalCloseButton,\n ModalProps as ChakraModalProps,\n} from '@chakra-ui/react'\n\nexport interface BaseModalProps extends ChakraModalProps {\n /**\n * The modal title\n */\n title?: React.ReactNode\n /**\n * The modal footer\n */\n footer?: React.ReactNode\n /**\n * Hide the close button\n */\n hideCloseButton?: boolean\n /**\n * Hide the overlay\n */\n hideOverlay?: boolean\n}\n\nexport const BaseModal: React.FC<BaseModalProps> = (props) => {\n const {\n title,\n footer,\n children,\n isOpen,\n onClose,\n hideCloseButton,\n hideOverlay,\n ...rest\n } = props\n return (\n <ChakraModal isOpen={isOpen} onClose={onClose} {...rest}>\n {!hideOverlay && <ModalOverlay />}\n <ModalContent>\n {title && <ModalHeader>{title}</ModalHeader>}\n {!hideCloseButton && <ModalCloseButton />}\n {children}\n {footer && <ModalFooter>{footer}</ModalFooter>}\n </ModalContent>\n </ChakraModal>\n )\n}\n\nexport const Modal: React.FC<BaseModalProps> = (props) => {\n const { children, footer, ...rest } = props\n return (\n <BaseModal {...rest}>\n <ModalBody>{children}</ModalBody>\n </BaseModal>\n )\n}\n","import * as React from 'react'\n\nimport {\n ModalFooter,\n MenuDescendantsProvider,\n MenuProvider,\n MenuListProps,\n useMenu,\n useMenuList,\n chakra,\n StylesProvider,\n useMultiStyleConfig,\n useTheme,\n useStyles,\n forwardRef,\n} from '@chakra-ui/react'\n\nimport { BaseModal, BaseModalProps } from './modal'\n\nexport interface MenuDialogProps extends BaseModalProps {\n /**\n * The modal footer, wrapped with `ModalFooter`\n */\n footer?: React.ReactNode\n}\n\nexport const MenuDialog: React.FC<MenuDialogProps> = (props) => {\n const { children, footer, isOpen, onClose, ...rest } = props\n\n const styles = useMultiStyleConfig('Menu', props)\n const { direction } = useTheme()\n const { descendants, ...ctx } = useMenu({\n onClose,\n autoSelect: true,\n defaultIsOpen: true,\n closeOnBlur: false,\n direction,\n })\n const context = React.useMemo(() => ctx, [ctx])\n\n React.useEffect(() => {\n ctx.openAndFocusFirstItem()\n }, [props.isOpen])\n\n return (\n <BaseModal\n isOpen={isOpen}\n onClose={onClose}\n initialFocusRef={ctx.menuRef}\n {...rest}\n >\n <MenuDescendantsProvider value={descendants}>\n <MenuProvider value={context}>\n <StylesProvider value={styles}>{children}</StylesProvider>\n </MenuProvider>\n </MenuDescendantsProvider>\n\n {footer && <ModalFooter>{footer}</ModalFooter>}\n </BaseModal>\n )\n}\n\nMenuDialog.defaultProps = {\n variant: 'dialog',\n}\n\nexport const MenuDialogList = forwardRef<MenuListProps, 'div'>((props, ref) => {\n const { rootProps, ...rest } = props\n\n const ownProps = useMenuList(rest, ref) as any\n\n const styles = useStyles()\n\n return (\n <chakra.div\n {...ownProps}\n __css={{\n outline: 0,\n maxHeight: '80vh', // can override this in theme\n overflowY: 'auto', // can override this in theme\n ...styles.list,\n boxShadow: 'none',\n border: 0,\n }}\n />\n )\n})\n","import * as React from 'react'\n\nimport { ModalBody, ModalFooter } from '@chakra-ui/react'\n\nimport { Form, Fields, SubmitButton, FormProps } from '@saas-ui/forms'\nimport { Button } from '@saas-ui/button'\n\nimport { BaseModal, BaseModalProps } from './modal'\n\nexport interface FormDialogProps\n extends Omit<BaseModalProps, 'children'>,\n Pick<\n FormProps,\n | 'schema'\n | 'defaultValues'\n | 'onSubmit'\n | 'resolver'\n | 'mode'\n | 'reValidateMode'\n | 'shouldFocusError'\n | 'shouldUnregister'\n | 'shouldUseNativeValidation'\n | 'criteriaMode'\n | 'delayError'\n > {\n /**\n * The modal footer, will be wrapped with `ModalFooter`.\n * Defaults to a cancel and submit button.\n */\n footer?: React.ReactNode\n /**\n * The cancel button label\n * @default \"Cancel\"\n */\n cancelLabel?: React.ReactNode\n /**\n * The submit button label\n * @default \"Submit\"\n */\n submitLabel?: React.ReactNode\n /**\n * If no children are passed, this will auto render fields based on the supplied schema.\n */\n children?: React.ReactNode\n}\n\nexport const FormDialog: React.FC<FormDialogProps> = (props) => {\n const {\n children,\n schema,\n defaultValues,\n onSubmit,\n reValidateMode,\n shouldFocusError = true,\n shouldUnregister,\n shouldUseNativeValidation,\n criteriaMode,\n delayError,\n cancelLabel,\n submitLabel,\n footer,\n isOpen,\n onClose,\n ...rest\n } = props\n\n const formProps = {\n schema,\n defaultValues,\n onSubmit,\n reValidateMode,\n shouldFocusError,\n shouldUnregister,\n shouldUseNativeValidation,\n criteriaMode,\n delayError,\n }\n\n const initialRef = React.useRef<HTMLButtonElement | null>(null)\n\n return (\n <BaseModal\n isOpen={isOpen}\n onClose={onClose}\n initialFocusRef={initialRef}\n {...rest}\n >\n <Form {...formProps}>\n <ModalBody>{children || <Fields schema={schema} />}</ModalBody>\n\n {footer || (\n <ModalFooter>\n <Button variant=\"ghost\" mr={3} onClick={onClose}>\n {cancelLabel || 'Cancel'}\n </Button>\n <SubmitButton ref={initialRef}>\n {submitLabel || 'Submit'}\n </SubmitButton>\n </ModalFooter>\n )}\n </Form>\n </BaseModal>\n )\n}\n","import * as React from 'react'\n\nimport { Modal, BaseModalProps } from './modal'\nimport { Drawer, DrawerProps } from './drawer'\nimport { ConfirmDialog, ConfirmDialogProps } from './dialog'\nimport { MenuDialog, MenuDialogProps } from './menu'\nimport { FormDialog, FormDialogProps } from './form'\n\nexport interface ModalsContextValue {\n open?: (options: OpenOptions) => ModalId\n drawer?: (options: DrawerOptions) => ModalId\n alert?: (options: ConfirmDialogOptions) => ModalId\n confirm?: (options: ConfirmDialogOptions) => ModalId\n menu?: (options: MenuDialogOptions) => ModalId\n form?: (options: FormDialogOptions) => ModalId\n close?: (id: ModalId) => void\n closeAll?: () => void\n}\n\nexport const ModalsContext = React.createContext<ModalsContextValue>({})\n\ninterface ModalsProviderProps {\n children: React.ReactNode\n modals?: Record<string, React.FC<any>>\n}\n\nexport type ModalId = string | number\n\ninterface ModalOptions\n extends Omit<BaseModalProps, 'onClose' | 'isOpen' | 'children'> {\n onClose?: (args: { force?: boolean }) => Promise<boolean | undefined> | void\n body?: React.ReactNode\n children?: React.ReactNode\n [key: string]: any\n}\n\nexport interface DrawerOptions\n extends ModalOptions,\n Omit<DrawerProps, 'onClose' | 'isOpen' | 'children' | 'title' | 'size'> {}\n\nexport interface ConfirmDialogOptions\n extends ModalOptions,\n Omit<ConfirmDialogProps, 'onClose' | 'isOpen' | 'children'> {}\n\nexport interface MenuDialogOptions\n extends ModalOptions,\n Omit<MenuDialogProps, 'onClose' | 'isOpen' | 'children'> {}\n\nexport interface FormDialogOptions\n extends ModalOptions,\n Omit<FormDialogProps, 'onClose' | 'isOpen' | 'children'> {}\n\nexport interface OpenOptions extends ModalOptions {\n type?: ModalTypes | string\n scope?: ModalScopes\n}\n\nexport type ModalScopes = 'modal' | 'alert'\n\nexport type ModalTypes = 'modal' | 'drawer' | 'alert' | 'confirm' | 'menu'\n\nexport interface ModalConfig<\n TModalOptions extends ModalOptions = ModalOptions\n> {\n /**\n * The modal id, autogenerated when not set.\n * Can be used to close modals.\n */\n id?: ModalId | null\n /**\n * The modal props\n */\n props?: TModalOptions | null\n /**\n * The modal scope\n * Modals can only have one level per scope.\n * The default scopes are 'modal' and 'alert', alerts can be openend above modals.\n */\n scope?: ModalScopes | string\n /**\n * The modal type to open.\n * Build in types are 'modal', 'drawer', 'alert', 'confirm'\n *\n * Custom types can be configured using the `modals` prop of `ModalProvider`\n */\n type?: ModalTypes | string\n}\n\nconst initialModalState: ModalConfig = {\n id: null,\n props: null,\n type: 'modal',\n}\n\nconst defaultModals = {\n alert: ConfirmDialog,\n confirm: ConfirmDialog,\n drawer: Drawer,\n modal: Modal,\n menu: MenuDialog,\n form: FormDialog,\n}\n\nexport function ModalsProvider({ children, modals }: ModalsProviderProps) {\n // Note that updating the Set doesn't trigger a re-render,\n // use in conjuction with setActiveModals\n const _instances = React.useMemo(() => new Set<ModalConfig>(), [])\n\n const [activeModals, setActiveModals] = React.useState<\n Record<string, ModalConfig>\n >({\n modal: initialModalState,\n })\n\n const getModalComponent = React.useMemo(() => {\n const _modals = {\n ...defaultModals,\n ...modals,\n }\n\n return (type = 'modal') => {\n const component = _modals[type] || _modals.modal\n\n return component\n }\n }, [modals])\n\n const setActiveModal = (modal: ModalConfig, scope?: string) => {\n if (!scope) {\n return setActiveModals({\n modal,\n })\n }\n setActiveModals((prevState) => ({\n ...prevState,\n [scope]: modal,\n }))\n }\n\n const open = <T extends ModalOptions>(options: T): ModalId => {\n const {\n id = _instances.size + 1,\n type = 'modal',\n scope = 'modal',\n ...props\n } = options\n\n const modal: ModalConfig<T> = {\n id,\n props: props as T,\n type,\n scope,\n }\n\n _instances.add(modal)\n setActiveModal(modal, scope)\n\n return id\n }\n\n const drawer = (options: DrawerOptions): ModalId => {\n return open<DrawerOptions>({\n ...options,\n type: 'drawer',\n })\n }\n\n const alert = (options: ConfirmDialogOptions): ModalId => {\n return open({\n ...options,\n scope: 'alert',\n type: 'alert',\n cancelProps: {\n display: 'none',\n },\n confirmProps: {\n label: 'OK',\n },\n leastDestructiveFocus: 'confirm',\n })\n }\n\n const confirm = (options: ConfirmDialogOptions): ModalId => {\n return open<ConfirmDialogOptions>({\n ...options,\n scope: 'alert',\n type: 'confirm',\n })\n }\n\n const menu = (options: MenuDialogOptions): ModalId => {\n return open<MenuDialogOptions>({\n ...options,\n type: 'menu',\n })\n }\n\n const form = (options: FormDialogOptions): ModalId => {\n return open<FormDialogOptions>({\n ...options,\n type: 'form',\n })\n }\n\n const close = async (id?: ModalId | null, force?: boolean) => {\n const modals = [...Array.from(_instances)]\n const modal = modals.filter((modal) => modal.id === id)[0]\n\n if (!modal) {\n return\n }\n\n const shouldClose = await modal.props?.onClose?.({ force })\n if (shouldClose === false) {\n return\n }\n\n _instances.delete(modal)\n\n const scoped = modals.filter(({ scope }) => scope === modal.scope)\n\n setActiveModal(\n scoped[scoped.length - 2] || {\n id: null,\n props: null,\n type: modal.type, // Keep type same as last modal type to make sure the animation isn't interrupted\n },\n modal.scope\n )\n }\n\n const closeAll = () => {\n _instances.forEach((modal) => modal.props?.onClose?.({ force: true }))\n _instances.clear()\n\n setActiveModal(initialModalState)\n }\n\n const context = {\n open,\n drawer,\n alert,\n confirm,\n menu,\n form,\n close,\n closeAll,\n }\n\n const content = Object.entries(activeModals).map(([scope, config]) => {\n const Component = getModalComponent(config.type)\n\n const { title, body, children, ...props } = config.props || {}\n\n return (\n <Component\n key={scope}\n title={title}\n children={body || children}\n {...props}\n isOpen={!!(config.id && _instances.size)}\n onClose={() => close(config.id)}\n />\n )\n })\n\n return (\n <ModalsContext.Provider value={context}>\n {content}\n {children}\n </ModalsContext.Provider>\n )\n}\n\nexport const useModalsContext = (): ModalsContextValue =>\n React.useContext(ModalsContext)\n\nexport const useModals = () => {\n return useModalsContext()\n}\n"],"names":["ConfirmDialog","props","title","cancelLabel","confirmLabel","cancelProps","confirmProps","buttonGroupProps","isOpen","closeOnCancel","closeOnConfirm","leastDestructiveFocus","onClose","onCancel","onConfirm","children","rest","cancelRef","React","useRef","confirmRef","AlertDialog","leastDestructiveRef","AlertDialogOverlay","AlertDialogContent","AlertDialogHeader","AlertDialogBody","AlertDialogFooter","ButtonGroup","Button","ref","onClick","BaseDrawer","hideCloseButton","hideOverlay","ChakraDrawer","DrawerOverlay","DrawerContent","DrawerHeader","DrawerCloseButton","Drawer","footer","DrawerBody","DrawerFooter","BaseModal","ChakraModal","ModalOverlay","ModalContent","ModalHeader","ModalCloseButton","ModalFooter","Modal","ModalBody","MenuDialog","styles","useMultiStyleConfig","direction","useTheme","useMenu","autoSelect","defaultIsOpen","closeOnBlur","descendants","ctx","context","useMemo","useEffect","openAndFocusFirstItem","initialFocusRef","menuRef","MenuDescendantsProvider","value","MenuProvider","StylesProvider","defaultProps","variant","MenuDialogList","forwardRef","ownProps","useMenuList","useStyles","chakra","div","__css","outline","maxHeight","overflowY","list","boxShadow","border","FormDialog","schema","defaultValues","onSubmit","reValidateMode","shouldFocusError","shouldUnregister","shouldUseNativeValidation","criteriaMode","delayError","submitLabel","formProps","initialRef","Form","Fields","mr","SubmitButton","ModalsContext","createContext","initialModalState","id","type","defaultModals","alert","confirm","drawer","modal","menu","form","ModalsProvider","modals","_instances","Set","activeModals","setActiveModals","useState","getModalComponent","_modals","setActiveModal","scope","prevState","open","options","size","add","close","async","force","Array","from","filter","_modal$props","delete","scoped","length","display","label","closeAll","forEach","_modal$props2","clear","content","Object","entries","map","config","Component","body","key","Provider","useModalsContext","useContext","useModals"],"mappings":"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"}
1
+ {"version":3,"file":"index.modern.js","sources":["../src/dialog.tsx","../src/drawer.tsx","../src/modal.tsx","../src/menu.tsx","../src/form.tsx","../src/provider.tsx"],"sourcesContent":["import * as React from 'react'\n\nimport {\n AlertDialog,\n AlertDialogBody,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogContent,\n AlertDialogOverlay,\n AlertDialogProps,\n} from '@chakra-ui/react'\n\nimport {\n ButtonGroup,\n ButtonGroupProps,\n Button,\n ButtonProps,\n} from '@saas-ui/button'\n\nexport interface ConfirmDialogProps\n extends Omit<AlertDialogProps, 'leastDestructiveRef'> {\n /**\n * The dialog title\n */\n title?: React.ReactNode\n /**\n * The cancel button label\n */\n cancelLabel?: React.ReactNode\n /**\n * The confirm button label\n */\n confirmLabel?: React.ReactNode\n /**\n * The cancel button props\n */\n cancelProps?: ButtonProps\n /**\n * The confirm button props\n */\n confirmProps?: ButtonProps\n /**\n * The button group props\n */\n buttonGroupProps?: ButtonGroupProps\n /**\n * Close the dialog on cancel\n * @default true\n */\n closeOnCancel?: boolean\n /**\n * Close the dialog on confirm\n * @default true\n */\n closeOnConfirm?: boolean\n /**\n * Defines which button gets initial focus\n * https://www.w3.org/TR/wai-aria-practices/#alertdialog\n */\n leastDestructiveFocus?: 'cancel' | 'confirm'\n /**\n * Function that's called when cancel is clicked\n */\n onCancel?: () => void\n /**\n * Function that's called when confirm is clicked\n */\n onConfirm?: () => void\n}\n\nexport const ConfirmDialog: React.FC<ConfirmDialogProps> = (props) => {\n const {\n title,\n cancelLabel = 'Cancel',\n confirmLabel = 'Confirm',\n cancelProps,\n confirmProps,\n buttonGroupProps,\n isOpen,\n closeOnCancel = true,\n closeOnConfirm = true,\n leastDestructiveFocus = 'cancel',\n onClose,\n onCancel,\n onConfirm,\n children,\n ...rest\n } = props\n\n const cancelRef = React.useRef(null)\n const confirmRef = React.useRef(null)\n\n return (\n <AlertDialog\n isOpen={isOpen}\n onClose={onClose}\n {...rest}\n leastDestructiveRef={\n leastDestructiveFocus === 'cancel' ? cancelRef : confirmRef\n }\n >\n <AlertDialogOverlay>\n <AlertDialogContent>\n <AlertDialogHeader>{title}</AlertDialogHeader>\n\n <AlertDialogBody>{children}</AlertDialogBody>\n\n <AlertDialogFooter>\n <ButtonGroup {...buttonGroupProps}>\n <Button\n ref={cancelRef}\n {...cancelProps}\n onClick={() => {\n onCancel?.()\n\n closeOnCancel && onClose()\n }}\n >\n Cancel\n </Button>\n <Button\n ref={confirmRef}\n {...confirmProps}\n onClick={() => {\n onConfirm?.()\n\n closeOnConfirm && onClose()\n }}\n >\n Confirm\n </Button>\n </ButtonGroup>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialogOverlay>\n </AlertDialog>\n )\n}\n","import * as React from 'react'\n\nimport {\n Drawer as ChakraDrawer,\n DrawerOverlay,\n DrawerContent,\n DrawerHeader,\n DrawerFooter,\n DrawerBody,\n DrawerCloseButton,\n DrawerProps as ChakraDrawerProps,\n} from '@chakra-ui/react'\n\nexport interface BaseDrawerProps extends Omit<ChakraDrawerProps, 'children'> {\n /**\n * The drawer title\n */\n title: React.ReactNode\n /**\n * Hide the close button\n */\n hideCloseButton?: boolean\n /**\n * Hide the overflow\n */\n hideOverlay?: boolean\n children?: React.ReactNode\n}\n\nexport const BaseDrawer: React.FC<BaseDrawerProps> = (props) => {\n const {\n title,\n children,\n isOpen,\n onClose,\n hideCloseButton,\n hideOverlay,\n ...rest\n } = props\n return (\n <ChakraDrawer isOpen={isOpen} onClose={onClose} {...rest}>\n {!hideOverlay && <DrawerOverlay />}\n <DrawerContent>\n <DrawerHeader>{title}</DrawerHeader>\n {!hideCloseButton && <DrawerCloseButton />}\n {children}\n </DrawerContent>\n </ChakraDrawer>\n )\n}\n\nexport interface DrawerProps extends BaseDrawerProps {\n /**\n * Drawer footer content, wrapped with `DrawerFooter`\n */\n footer?: React.ReactNode\n}\n\nexport const Drawer: React.FC<DrawerProps> = (props) => {\n const { footer, children, ...rest } = props\n return (\n <BaseDrawer {...rest}>\n <DrawerBody>{children}</DrawerBody>\n\n {footer && <DrawerFooter>{footer}</DrawerFooter>}\n </BaseDrawer>\n )\n}\n","import * as React from 'react'\n\nimport {\n Modal as ChakraModal,\n ModalOverlay,\n ModalContent,\n ModalHeader,\n ModalFooter,\n ModalBody,\n ModalCloseButton,\n ModalProps as ChakraModalProps,\n} from '@chakra-ui/react'\n\nexport interface BaseModalProps extends ChakraModalProps {\n /**\n * The modal title\n */\n title?: React.ReactNode\n /**\n * The modal footer\n */\n footer?: React.ReactNode\n /**\n * Hide the close button\n */\n hideCloseButton?: boolean\n /**\n * Hide the overlay\n */\n hideOverlay?: boolean\n}\n\nexport const BaseModal: React.FC<BaseModalProps> = (props) => {\n const {\n title,\n footer,\n children,\n isOpen,\n onClose,\n hideCloseButton,\n hideOverlay,\n ...rest\n } = props\n return (\n <ChakraModal isOpen={isOpen} onClose={onClose} {...rest}>\n {!hideOverlay && <ModalOverlay />}\n <ModalContent>\n {title && <ModalHeader>{title}</ModalHeader>}\n {!hideCloseButton && <ModalCloseButton />}\n {children}\n {footer && <ModalFooter>{footer}</ModalFooter>}\n </ModalContent>\n </ChakraModal>\n )\n}\n\nexport const Modal: React.FC<BaseModalProps> = (props) => {\n const { children, footer, ...rest } = props\n return (\n <BaseModal {...rest}>\n <ModalBody>{children}</ModalBody>\n </BaseModal>\n )\n}\n","import * as React from 'react'\n\nimport {\n ModalFooter,\n MenuDescendantsProvider,\n MenuProvider,\n MenuListProps,\n useMenu,\n useMenuList,\n chakra,\n StylesProvider,\n useMultiStyleConfig,\n useTheme,\n useStyles,\n forwardRef,\n} from '@chakra-ui/react'\n\nimport { BaseModal, BaseModalProps } from './modal'\n\nexport interface MenuDialogProps extends BaseModalProps {\n /**\n * The modal footer, wrapped with `ModalFooter`\n */\n footer?: React.ReactNode\n}\n\nexport const MenuDialog: React.FC<MenuDialogProps> = (props) => {\n const { children, footer, isOpen, onClose, ...rest } = props\n\n const styles = useMultiStyleConfig('Menu', props)\n const { direction } = useTheme()\n const { descendants, ...ctx } = useMenu({\n onClose,\n autoSelect: true,\n defaultIsOpen: true,\n closeOnBlur: false,\n direction,\n })\n const context = React.useMemo(() => ctx, [ctx])\n\n React.useEffect(() => {\n ctx.openAndFocusFirstItem()\n }, [props.isOpen])\n\n return (\n <BaseModal\n isOpen={isOpen}\n onClose={onClose}\n initialFocusRef={ctx.menuRef}\n {...rest}\n >\n <MenuDescendantsProvider value={descendants}>\n <MenuProvider value={context}>\n <StylesProvider value={styles}>{children}</StylesProvider>\n </MenuProvider>\n </MenuDescendantsProvider>\n\n {footer && <ModalFooter>{footer}</ModalFooter>}\n </BaseModal>\n )\n}\n\nMenuDialog.defaultProps = {\n variant: 'dialog',\n}\n\nexport const MenuDialogList = forwardRef<MenuListProps, 'div'>((props, ref) => {\n const { rootProps, ...rest } = props\n\n const ownProps = useMenuList(rest, ref) as any\n\n const styles = useStyles()\n\n return (\n <chakra.div\n {...ownProps}\n __css={{\n outline: 0,\n maxHeight: '80vh', // can override this in theme\n overflowY: 'auto', // can override this in theme\n ...styles.list,\n boxShadow: 'none',\n border: 0,\n }}\n />\n )\n})\n","import * as React from 'react'\n\nimport { ModalBody, ModalFooter, forwardRef } from '@chakra-ui/react'\n\nimport {\n Form,\n Fields,\n SubmitButton,\n FormProps,\n FieldValues,\n FieldResolver,\n UseFormReturn,\n} from '@saas-ui/forms'\nimport { Button } from '@saas-ui/button'\n\nimport { BaseModal, BaseModalProps } from './modal'\n\nexport interface FormDialogProps<TFieldValues extends FieldValues = FieldValues>\n extends Omit<BaseModalProps, 'children'>,\n Pick<\n FormProps<TFieldValues>,\n | 'schema'\n | 'defaultValues'\n | 'onSubmit'\n | 'onError'\n | 'resolver'\n | 'mode'\n | 'reValidateMode'\n | 'shouldFocusError'\n | 'shouldUnregister'\n | 'shouldUseNativeValidation'\n | 'criteriaMode'\n | 'delayError'\n > {\n /**\n * The modal footer, will be wrapped with `ModalFooter`.\n * Defaults to a cancel and submit button.\n */\n footer?: React.ReactNode\n /**\n * The cancel button label\n * @default \"Cancel\"\n */\n cancelLabel?: React.ReactNode\n /**\n * The submit button label\n * @default \"Submit\"\n */\n submitLabel?: React.ReactNode\n /**\n * If no children are passed, this will auto render fields based on the supplied schema.\n */\n children?: React.ReactNode\n /**\n * A schema field resolver used to auto generate form fields.\n */\n fieldResolver?: FieldResolver\n}\n\nexport const FormDialog = forwardRef(\n <TFieldValues extends FieldValues = FieldValues>(\n props: FormDialogProps<TFieldValues>,\n ref: React.ForwardedRef<UseFormReturn<TFieldValues>>\n ) => {\n const {\n children,\n schema,\n resolver,\n fieldResolver,\n defaultValues,\n onSubmit,\n onError,\n reValidateMode,\n shouldFocusError = true,\n shouldUnregister,\n shouldUseNativeValidation,\n criteriaMode,\n delayError,\n cancelLabel,\n submitLabel,\n footer,\n isOpen,\n onClose,\n ...rest\n } = props\n\n const formProps = {\n ref,\n schema,\n defaultValues,\n onSubmit,\n onError,\n reValidateMode,\n shouldFocusError,\n shouldUnregister,\n shouldUseNativeValidation,\n criteriaMode,\n delayError,\n }\n\n const initialRef = React.useRef<HTMLButtonElement | null>(null)\n\n return (\n <BaseModal\n isOpen={isOpen}\n onClose={onClose}\n initialFocusRef={initialRef}\n {...rest}\n >\n <Form {...formProps}>\n <ModalBody>\n {children || (\n <Fields schema={schema} fieldResolver={fieldResolver} />\n )}\n </ModalBody>\n\n {footer || (\n <ModalFooter>\n <Button variant=\"ghost\" mr={3} onClick={onClose}>\n {cancelLabel || 'Cancel'}\n </Button>\n <SubmitButton ref={initialRef}>\n {submitLabel || 'Submit'}\n </SubmitButton>\n </ModalFooter>\n )}\n </Form>\n </BaseModal>\n )\n }\n) as <TFieldValues extends FieldValues>(\n props: FormDialogProps<TFieldValues> & {\n ref?: React.ForwardedRef<UseFormReturn<TFieldValues>>\n }\n) => React.ReactElement\n","import * as React from 'react'\n\nimport { Modal, BaseModalProps } from './modal'\nimport { Drawer, DrawerProps } from './drawer'\nimport { ConfirmDialog, ConfirmDialogProps } from './dialog'\nimport { MenuDialog, MenuDialogProps } from './menu'\nimport { FormDialog, FormDialogProps } from './form'\n\nexport interface ModalsContextValue {\n open: (options: OpenOptions) => ModalId\n drawer: (options: DrawerOptions) => ModalId\n alert: (options: ConfirmDialogOptions) => ModalId\n confirm: (options: ConfirmDialogOptions) => ModalId\n menu: (options: MenuDialogOptions) => ModalId\n form: (options: FormDialogOptions) => ModalId\n close: (id: ModalId) => void\n closeAll: () => void\n}\n\nexport const ModalsContext = React.createContext<ModalsContextValue | null>(\n null\n)\n\ninterface ModalsProviderProps {\n children: React.ReactNode\n modals?: Record<string, React.FC<any>>\n}\n\nexport type ModalId = string | number\n\ninterface ModalOptions\n extends Omit<BaseModalProps, 'onClose' | 'isOpen' | 'children'> {\n onClose?: (args: { force?: boolean }) => Promise<boolean | undefined> | void\n body?: React.ReactNode\n children?: React.ReactNode\n [key: string]: any\n}\n\nexport interface DrawerOptions\n extends ModalOptions,\n Omit<DrawerProps, 'onClose' | 'isOpen' | 'children' | 'title' | 'size'> {}\n\nexport interface ConfirmDialogOptions\n extends ModalOptions,\n Omit<ConfirmDialogProps, 'onClose' | 'isOpen' | 'children'> {}\n\nexport interface MenuDialogOptions\n extends ModalOptions,\n Omit<MenuDialogProps, 'onClose' | 'isOpen' | 'children'> {}\n\nexport interface FormDialogOptions\n extends ModalOptions,\n Omit<FormDialogProps, 'onClose' | 'isOpen' | 'children'> {}\n\nexport interface OpenOptions extends ModalOptions {\n type?: ModalTypes\n scope?: ModalScopes\n}\n\nexport type ModalScopes = 'modal' | 'alert'\n\nexport type ModalTypes =\n | 'modal'\n | 'drawer'\n | 'alert'\n | 'confirm'\n | 'menu'\n | string\n\nexport interface ModalConfig<\n TModalOptions extends ModalOptions = ModalOptions\n> {\n /**\n * The modal id, autogenerated when not set.\n * Can be used to close modals.\n */\n id?: ModalId | null\n /**\n * The modal props\n */\n props?: TModalOptions | null\n /**\n * The modal scope\n * Modals can only have one level per scope.\n * The default scopes are 'modal' and 'alert', alerts can be openend above modals.\n */\n scope?: ModalScopes | string\n /**\n * The modal type to open.\n * Build in types are 'modal', 'drawer', 'alert', 'confirm'\n *\n * Custom types can be configured using the `modals` prop of `ModalProvider`\n */\n type?: ModalTypes\n /**\n * Render a custom modal component.\n * This will ignore the `type` param.\n */\n component?: React.FC<BaseModalProps>\n}\n\nconst initialModalState: ModalConfig = {\n id: null,\n props: null,\n type: 'modal',\n}\n\nconst defaultModals = {\n alert: ConfirmDialog,\n confirm: ConfirmDialog,\n drawer: Drawer,\n modal: Modal,\n menu: MenuDialog,\n form: FormDialog,\n}\n\nexport function ModalsProvider({ children, modals }: ModalsProviderProps) {\n // Note that updating the Set doesn't trigger a re-render,\n // use in conjuction with setActiveModals\n const _instances = React.useMemo(() => new Set<ModalConfig>(), [])\n\n const [activeModals, setActiveModals] = React.useState<\n Record<string, ModalConfig>\n >({\n modal: initialModalState,\n })\n\n const getModalComponent = React.useMemo(() => {\n const _modals = {\n ...defaultModals,\n ...modals,\n }\n\n return (type: ModalTypes = 'modal') => {\n const component = _modals[type] || _modals.modal\n\n return component\n }\n }, [modals])\n\n const setActiveModal = (modal: ModalConfig, scope?: string) => {\n if (!scope) {\n return setActiveModals({\n modal,\n })\n }\n setActiveModals((prevState) => ({\n ...prevState,\n [scope]: modal,\n }))\n }\n\n const open = <T extends ModalOptions>(\n options: T | React.FC<BaseModalProps>\n ): ModalId => {\n if (typeof options === 'function') {\n const component: React.FC<BaseModalProps> = options\n options = {\n component,\n } as unknown as T\n }\n\n const {\n id = _instances.size + 1,\n type = 'modal',\n scope = 'modal',\n component,\n ...props\n } = options\n\n const modal: ModalConfig<T> = {\n id,\n props: props as T,\n type,\n scope,\n component,\n }\n\n _instances.add(modal)\n setActiveModal(modal, scope)\n\n return id\n }\n\n const drawer = (options: DrawerOptions): ModalId => {\n return open<DrawerOptions>({\n ...options,\n type: 'drawer',\n })\n }\n\n const alert = (options: ConfirmDialogOptions): ModalId => {\n return open({\n ...options,\n scope: 'alert',\n type: 'alert',\n cancelProps: {\n display: 'none',\n },\n confirmProps: {\n label: 'OK',\n },\n leastDestructiveFocus: 'confirm',\n })\n }\n\n const confirm = (options: ConfirmDialogOptions): ModalId => {\n return open<ConfirmDialogOptions>({\n ...options,\n scope: 'alert',\n type: 'confirm',\n })\n }\n\n const menu = (options: MenuDialogOptions): ModalId => {\n return open<MenuDialogOptions>({\n ...options,\n type: 'menu',\n })\n }\n\n const form = (options: FormDialogOptions): ModalId => {\n return open<FormDialogOptions>({\n ...options,\n type: 'form',\n })\n }\n\n const close = async (id?: ModalId | null, force?: boolean) => {\n const modals = [...Array.from(_instances)]\n const modal = modals.filter((modal) => modal.id === id)[0]\n\n if (!modal) {\n return\n }\n\n const shouldClose = await modal.props?.onClose?.({ force })\n if (shouldClose === false) {\n return\n }\n\n _instances.delete(modal)\n\n const scoped = modals.filter(({ scope }) => scope === modal.scope)\n\n setActiveModal(\n scoped[scoped.length - 2] || {\n id: null,\n props: null,\n type: modal.type, // Keep type same as last modal type to make sure the animation isn't interrupted\n },\n modal.scope\n )\n }\n\n const closeAll = () => {\n _instances.forEach((modal) => modal.props?.onClose?.({ force: true }))\n _instances.clear()\n\n setActiveModal(initialModalState)\n }\n\n const context = {\n open,\n drawer,\n alert,\n confirm,\n menu,\n form,\n close,\n closeAll,\n }\n\n const content = Object.entries(activeModals).map(([scope, config]) => {\n const Component = config.component || getModalComponent(config.type)\n\n const { title, body, children, ...props } = config.props || {}\n\n return (\n <Component\n key={scope}\n title={title}\n children={body || children}\n {...props}\n isOpen={!!(config.id && _instances.size)}\n onClose={() => close(config.id)}\n />\n )\n })\n\n return (\n <ModalsContext.Provider value={context}>\n {content}\n {children}\n </ModalsContext.Provider>\n )\n}\n\nexport const useModalsContext = () =>\n React.useContext(ModalsContext) as ModalsContextValue\n\nexport const useModals = () => {\n return useModalsContext()\n}\n"],"names":["ConfirmDialog","props","title","cancelLabel","confirmLabel","cancelProps","confirmProps","buttonGroupProps","isOpen","closeOnCancel","closeOnConfirm","leastDestructiveFocus","onClose","onCancel","onConfirm","children","rest","cancelRef","React","useRef","confirmRef","AlertDialog","leastDestructiveRef","AlertDialogOverlay","AlertDialogContent","AlertDialogHeader","AlertDialogBody","AlertDialogFooter","ButtonGroup","Button","ref","onClick","BaseDrawer","hideCloseButton","hideOverlay","ChakraDrawer","DrawerOverlay","DrawerContent","DrawerHeader","DrawerCloseButton","Drawer","footer","DrawerBody","DrawerFooter","BaseModal","ChakraModal","ModalOverlay","ModalContent","ModalHeader","ModalCloseButton","ModalFooter","Modal","ModalBody","MenuDialog","styles","useMultiStyleConfig","direction","useTheme","useMenu","autoSelect","defaultIsOpen","closeOnBlur","descendants","ctx","context","useMemo","useEffect","openAndFocusFirstItem","initialFocusRef","menuRef","MenuDescendantsProvider","value","MenuProvider","StylesProvider","defaultProps","variant","MenuDialogList","forwardRef","ownProps","useMenuList","useStyles","chakra","div","__css","outline","maxHeight","overflowY","list","boxShadow","border","FormDialog","schema","fieldResolver","defaultValues","onSubmit","onError","reValidateMode","shouldFocusError","shouldUnregister","shouldUseNativeValidation","criteriaMode","delayError","submitLabel","formProps","initialRef","Form","Fields","mr","SubmitButton","ModalsContext","createContext","initialModalState","id","type","defaultModals","alert","confirm","drawer","modal","menu","form","ModalsProvider","modals","_instances","Set","activeModals","setActiveModals","useState","getModalComponent","_modals","setActiveModal","scope","prevState","open","options","component","size","add","close","async","force","Array","from","filter","_modal$props","delete","scoped","length","display","label","closeAll","forEach","_modal$props2","clear","content","Object","entries","map","config","Component","body","key","Provider","useModalsContext","useContext","useModals"],"mappings":"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"}
@@ -5,16 +5,16 @@ import { ConfirmDialogProps } from './dialog';
5
5
  import { MenuDialogProps } from './menu';
6
6
  import { FormDialogProps } from './form';
7
7
  export interface ModalsContextValue {
8
- open?: (options: OpenOptions) => ModalId;
9
- drawer?: (options: DrawerOptions) => ModalId;
10
- alert?: (options: ConfirmDialogOptions) => ModalId;
11
- confirm?: (options: ConfirmDialogOptions) => ModalId;
12
- menu?: (options: MenuDialogOptions) => ModalId;
13
- form?: (options: FormDialogOptions) => ModalId;
14
- close?: (id: ModalId) => void;
15
- closeAll?: () => void;
8
+ open: (options: OpenOptions) => ModalId;
9
+ drawer: (options: DrawerOptions) => ModalId;
10
+ alert: (options: ConfirmDialogOptions) => ModalId;
11
+ confirm: (options: ConfirmDialogOptions) => ModalId;
12
+ menu: (options: MenuDialogOptions) => ModalId;
13
+ form: (options: FormDialogOptions) => ModalId;
14
+ close: (id: ModalId) => void;
15
+ closeAll: () => void;
16
16
  }
17
- export declare const ModalsContext: React.Context<ModalsContextValue>;
17
+ export declare const ModalsContext: React.Context<ModalsContextValue | null>;
18
18
  interface ModalsProviderProps {
19
19
  children: React.ReactNode;
20
20
  modals?: Record<string, React.FC<any>>;
@@ -37,11 +37,11 @@ export interface MenuDialogOptions extends ModalOptions, Omit<MenuDialogProps, '
37
37
  export interface FormDialogOptions extends ModalOptions, Omit<FormDialogProps, 'onClose' | 'isOpen' | 'children'> {
38
38
  }
39
39
  export interface OpenOptions extends ModalOptions {
40
- type?: ModalTypes | string;
40
+ type?: ModalTypes;
41
41
  scope?: ModalScopes;
42
42
  }
43
43
  export declare type ModalScopes = 'modal' | 'alert';
44
- export declare type ModalTypes = 'modal' | 'drawer' | 'alert' | 'confirm' | 'menu';
44
+ export declare type ModalTypes = 'modal' | 'drawer' | 'alert' | 'confirm' | 'menu' | string;
45
45
  export interface ModalConfig<TModalOptions extends ModalOptions = ModalOptions> {
46
46
  /**
47
47
  * The modal id, autogenerated when not set.
@@ -64,7 +64,12 @@ export interface ModalConfig<TModalOptions extends ModalOptions = ModalOptions>
64
64
  *
65
65
  * Custom types can be configured using the `modals` prop of `ModalProvider`
66
66
  */
67
- type?: ModalTypes | string;
67
+ type?: ModalTypes;
68
+ /**
69
+ * Render a custom modal component.
70
+ * This will ignore the `type` param.
71
+ */
72
+ component?: React.FC<BaseModalProps>;
68
73
  }
69
74
  export declare function ModalsProvider({ children, modals }: ModalsProviderProps): JSX.Element;
70
75
  export declare const useModalsContext: () => ModalsContextValue;
@@ -1 +1 @@
1
- {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.tsx"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@saas-ui/modals",
3
- "version": "0.3.3",
3
+ "version": "0.4.0-next.0",
4
4
  "description": "A modal manager for Chakra UI",
5
5
  "source": "src/index.ts",
6
6
  "exports": {
@@ -56,11 +56,12 @@
56
56
  "url": "https://storybook.saas-ui.dev"
57
57
  },
58
58
  "dependencies": {
59
- "@saas-ui/button": "0.3.0",
60
- "@saas-ui/forms": "0.5.2"
59
+ "@saas-ui/button": "0.4.0-next.0",
60
+ "@saas-ui/forms": "0.6.0-next.0"
61
61
  },
62
62
  "peerDependencies": {
63
63
  "@chakra-ui/react": ">=1.8.0",
64
+ "@chakra-ui/system": ">=1.0.0",
64
65
  "react": ">=16.8.6"
65
66
  }
66
67
  }
package/src/form.tsx CHANGED
@@ -1,19 +1,28 @@
1
1
  import * as React from 'react'
2
2
 
3
- import { ModalBody, ModalFooter } from '@chakra-ui/react'
3
+ import { ModalBody, ModalFooter, forwardRef } from '@chakra-ui/react'
4
4
 
5
- import { Form, Fields, SubmitButton, FormProps } from '@saas-ui/forms'
5
+ import {
6
+ Form,
7
+ Fields,
8
+ SubmitButton,
9
+ FormProps,
10
+ FieldValues,
11
+ FieldResolver,
12
+ UseFormReturn,
13
+ } from '@saas-ui/forms'
6
14
  import { Button } from '@saas-ui/button'
7
15
 
8
16
  import { BaseModal, BaseModalProps } from './modal'
9
17
 
10
- export interface FormDialogProps
18
+ export interface FormDialogProps<TFieldValues extends FieldValues = FieldValues>
11
19
  extends Omit<BaseModalProps, 'children'>,
12
20
  Pick<
13
- FormProps,
21
+ FormProps<TFieldValues>,
14
22
  | 'schema'
15
23
  | 'defaultValues'
16
24
  | 'onSubmit'
25
+ | 'onError'
17
26
  | 'resolver'
18
27
  | 'mode'
19
28
  | 'reValidateMode'
@@ -42,63 +51,85 @@ export interface FormDialogProps
42
51
  * If no children are passed, this will auto render fields based on the supplied schema.
43
52
  */
44
53
  children?: React.ReactNode
54
+ /**
55
+ * A schema field resolver used to auto generate form fields.
56
+ */
57
+ fieldResolver?: FieldResolver
45
58
  }
46
59
 
47
- export const FormDialog: React.FC<FormDialogProps> = (props) => {
48
- const {
49
- children,
50
- schema,
51
- defaultValues,
52
- onSubmit,
53
- reValidateMode,
54
- shouldFocusError = true,
55
- shouldUnregister,
56
- shouldUseNativeValidation,
57
- criteriaMode,
58
- delayError,
59
- cancelLabel,
60
- submitLabel,
61
- footer,
62
- isOpen,
63
- onClose,
64
- ...rest
65
- } = props
60
+ export const FormDialog = forwardRef(
61
+ <TFieldValues extends FieldValues = FieldValues>(
62
+ props: FormDialogProps<TFieldValues>,
63
+ ref: React.ForwardedRef<UseFormReturn<TFieldValues>>
64
+ ) => {
65
+ const {
66
+ children,
67
+ schema,
68
+ resolver,
69
+ fieldResolver,
70
+ defaultValues,
71
+ onSubmit,
72
+ onError,
73
+ reValidateMode,
74
+ shouldFocusError = true,
75
+ shouldUnregister,
76
+ shouldUseNativeValidation,
77
+ criteriaMode,
78
+ delayError,
79
+ cancelLabel,
80
+ submitLabel,
81
+ footer,
82
+ isOpen,
83
+ onClose,
84
+ ...rest
85
+ } = props
66
86
 
67
- const formProps = {
68
- schema,
69
- defaultValues,
70
- onSubmit,
71
- reValidateMode,
72
- shouldFocusError,
73
- shouldUnregister,
74
- shouldUseNativeValidation,
75
- criteriaMode,
76
- delayError,
77
- }
87
+ const formProps = {
88
+ ref,
89
+ schema,
90
+ defaultValues,
91
+ onSubmit,
92
+ onError,
93
+ reValidateMode,
94
+ shouldFocusError,
95
+ shouldUnregister,
96
+ shouldUseNativeValidation,
97
+ criteriaMode,
98
+ delayError,
99
+ }
78
100
 
79
- const initialRef = React.useRef<HTMLButtonElement | null>(null)
101
+ const initialRef = React.useRef<HTMLButtonElement | null>(null)
80
102
 
81
- return (
82
- <BaseModal
83
- isOpen={isOpen}
84
- onClose={onClose}
85
- initialFocusRef={initialRef}
86
- {...rest}
87
- >
88
- <Form {...formProps}>
89
- <ModalBody>{children || <Fields schema={schema} />}</ModalBody>
103
+ return (
104
+ <BaseModal
105
+ isOpen={isOpen}
106
+ onClose={onClose}
107
+ initialFocusRef={initialRef}
108
+ {...rest}
109
+ >
110
+ <Form {...formProps}>
111
+ <ModalBody>
112
+ {children || (
113
+ <Fields schema={schema} fieldResolver={fieldResolver} />
114
+ )}
115
+ </ModalBody>
90
116
 
91
- {footer || (
92
- <ModalFooter>
93
- <Button variant="ghost" mr={3} onClick={onClose}>
94
- {cancelLabel || 'Cancel'}
95
- </Button>
96
- <SubmitButton ref={initialRef}>
97
- {submitLabel || 'Submit'}
98
- </SubmitButton>
99
- </ModalFooter>
100
- )}
101
- </Form>
102
- </BaseModal>
103
- )
104
- }
117
+ {footer || (
118
+ <ModalFooter>
119
+ <Button variant="ghost" mr={3} onClick={onClose}>
120
+ {cancelLabel || 'Cancel'}
121
+ </Button>
122
+ <SubmitButton ref={initialRef}>
123
+ {submitLabel || 'Submit'}
124
+ </SubmitButton>
125
+ </ModalFooter>
126
+ )}
127
+ </Form>
128
+ </BaseModal>
129
+ )
130
+ }
131
+ ) as <TFieldValues extends FieldValues>(
132
+ props: FormDialogProps<TFieldValues> & {
133
+ ref?: React.ForwardedRef<UseFormReturn<TFieldValues>>
134
+ }
135
+ ) => React.ReactElement
package/src/provider.tsx CHANGED
@@ -7,17 +7,19 @@ import { MenuDialog, MenuDialogProps } from './menu'
7
7
  import { FormDialog, FormDialogProps } from './form'
8
8
 
9
9
  export interface ModalsContextValue {
10
- open?: (options: OpenOptions) => ModalId
11
- drawer?: (options: DrawerOptions) => ModalId
12
- alert?: (options: ConfirmDialogOptions) => ModalId
13
- confirm?: (options: ConfirmDialogOptions) => ModalId
14
- menu?: (options: MenuDialogOptions) => ModalId
15
- form?: (options: FormDialogOptions) => ModalId
16
- close?: (id: ModalId) => void
17
- closeAll?: () => void
10
+ open: (options: OpenOptions) => ModalId
11
+ drawer: (options: DrawerOptions) => ModalId
12
+ alert: (options: ConfirmDialogOptions) => ModalId
13
+ confirm: (options: ConfirmDialogOptions) => ModalId
14
+ menu: (options: MenuDialogOptions) => ModalId
15
+ form: (options: FormDialogOptions) => ModalId
16
+ close: (id: ModalId) => void
17
+ closeAll: () => void
18
18
  }
19
19
 
20
- export const ModalsContext = React.createContext<ModalsContextValue>({})
20
+ export const ModalsContext = React.createContext<ModalsContextValue | null>(
21
+ null
22
+ )
21
23
 
22
24
  interface ModalsProviderProps {
23
25
  children: React.ReactNode
@@ -51,13 +53,19 @@ export interface FormDialogOptions
51
53
  Omit<FormDialogProps, 'onClose' | 'isOpen' | 'children'> {}
52
54
 
53
55
  export interface OpenOptions extends ModalOptions {
54
- type?: ModalTypes | string
56
+ type?: ModalTypes
55
57
  scope?: ModalScopes
56
58
  }
57
59
 
58
60
  export type ModalScopes = 'modal' | 'alert'
59
61
 
60
- export type ModalTypes = 'modal' | 'drawer' | 'alert' | 'confirm' | 'menu'
62
+ export type ModalTypes =
63
+ | 'modal'
64
+ | 'drawer'
65
+ | 'alert'
66
+ | 'confirm'
67
+ | 'menu'
68
+ | string
61
69
 
62
70
  export interface ModalConfig<
63
71
  TModalOptions extends ModalOptions = ModalOptions
@@ -83,7 +91,12 @@ export interface ModalConfig<
83
91
  *
84
92
  * Custom types can be configured using the `modals` prop of `ModalProvider`
85
93
  */
86
- type?: ModalTypes | string
94
+ type?: ModalTypes
95
+ /**
96
+ * Render a custom modal component.
97
+ * This will ignore the `type` param.
98
+ */
99
+ component?: React.FC<BaseModalProps>
87
100
  }
88
101
 
89
102
  const initialModalState: ModalConfig = {
@@ -118,7 +131,7 @@ export function ModalsProvider({ children, modals }: ModalsProviderProps) {
118
131
  ...modals,
119
132
  }
120
133
 
121
- return (type = 'modal') => {
134
+ return (type: ModalTypes = 'modal') => {
122
135
  const component = _modals[type] || _modals.modal
123
136
 
124
137
  return component
@@ -137,11 +150,21 @@ export function ModalsProvider({ children, modals }: ModalsProviderProps) {
137
150
  }))
138
151
  }
139
152
 
140
- const open = <T extends ModalOptions>(options: T): ModalId => {
153
+ const open = <T extends ModalOptions>(
154
+ options: T | React.FC<BaseModalProps>
155
+ ): ModalId => {
156
+ if (typeof options === 'function') {
157
+ const component: React.FC<BaseModalProps> = options
158
+ options = {
159
+ component,
160
+ } as unknown as T
161
+ }
162
+
141
163
  const {
142
164
  id = _instances.size + 1,
143
165
  type = 'modal',
144
166
  scope = 'modal',
167
+ component,
145
168
  ...props
146
169
  } = options
147
170
 
@@ -150,6 +173,7 @@ export function ModalsProvider({ children, modals }: ModalsProviderProps) {
150
173
  props: props as T,
151
174
  type,
152
175
  scope,
176
+ component,
153
177
  }
154
178
 
155
179
  _instances.add(modal)
@@ -248,7 +272,7 @@ export function ModalsProvider({ children, modals }: ModalsProviderProps) {
248
272
  }
249
273
 
250
274
  const content = Object.entries(activeModals).map(([scope, config]) => {
251
- const Component = getModalComponent(config.type)
275
+ const Component = config.component || getModalComponent(config.type)
252
276
 
253
277
  const { title, body, children, ...props } = config.props || {}
254
278
 
@@ -272,8 +296,8 @@ export function ModalsProvider({ children, modals }: ModalsProviderProps) {
272
296
  )
273
297
  }
274
298
 
275
- export const useModalsContext = (): ModalsContextValue =>
276
- React.useContext(ModalsContext)
299
+ export const useModalsContext = () =>
300
+ React.useContext(ModalsContext) as ModalsContextValue
277
301
 
278
302
  export const useModals = () => {
279
303
  return useModalsContext()