@saas-ui/modals 1.5.5 → 2.0.0-next.1

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/dist/index.mjs ADDED
@@ -0,0 +1,401 @@
1
+ import * as React from 'react';
2
+ import { createStylesContext, forwardRef, useMenuContext, useMenuList, useMultiStyleConfig, chakra, ModalFooter, ModalBody, Button, AlertDialog, AlertDialogOverlay, AlertDialogContent, AlertDialogHeader, AlertDialogBody, AlertDialogFooter, ButtonGroup, Drawer as Drawer$1, DrawerOverlay, DrawerContent, DrawerHeader, DrawerCloseButton, DrawerBody, DrawerFooter, Modal as Modal$1, ModalOverlay, ModalContent, ModalHeader, ModalCloseButton, Menu } from '@chakra-ui/react';
3
+ import { runIfFn } from '@saas-ui/react-utils';
4
+ import { Form, Fields, SubmitButton } from '@saas-ui/forms';
5
+
6
+ // src/dialog.tsx
7
+ var ConfirmDialog = (props) => {
8
+ const {
9
+ title,
10
+ cancelLabel = "Cancel",
11
+ confirmLabel = "Confirm",
12
+ cancelProps,
13
+ confirmProps,
14
+ buttonGroupProps,
15
+ isOpen,
16
+ closeOnCancel = true,
17
+ closeOnConfirm = true,
18
+ leastDestructiveFocus = "cancel",
19
+ onClose,
20
+ onCancel,
21
+ onConfirm,
22
+ children,
23
+ ...rest
24
+ } = props;
25
+ const cancelRef = React.useRef(null);
26
+ const confirmRef = React.useRef(null);
27
+ return /* @__PURE__ */ React.createElement(AlertDialog, {
28
+ isOpen,
29
+ onClose,
30
+ ...rest,
31
+ leastDestructiveRef: leastDestructiveFocus === "cancel" ? cancelRef : confirmRef
32
+ }, /* @__PURE__ */ React.createElement(AlertDialogOverlay, null, /* @__PURE__ */ React.createElement(AlertDialogContent, null, /* @__PURE__ */ React.createElement(AlertDialogHeader, null, title), /* @__PURE__ */ React.createElement(AlertDialogBody, null, children), /* @__PURE__ */ React.createElement(AlertDialogFooter, null, /* @__PURE__ */ React.createElement(ButtonGroup, {
33
+ ...buttonGroupProps
34
+ }, /* @__PURE__ */ React.createElement(Button, {
35
+ ref: cancelRef,
36
+ ...cancelProps,
37
+ onClick: () => {
38
+ onCancel == null ? void 0 : onCancel();
39
+ closeOnCancel && onClose();
40
+ }
41
+ }, (cancelProps == null ? void 0 : cancelProps.children) || cancelLabel), /* @__PURE__ */ React.createElement(Button, {
42
+ ref: confirmRef,
43
+ ...confirmProps,
44
+ onClick: () => {
45
+ onConfirm == null ? void 0 : onConfirm();
46
+ closeOnConfirm && onClose();
47
+ }
48
+ }, (confirmProps == null ? void 0 : confirmProps.children) || confirmLabel))))));
49
+ };
50
+ var BaseDrawer = (props) => {
51
+ const {
52
+ title,
53
+ children,
54
+ isOpen,
55
+ onClose,
56
+ hideCloseButton,
57
+ hideOverlay,
58
+ ...rest
59
+ } = props;
60
+ return /* @__PURE__ */ React.createElement(Drawer$1, {
61
+ isOpen,
62
+ onClose,
63
+ ...rest
64
+ }, !hideOverlay && /* @__PURE__ */ React.createElement(DrawerOverlay, null), /* @__PURE__ */ React.createElement(DrawerContent, null, /* @__PURE__ */ React.createElement(DrawerHeader, null, title), !hideCloseButton && /* @__PURE__ */ React.createElement(DrawerCloseButton, null), children));
65
+ };
66
+ var Drawer = (props) => {
67
+ const { footer, children, ...rest } = props;
68
+ return /* @__PURE__ */ React.createElement(BaseDrawer, {
69
+ ...rest
70
+ }, /* @__PURE__ */ React.createElement(DrawerBody, null, children), footer && /* @__PURE__ */ React.createElement(DrawerFooter, null, footer));
71
+ };
72
+ var BaseModal = (props) => {
73
+ const {
74
+ title,
75
+ footer,
76
+ children,
77
+ isOpen,
78
+ onClose,
79
+ hideCloseButton,
80
+ hideOverlay,
81
+ ...rest
82
+ } = props;
83
+ return /* @__PURE__ */ React.createElement(Modal$1, {
84
+ isOpen,
85
+ onClose,
86
+ ...rest
87
+ }, !hideOverlay && /* @__PURE__ */ React.createElement(ModalOverlay, null), /* @__PURE__ */ React.createElement(ModalContent, null, title && /* @__PURE__ */ React.createElement(ModalHeader, null, title), !hideCloseButton && /* @__PURE__ */ React.createElement(ModalCloseButton, null), children, footer && /* @__PURE__ */ React.createElement(ModalFooter, null, footer)));
88
+ };
89
+ var Modal = (props) => {
90
+ const { children, ...rest } = props;
91
+ return /* @__PURE__ */ React.createElement(BaseModal, {
92
+ ...rest
93
+ }, /* @__PURE__ */ React.createElement(ModalBody, null, children));
94
+ };
95
+ var [StylesProvider] = createStylesContext("SuiMenuDialog");
96
+ var MenuDialog = (props) => {
97
+ const { onClose, onCloseComplete, ...rest } = props;
98
+ return /* @__PURE__ */ React.createElement(Menu, {
99
+ variant: "dialog",
100
+ onClose: () => {
101
+ onClose == null ? void 0 : onClose();
102
+ onCloseComplete == null ? void 0 : onCloseComplete();
103
+ },
104
+ ...rest
105
+ });
106
+ };
107
+ var MenuDialogList = forwardRef(
108
+ (props, forwardedRef) => {
109
+ const {
110
+ rootProps,
111
+ title,
112
+ footer,
113
+ initialFocusRef,
114
+ hideCloseButton,
115
+ motionPreset,
116
+ ...rest
117
+ } = props;
118
+ const { isOpen, onClose, menuRef } = useMenuContext();
119
+ const { ref, ...ownProps } = useMenuList(rest, forwardedRef);
120
+ const styles = useMultiStyleConfig("Menu", props);
121
+ return /* @__PURE__ */ React.createElement(BaseModal, {
122
+ isOpen,
123
+ onClose,
124
+ initialFocusRef: initialFocusRef || menuRef,
125
+ title,
126
+ hideCloseButton,
127
+ motionPreset
128
+ }, /* @__PURE__ */ React.createElement(StylesProvider, {
129
+ value: styles
130
+ }, /* @__PURE__ */ React.createElement(chakra.div, {
131
+ ...ownProps,
132
+ ref,
133
+ __css: {
134
+ outline: 0,
135
+ maxHeight: "80vh",
136
+ overflowY: "auto",
137
+ ...styles.list,
138
+ boxShadow: "none",
139
+ border: 0
140
+ }
141
+ })), footer && /* @__PURE__ */ React.createElement(ModalFooter, null, footer));
142
+ }
143
+ );
144
+ var FormDialog = forwardRef(
145
+ (props, ref) => {
146
+ const {
147
+ children,
148
+ schema,
149
+ resolver,
150
+ fieldResolver,
151
+ defaultValues,
152
+ values,
153
+ context,
154
+ onChange,
155
+ onSubmit,
156
+ onError,
157
+ mode,
158
+ reValidateMode,
159
+ shouldFocusError = true,
160
+ shouldUnregister,
161
+ shouldUseNativeValidation,
162
+ criteriaMode,
163
+ delayError = 100,
164
+ cancelLabel = "Cancel",
165
+ submitLabel = "Submit",
166
+ footer,
167
+ isOpen,
168
+ onClose,
169
+ ...rest
170
+ } = props;
171
+ const formProps = {
172
+ ref,
173
+ schema,
174
+ resolver,
175
+ defaultValues,
176
+ values,
177
+ context,
178
+ onChange,
179
+ onSubmit,
180
+ onError,
181
+ mode,
182
+ reValidateMode,
183
+ shouldFocusError,
184
+ shouldUnregister,
185
+ shouldUseNativeValidation,
186
+ criteriaMode,
187
+ delayError
188
+ };
189
+ return /* @__PURE__ */ React.createElement(BaseModal, {
190
+ isOpen,
191
+ onClose,
192
+ ...rest
193
+ }, /* @__PURE__ */ React.createElement(Form, {
194
+ ...formProps,
195
+ ref
196
+ }, (form) => /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(ModalBody, null, runIfFn(children, form) || /* @__PURE__ */ React.createElement(Fields, {
197
+ schema,
198
+ fieldResolver,
199
+ focusFirstField: true
200
+ })), footer || /* @__PURE__ */ React.createElement(ModalFooter, null, /* @__PURE__ */ React.createElement(Button, {
201
+ variant: "ghost",
202
+ mr: 3,
203
+ onClick: onClose
204
+ }, cancelLabel), /* @__PURE__ */ React.createElement(SubmitButton, null, submitLabel)))));
205
+ }
206
+ );
207
+ var ModalsContext = React.createContext(
208
+ null
209
+ );
210
+ var initialModalState = {
211
+ id: null,
212
+ props: null,
213
+ type: "modal"
214
+ };
215
+ var defaultModals = {
216
+ alert: ConfirmDialog,
217
+ confirm: ConfirmDialog,
218
+ drawer: Drawer,
219
+ modal: Modal,
220
+ menu: MenuDialog,
221
+ form: FormDialog
222
+ };
223
+ function ModalsProvider({ children, modals }) {
224
+ const _instances = React.useMemo(() => /* @__PURE__ */ new Set(), []);
225
+ const [activeModals, setActiveModals] = React.useState({
226
+ modal: initialModalState
227
+ });
228
+ const getModalComponent = React.useMemo(() => {
229
+ const _modals = {
230
+ ...defaultModals,
231
+ ...modals
232
+ };
233
+ return (type = "modal") => {
234
+ const component = _modals[type] || _modals.modal;
235
+ return component;
236
+ };
237
+ }, [modals]);
238
+ const setActiveModal = (modal, scope) => {
239
+ if (!scope) {
240
+ return setActiveModals({
241
+ modal
242
+ });
243
+ }
244
+ setActiveModals((prevState) => ({
245
+ ...prevState,
246
+ [scope]: modal
247
+ }));
248
+ };
249
+ const open = (options) => {
250
+ if (typeof options === "function") {
251
+ const component2 = options;
252
+ options = {
253
+ component: component2
254
+ };
255
+ }
256
+ const {
257
+ id = _instances.size + 1,
258
+ type = "modal",
259
+ scope = "modal",
260
+ component,
261
+ ...props
262
+ } = options;
263
+ const modal = {
264
+ id,
265
+ props,
266
+ type,
267
+ scope,
268
+ component,
269
+ isOpen: true
270
+ };
271
+ _instances.add(modal);
272
+ setActiveModal(modal, scope);
273
+ return id;
274
+ };
275
+ const drawer = (options) => {
276
+ return open({
277
+ ...options,
278
+ type: "drawer"
279
+ });
280
+ };
281
+ const alert = (options) => {
282
+ return open({
283
+ ...options,
284
+ scope: "alert",
285
+ type: "alert",
286
+ cancelProps: {
287
+ display: "none"
288
+ },
289
+ confirmProps: {
290
+ label: "OK"
291
+ },
292
+ leastDestructiveFocus: "confirm"
293
+ });
294
+ };
295
+ const confirm = (options) => {
296
+ return open({
297
+ ...options,
298
+ scope: "alert",
299
+ type: "confirm"
300
+ });
301
+ };
302
+ const menu = (options) => {
303
+ return open({
304
+ ...options,
305
+ type: "menu"
306
+ });
307
+ };
308
+ const form = (options) => {
309
+ return open({
310
+ ...options,
311
+ type: "form"
312
+ });
313
+ };
314
+ const close = async (id, force) => {
315
+ var _a, _b;
316
+ const modals2 = [...Array.from(_instances)];
317
+ const modal = modals2.filter((modal2) => modal2.id === id)[0];
318
+ if (!modal) {
319
+ return;
320
+ }
321
+ const shouldClose = await ((_b = (_a = modal.props) == null ? void 0 : _a.onClose) == null ? void 0 : _b.call(_a, { force }));
322
+ if (shouldClose === false) {
323
+ return;
324
+ }
325
+ const scoped = modals2.filter(({ scope }) => scope === modal.scope);
326
+ if (scoped.length === 1) {
327
+ setActiveModal(
328
+ {
329
+ ...modal,
330
+ isOpen: false
331
+ },
332
+ modal.scope
333
+ );
334
+ } else if (scoped.length > 1) {
335
+ setActiveModal(scoped[scoped.length - 2], modal.scope);
336
+ } else {
337
+ setActiveModal(
338
+ {
339
+ id: null,
340
+ props: null,
341
+ type: modal.type
342
+ },
343
+ modal.scope
344
+ );
345
+ }
346
+ };
347
+ const closeComplete = (id) => {
348
+ const modals2 = [...Array.from(_instances)];
349
+ const modal = modals2.filter((modal2) => modal2.id === id)[0];
350
+ _instances.delete(modal);
351
+ const scoped = modals2.filter(({ scope }) => scope === modal.scope);
352
+ if (scoped.length === 1) {
353
+ setActiveModal(initialModalState, modal.scope);
354
+ }
355
+ };
356
+ const closeAll = () => {
357
+ _instances.forEach((modal) => {
358
+ var _a, _b;
359
+ return (_b = (_a = modal.props) == null ? void 0 : _a.onClose) == null ? void 0 : _b.call(_a, { force: true });
360
+ });
361
+ _instances.clear();
362
+ setActiveModal(initialModalState);
363
+ };
364
+ const context = {
365
+ open,
366
+ drawer,
367
+ alert,
368
+ confirm,
369
+ menu,
370
+ form,
371
+ close,
372
+ closeAll
373
+ };
374
+ const content = React.useMemo(
375
+ () => Object.entries(activeModals).map(([scope, config]) => {
376
+ const Component = config.component || getModalComponent(config.type);
377
+ const { title, body, children: children2, ...props } = config.props || {};
378
+ return /* @__PURE__ */ React.createElement(Component, {
379
+ key: scope,
380
+ title,
381
+ children: body || children2,
382
+ ...props,
383
+ isOpen: !!config.isOpen,
384
+ onClose: () => close(config.id),
385
+ onCloseComplete: () => closeComplete(config.id)
386
+ });
387
+ }),
388
+ [activeModals]
389
+ );
390
+ return /* @__PURE__ */ React.createElement(ModalsContext.Provider, {
391
+ value: context
392
+ }, content, children);
393
+ }
394
+ var useModalsContext = () => React.useContext(ModalsContext);
395
+ var useModals = () => {
396
+ return useModalsContext();
397
+ };
398
+
399
+ export { BaseDrawer, BaseModal, ConfirmDialog, Drawer, FormDialog, MenuDialog, MenuDialogList, Modal, ModalsContext, ModalsProvider, useModals, useModalsContext };
400
+ //# sourceMappingURL=out.js.map
401
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/dialog.tsx","../src/drawer.tsx","../src/modal.tsx","../src/menu.tsx","../src/form.tsx","../src/provider.tsx"],"names":["React","ModalFooter","ModalBody","Button","forwardRef","component","modals","modal","children"],"mappings":"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","sourcesContent":["import * as React from 'react'\n\nimport {\n AlertDialog,\n AlertDialogBody,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogContent,\n AlertDialogOverlay,\n AlertDialogProps,\n ButtonGroup,\n ButtonGroupProps,\n Button,\n ButtonProps,\n} from '@chakra-ui/react'\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 {cancelProps?.children || cancelLabel}\n </Button>\n <Button\n ref={confirmRef}\n {...confirmProps}\n onClick={() => {\n onConfirm?.()\n\n closeOnConfirm && onClose()\n }}\n >\n {confirmProps?.children || confirmLabel}\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, ...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 chakra,\n forwardRef,\n useMenuContext,\n useMenuList,\n createStylesContext,\n useMultiStyleConfig,\n Menu,\n MenuListProps,\n} from '@chakra-ui/react'\n\nimport { BaseModal, BaseModalProps } from './modal'\n\nconst [StylesProvider] = createStylesContext('SuiMenuDialog')\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 { onClose, onCloseComplete, ...rest } = props\n\n return (\n <Menu\n variant=\"dialog\"\n onClose={() => {\n onClose?.()\n // Not supported in Menu, so we call it here instead\n // @todo Refactor this in v2?\n onCloseComplete?.()\n }}\n {...rest}\n />\n )\n}\n\nexport interface MenuDialogListProps\n extends Omit<\n BaseModalProps,\n 'isOpen' | 'onClose' | 'children' | 'scrollBehavior'\n >,\n Omit<MenuListProps, 'title'> {}\n\nexport const MenuDialogList = forwardRef<MenuDialogListProps, 'div'>(\n (props, forwardedRef) => {\n const {\n rootProps,\n title,\n footer,\n initialFocusRef,\n hideCloseButton,\n motionPreset,\n ...rest\n } = props\n\n const { isOpen, onClose, menuRef } = useMenuContext()\n\n const { ref, ...ownProps } = useMenuList(rest, forwardedRef)\n\n const styles = useMultiStyleConfig('Menu', props)\n\n return (\n <BaseModal\n isOpen={isOpen}\n onClose={onClose}\n initialFocusRef={initialFocusRef || menuRef}\n title={title}\n hideCloseButton={hideCloseButton}\n motionPreset={motionPreset}\n >\n {/* We forward the styles again, otherwise the modal styles will be picked up */}\n <StylesProvider value={styles}>\n <chakra.div\n {...ownProps}\n ref={ref as React.Ref<HTMLDivElement>}\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 </StylesProvider>\n {footer && <ModalFooter>{footer}</ModalFooter>}\n </BaseModal>\n )\n }\n)\n","import * as React from 'react'\n\nimport { ModalBody, ModalFooter, Button, forwardRef } from '@chakra-ui/react'\nimport { runIfFn } from '@saas-ui/react-utils'\n\nimport {\n Form,\n Fields,\n SubmitButton,\n FormProps,\n FieldValues,\n FieldResolver,\n} from '@saas-ui/forms'\n\nimport { BaseModal, BaseModalProps } from './modal'\n\nexport interface FormDialogProps<\n TFieldValues extends FieldValues = FieldValues,\n TContext extends object = object\n> extends Omit<BaseModalProps, 'children'>,\n Pick<\n FormProps<TFieldValues, TContext>,\n | 'schema'\n | 'defaultValues'\n | 'values'\n | 'context'\n | 'onChange'\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 <\n TFieldValues extends FieldValues = FieldValues,\n TContext extends object = object\n >(\n props: FormDialogProps<TFieldValues, TContext>,\n ref: React.ForwardedRef<HTMLFormElement>\n ) => {\n const {\n children,\n schema,\n resolver,\n fieldResolver,\n defaultValues,\n values,\n context,\n onChange,\n onSubmit,\n onError,\n mode,\n reValidateMode,\n shouldFocusError = true,\n shouldUnregister,\n shouldUseNativeValidation,\n criteriaMode,\n delayError = 100,\n cancelLabel = 'Cancel',\n submitLabel = 'Submit',\n footer,\n isOpen,\n onClose,\n ...rest\n } = props\n\n const formProps = {\n ref,\n schema,\n resolver,\n defaultValues,\n values,\n context,\n onChange,\n onSubmit,\n onError,\n mode,\n reValidateMode,\n shouldFocusError,\n shouldUnregister,\n shouldUseNativeValidation,\n criteriaMode,\n delayError,\n }\n\n return (\n <BaseModal isOpen={isOpen} onClose={onClose} {...rest}>\n <Form {...formProps} ref={ref}>\n {(form) => (\n <>\n <ModalBody>\n {runIfFn(children, form) || (\n <Fields\n schema={schema}\n fieldResolver={fieldResolver}\n focusFirstField\n />\n )}\n </ModalBody>\n\n {footer || (\n <ModalFooter>\n <Button variant=\"ghost\" mr={3} onClick={onClose}>\n {cancelLabel}\n </Button>\n <SubmitButton>{submitLabel}</SubmitButton>\n </ModalFooter>\n )}\n </>\n )}\n </Form>\n </BaseModal>\n )\n }\n) as <TFieldValues extends FieldValues>(\n props: FormDialogProps<TFieldValues> & {\n ref?: React.ForwardedRef<HTMLFormElement>\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 * Whether the modal is open or not.\n * This is used internally to keep track of the modal state.\n */\n isOpen?: boolean\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: Record<string, React.FC<any>> = {\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 isOpen: true,\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 const scoped = modals.filter(({ scope }) => scope === modal.scope)\n\n if (scoped.length === 1) {\n setActiveModal(\n {\n ...modal,\n isOpen: false,\n },\n modal.scope\n )\n } else if (scoped.length > 1) {\n setActiveModal(scoped[scoped.length - 2], modal.scope)\n } else {\n setActiveModal(\n {\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\n const closeComplete = (id?: ModalId | null) => {\n const modals = [...Array.from(_instances)]\n const modal = modals.filter((modal) => modal.id === id)[0]\n\n _instances.delete(modal)\n\n const scoped = modals.filter(({ scope }) => scope === modal.scope)\n\n if (scoped.length === 1) {\n setActiveModal(initialModalState, 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 = React.useMemo(\n () =>\n 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.isOpen}\n onClose={() => close(config.id)}\n onCloseComplete={() => closeComplete(config.id)}\n />\n )\n }),\n [activeModals]\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"]}
package/package.json CHANGED
@@ -1,23 +1,23 @@
1
1
  {
2
2
  "name": "@saas-ui/modals",
3
- "version": "1.5.5",
3
+ "version": "2.0.0-next.1",
4
4
  "description": "A modal manager for Chakra UI",
5
5
  "source": "src/index.ts",
6
6
  "exports": {
7
7
  ".": {
8
8
  "require": "./dist/index.js",
9
- "import": "./dist/index.modern.mjs"
9
+ "import": "./dist/index.mjs"
10
10
  },
11
11
  "./src": {
12
12
  "default": "./src/index.ts"
13
13
  }
14
14
  },
15
15
  "main": "./dist/index.js",
16
- "module": "./dist/index.modern.mjs",
16
+ "module": "./dist/index.mjs",
17
17
  "types": "./dist/index.d.ts",
18
18
  "scripts": {
19
19
  "clean": "rimraf dist",
20
- "build": "yarn clean && cross-env NODE_ENV=production microbundle --tsconfig ./tsconfig.json --jsx React.createElement --jsxFragment React.Fragment -f cjs,modern --compress",
20
+ "build": "tsup src/index.ts --config tsup.config.ts",
21
21
  "lint": "eslint src --ext .ts,.tsx,.js,.jsx --config ../../.eslintrc.js",
22
22
  "lint:staged": "lint-staged --allow-empty --config ../../lint-staged.config.js",
23
23
  "typecheck": "tsc --noEmit"
@@ -57,14 +57,16 @@
57
57
  },
58
58
  "dependencies": {
59
59
  "@chakra-ui/utils": "^2.0.14",
60
- "@saas-ui/button": "1.4.0",
61
- "@saas-ui/forms": "1.5.3",
62
- "@saas-ui/menu": "1.4.1"
60
+ "@saas-ui/forms": "2.0.0-next.1",
61
+ "@saas-ui/hooks": "2.0.0-next.1",
62
+ "@saas-ui/react-utils": "2.0.0-next.1"
63
63
  },
64
64
  "peerDependencies": {
65
- "@chakra-ui/react": ">=2.4.6",
66
- "@chakra-ui/system": ">=2.3.8",
67
- "framer-motion": ">=5.5.0",
68
- "react": ">=18.0.0"
65
+ "@chakra-ui/react": ">=2.4.9",
66
+ "@emotion/react": ">=11.0.0",
67
+ "@emotion/styled": ">=11.0.0",
68
+ "framer-motion": ">=6.0.0",
69
+ "react": ">=18.0.0",
70
+ "react-dom": ">=18.0.0"
69
71
  }
70
72
  }
package/src/dialog.tsx CHANGED
@@ -8,14 +8,11 @@ import {
8
8
  AlertDialogContent,
9
9
  AlertDialogOverlay,
10
10
  AlertDialogProps,
11
- } from '@chakra-ui/react'
12
-
13
- import {
14
11
  ButtonGroup,
15
12
  ButtonGroupProps,
16
13
  Button,
17
14
  ButtonProps,
18
- } from '@saas-ui/button'
15
+ } from '@chakra-ui/react'
19
16
 
20
17
  export interface ConfirmDialogProps
21
18
  extends Omit<AlertDialogProps, 'leastDestructiveRef'> {
@@ -116,7 +113,7 @@ export const ConfirmDialog: React.FC<ConfirmDialogProps> = (props) => {
116
113
  closeOnCancel && onClose()
117
114
  }}
118
115
  >
119
- {cancelProps?.children || cancelProps?.label || cancelLabel}
116
+ {cancelProps?.children || cancelLabel}
120
117
  </Button>
121
118
  <Button
122
119
  ref={confirmRef}
@@ -127,7 +124,7 @@ export const ConfirmDialog: React.FC<ConfirmDialogProps> = (props) => {
127
124
  closeOnConfirm && onClose()
128
125
  }}
129
126
  >
130
- {confirmProps?.children || confirmProps?.label || confirmLabel}
127
+ {confirmProps?.children || confirmLabel}
131
128
  </Button>
132
129
  </ButtonGroup>
133
130
  </AlertDialogFooter>
package/src/form.tsx CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as React from 'react'
2
2
 
3
3
  import { ModalBody, ModalFooter, Button, forwardRef } from '@chakra-ui/react'
4
- import { runIfFn } from '@chakra-ui/utils'
4
+ import { runIfFn } from '@saas-ui/react-utils'
5
5
 
6
6
  import {
7
7
  Form,
@@ -10,17 +10,20 @@ import {
10
10
  FormProps,
11
11
  FieldValues,
12
12
  FieldResolver,
13
- UseFormReturn,
14
13
  } from '@saas-ui/forms'
15
14
 
16
15
  import { BaseModal, BaseModalProps } from './modal'
17
16
 
18
- export interface FormDialogProps<TFieldValues extends FieldValues = FieldValues>
19
- extends Omit<BaseModalProps, 'children'>,
17
+ export interface FormDialogProps<
18
+ TFieldValues extends FieldValues = FieldValues,
19
+ TContext extends object = object
20
+ > extends Omit<BaseModalProps, 'children'>,
20
21
  Pick<
21
- FormProps<TFieldValues>,
22
+ FormProps<TFieldValues, TContext>,
22
23
  | 'schema'
23
24
  | 'defaultValues'
25
+ | 'values'
26
+ | 'context'
24
27
  | 'onChange'
25
28
  | 'onSubmit'
26
29
  | 'onError'
@@ -59,9 +62,12 @@ export interface FormDialogProps<TFieldValues extends FieldValues = FieldValues>
59
62
  }
60
63
 
61
64
  export const FormDialog = forwardRef(
62
- <TFieldValues extends FieldValues = FieldValues>(
63
- props: FormDialogProps<TFieldValues>,
64
- ref: React.ForwardedRef<UseFormReturn<TFieldValues>>
65
+ <
66
+ TFieldValues extends FieldValues = FieldValues,
67
+ TContext extends object = object
68
+ >(
69
+ props: FormDialogProps<TFieldValues, TContext>,
70
+ ref: React.ForwardedRef<HTMLFormElement>
65
71
  ) => {
66
72
  const {
67
73
  children,
@@ -69,6 +75,8 @@ export const FormDialog = forwardRef(
69
75
  resolver,
70
76
  fieldResolver,
71
77
  defaultValues,
78
+ values,
79
+ context,
72
80
  onChange,
73
81
  onSubmit,
74
82
  onError,
@@ -79,8 +87,8 @@ export const FormDialog = forwardRef(
79
87
  shouldUseNativeValidation,
80
88
  criteriaMode,
81
89
  delayError = 100,
82
- cancelLabel,
83
- submitLabel,
90
+ cancelLabel = 'Cancel',
91
+ submitLabel = 'Submit',
84
92
  footer,
85
93
  isOpen,
86
94
  onClose,
@@ -92,6 +100,8 @@ export const FormDialog = forwardRef(
92
100
  schema,
93
101
  resolver,
94
102
  defaultValues,
103
+ values,
104
+ context,
95
105
  onChange,
96
106
  onSubmit,
97
107
  onError,
@@ -106,7 +116,7 @@ export const FormDialog = forwardRef(
106
116
 
107
117
  return (
108
118
  <BaseModal isOpen={isOpen} onClose={onClose} {...rest}>
109
- <Form {...formProps}>
119
+ <Form {...formProps} ref={ref}>
110
120
  {(form) => (
111
121
  <>
112
122
  <ModalBody>
@@ -122,9 +132,9 @@ export const FormDialog = forwardRef(
122
132
  {footer || (
123
133
  <ModalFooter>
124
134
  <Button variant="ghost" mr={3} onClick={onClose}>
125
- {cancelLabel || 'Cancel'}
135
+ {cancelLabel}
126
136
  </Button>
127
- <SubmitButton>{submitLabel || 'Submit'}</SubmitButton>
137
+ <SubmitButton>{submitLabel}</SubmitButton>
128
138
  </ModalFooter>
129
139
  )}
130
140
  </>
@@ -135,6 +145,6 @@ export const FormDialog = forwardRef(
135
145
  }
136
146
  ) as <TFieldValues extends FieldValues>(
137
147
  props: FormDialogProps<TFieldValues> & {
138
- ref?: React.ForwardedRef<UseFormReturn<TFieldValues>>
148
+ ref?: React.ForwardedRef<HTMLFormElement>
139
149
  }
140
150
  ) => React.ReactElement
package/src/menu.tsx CHANGED
@@ -12,11 +12,9 @@ import {
12
12
  MenuListProps,
13
13
  } from '@chakra-ui/react'
14
14
 
15
- import {} from '@chakra-ui/system'
16
-
17
15
  import { BaseModal, BaseModalProps } from './modal'
18
16
 
19
- const [StylesProvider] = createStylesContext('MenuDialog')
17
+ const [StylesProvider] = createStylesContext('SuiMenuDialog')
20
18
 
21
19
  export interface MenuDialogProps extends BaseModalProps {
22
20
  /**