@saas-ui/modals 0.1.1 → 0.2.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.
@@ -1,6 +1,6 @@
1
- @saas-ui/modals:build: cache hit, replaying output c20143510457fd4d
2
- @saas-ui/modals:build: Build "@saas-ui/modals" to dist:
3
- @saas-ui/modals:build:  1.82 kB: index.js.gz
4
- @saas-ui/modals:build:  1.63 kB: index.js.br
5
- @saas-ui/modals:build:  1696 B: index.modern.js.gz
6
- @saas-ui/modals:build:  1529 B: index.modern.js.br
1
+ @saas-ui/modals:build: cache hit, replaying output b82b6517a24fbe55
2
+ @saas-ui/modals:build: Build "@saas-ui/modals" to dist:
3
+ @saas-ui/modals:build:  2.22 kB: index.js.gz
4
+ @saas-ui/modals:build:  1.98 kB: index.js.br
5
+ @saas-ui/modals:build:  2.17 kB: index.modern.js.gz
6
+ @saas-ui/modals:build:  1.94 kB: index.modern.js.br
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @saas-ui/modals
2
2
 
3
+ ## 0.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 4733b8f: Added new MenuDialog component
8
+
3
9
  ## 0.1.1
4
10
 
5
11
  ### Patch Changes
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export * from './dialog';
2
2
  export * from './drawer';
3
3
  export * from './modal';
4
+ export * from './menu';
4
5
  export * from './provider';
5
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAA;AACxB,cAAc,UAAU,CAAA;AACxB,cAAc,SAAS,CAAA;AACvB,cAAc,YAAY,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAA;AACxB,cAAc,UAAU,CAAA;AACxB,cAAc,SAAS,CAAA;AACvB,cAAc,QAAQ,CAAA;AACtB,cAAc,YAAY,CAAA"}
package/dist/index.js CHANGED
@@ -1,354 +1,2 @@
1
- var e = require('react'),
2
- n = require('@chakra-ui/react'),
3
- r = require('@saas-ui/button')
4
- function t(e) {
5
- if (e && e.__esModule) return e
6
- var n = Object.create(null)
7
- return (
8
- e &&
9
- Object.keys(e).forEach(function (r) {
10
- if ('default' !== r) {
11
- var t = Object.getOwnPropertyDescriptor(e, r)
12
- Object.defineProperty(
13
- n,
14
- r,
15
- t.get
16
- ? t
17
- : {
18
- enumerable: !0,
19
- get: function () {
20
- return e[r]
21
- },
22
- }
23
- )
24
- }
25
- }),
26
- (n.default = e),
27
- n
28
- )
29
- }
30
- var o = /*#__PURE__*/ t(e)
31
- function l() {
32
- return (
33
- (l =
34
- Object.assign ||
35
- function (e) {
36
- for (var n = 1; n < arguments.length; n++) {
37
- var r = arguments[n]
38
- for (var t in r)
39
- Object.prototype.hasOwnProperty.call(r, t) && (e[t] = r[t])
40
- }
41
- return e
42
- }),
43
- l.apply(this, arguments)
44
- )
45
- }
46
- function a(e, n) {
47
- if (null == e) return {}
48
- var r,
49
- t,
50
- o = {},
51
- l = Object.keys(e)
52
- for (t = 0; t < l.length; t++) n.indexOf((r = l[t])) >= 0 || (o[r] = e[r])
53
- return o
54
- }
55
- var c = [
56
- 'title',
57
- 'cancelLabel',
58
- 'confirmLabel',
59
- 'cancelProps',
60
- 'confirmProps',
61
- 'buttonGroupProps',
62
- 'isOpen',
63
- 'closeOnCancel',
64
- 'closeOnConfirm',
65
- 'leastDestructiveFocus',
66
- 'onClose',
67
- 'onCancel',
68
- 'onConfirm',
69
- 'children',
70
- ],
71
- i = function (e) {
72
- var t = e.title,
73
- i = e.cancelProps,
74
- u = e.confirmProps,
75
- s = e.buttonGroupProps,
76
- d = e.isOpen,
77
- f = e.closeOnCancel,
78
- p = void 0 === f || f,
79
- m = e.closeOnConfirm,
80
- v = void 0 === m || m,
81
- C = e.leastDestructiveFocus,
82
- h = void 0 === C ? 'cancel' : C,
83
- O = e.onClose,
84
- y = e.onCancel,
85
- E = e.onConfirm,
86
- D = e.children,
87
- b = a(e, c),
88
- M = o.useRef(null),
89
- P = o.useRef(null)
90
- /*#__PURE__*/ return o.createElement(
91
- n.AlertDialog,
92
- l({ isOpen: d, onClose: O }, b, {
93
- leastDestructiveRef: 'cancel' === h ? M : P,
94
- }),
95
- /*#__PURE__*/ o.createElement(
96
- n.AlertDialogOverlay,
97
- null,
98
- /*#__PURE__*/ o.createElement(
99
- n.AlertDialogContent,
100
- null,
101
- /*#__PURE__*/ o.createElement(n.AlertDialogHeader, null, t),
102
- /*#__PURE__*/ o.createElement(n.AlertDialogBody, null, D),
103
- /*#__PURE__*/ o.createElement(
104
- n.AlertDialogFooter,
105
- null,
106
- /*#__PURE__*/ o.createElement(
107
- r.ButtonGroup,
108
- s,
109
- /*#__PURE__*/ o.createElement(
110
- r.Button,
111
- l({ ref: M }, i, {
112
- onClick: function () {
113
- null == y || y(), p && O()
114
- },
115
- }),
116
- 'Cancel'
117
- ),
118
- /*#__PURE__*/ o.createElement(
119
- r.Button,
120
- l({ ref: P }, u, {
121
- onClick: function () {
122
- null == E || E(), v && O()
123
- },
124
- }),
125
- 'Confirm'
126
- )
127
- )
128
- )
129
- )
130
- )
131
- )
132
- },
133
- u = [
134
- 'title',
135
- 'children',
136
- 'isOpen',
137
- 'onClose',
138
- 'hideCloseButton',
139
- 'hideOverlay',
140
- ],
141
- s = ['footer', 'children'],
142
- d = function (e) {
143
- var r = e.title,
144
- t = e.children,
145
- c = e.isOpen,
146
- i = e.onClose,
147
- s = e.hideCloseButton,
148
- d = e.hideOverlay,
149
- f = a(e, u)
150
- /*#__PURE__*/ return o.createElement(
151
- n.Drawer,
152
- l({ isOpen: c, onClose: i }, f),
153
- !d && /*#__PURE__*/ o.createElement(n.DrawerOverlay, null),
154
- /*#__PURE__*/ o.createElement(
155
- n.DrawerContent,
156
- null,
157
- /*#__PURE__*/ o.createElement(n.DrawerHeader, null, r),
158
- !s && /*#__PURE__*/ o.createElement(n.DrawerCloseButton, null),
159
- t
160
- )
161
- )
162
- },
163
- f = function (e) {
164
- var r = e.footer,
165
- t = e.children,
166
- l = a(e, s)
167
- /*#__PURE__*/ return o.createElement(
168
- d,
169
- l,
170
- /*#__PURE__*/ o.createElement(n.DrawerBody, null, t),
171
- r && /*#__PURE__*/ o.createElement(n.DrawerFooter, null, r)
172
- )
173
- },
174
- p = [
175
- 'title',
176
- 'children',
177
- 'isOpen',
178
- 'onClose',
179
- 'hideCloseButton',
180
- 'hideOverlay',
181
- ],
182
- m = ['children', 'footer'],
183
- v = function (e) {
184
- var r = e.title,
185
- t = e.children,
186
- c = e.isOpen,
187
- i = e.onClose,
188
- u = e.hideCloseButton,
189
- s = e.hideOverlay,
190
- d = a(e, p)
191
- /*#__PURE__*/ return o.createElement(
192
- n.Modal,
193
- l({ isOpen: c, onClose: i }, d),
194
- !s && /*#__PURE__*/ o.createElement(n.ModalOverlay, null),
195
- /*#__PURE__*/ o.createElement(
196
- n.ModalContent,
197
- null,
198
- /*#__PURE__*/ o.createElement(n.ModalHeader, null, r),
199
- !u && /*#__PURE__*/ o.createElement(n.ModalCloseButton, null),
200
- t
201
- )
202
- )
203
- },
204
- C = function (e) {
205
- var r = e.children,
206
- t = e.footer,
207
- l = a(e, m)
208
- /*#__PURE__*/ return o.createElement(
209
- v,
210
- l,
211
- /*#__PURE__*/ o.createElement(n.ModalBody, null, r),
212
- t && /*#__PURE__*/ o.createElement(n.ModalFooter, null, t)
213
- )
214
- },
215
- h = ['id', 'type', 'scope'],
216
- O = ['title', 'children'],
217
- y = o.createContext({}),
218
- E = { id: null, props: null, type: 'modal' },
219
- D = { alert: i, confirm: i, drawer: f, modal: C },
220
- b = function () {
221
- return o.useContext(y)
222
- }
223
- ;(exports.BaseDrawer = d),
224
- (exports.BaseModal = v),
225
- (exports.ConfirmDialog = i),
226
- (exports.Drawer = f),
227
- (exports.Modal = C),
228
- (exports.ModalsContext = y),
229
- (exports.ModalsProvider = function (e) {
230
- var n = e.children,
231
- r = e.modals,
232
- t = o.useMemo(function () {
233
- return new Set()
234
- }, []),
235
- c = o.useState({ modal: E }),
236
- i = c[0],
237
- u = c[1],
238
- s = o.useMemo(
239
- function () {
240
- var e = l({}, D, r)
241
- return function (n) {
242
- return void 0 === n && (n = 'modal'), e[n] || e.modal
243
- }
244
- },
245
- [r]
246
- ),
247
- d = function (e, n) {
248
- if (!n) return u({ modal: e })
249
- u(function (r) {
250
- var t
251
- return l({}, r, (((t = {})[n] = e), t))
252
- })
253
- },
254
- f = function (e) {
255
- var n = e.id,
256
- r = void 0 === n ? t.size + 1 : n,
257
- o = e.type,
258
- c = void 0 === o ? 'modal' : o,
259
- i = e.scope,
260
- u = void 0 === i ? 'modal' : i,
261
- s = a(e, h),
262
- f = {
263
- id: r,
264
- props: l({}, s, { children: s.body || s.children }),
265
- type: c,
266
- scope: u,
267
- }
268
- return t.add(f), d(f, u), r
269
- },
270
- p = function (e, n) {
271
- try {
272
- var r,
273
- o = [].concat(t),
274
- l = o.filter(function (n) {
275
- return n.id === e
276
- })[0]
277
- return l
278
- ? Promise.resolve(
279
- null == (r = l.props) || null == r.onClose
280
- ? void 0
281
- : r.onClose({ force: n })
282
- ).then(function (e) {
283
- if (!1 !== e) {
284
- t.delete(l)
285
- var n = o.filter(function (e) {
286
- return e.scope === l.scope
287
- })
288
- d(
289
- n[n.length - 2] || { id: null, props: null, type: l.type },
290
- l.scope
291
- )
292
- }
293
- })
294
- : Promise.resolve()
295
- } catch (e) {
296
- return Promise.reject(e)
297
- }
298
- },
299
- m = {
300
- open: f,
301
- drawer: function (e) {
302
- return f(l({}, e, { type: 'drawer' }))
303
- },
304
- alert: function (e) {
305
- return f(
306
- l({}, e, {
307
- scope: 'alert',
308
- type: 'alert',
309
- cancelProps: { display: 'none' },
310
- confirmProps: { label: 'OK' },
311
- leastDestructiveFocus: 'confirm',
312
- })
313
- )
314
- },
315
- confirm: function (e) {
316
- return f(l({}, e, { scope: 'alert', type: 'confirm' }))
317
- },
318
- close: p,
319
- closeAll: function () {
320
- t.forEach(function (e) {
321
- var n
322
- return null == (n = e.props) || null == n.onClose
323
- ? void 0
324
- : n.onClose({ force: !0 })
325
- }),
326
- t.clear(),
327
- d(E)
328
- },
329
- },
330
- v = Object.entries(i).map(function (e) {
331
- var n = e[0],
332
- r = e[1],
333
- c = s(r.type),
334
- i = r.props || {},
335
- u = i.title,
336
- d = i.children,
337
- f = a(i, O)
338
- /*#__PURE__*/ return o.createElement(
339
- c,
340
- l({ key: n, title: u, children: d }, f, {
341
- isOpen: !(!r.id || !t.size),
342
- onClose: function () {
343
- return p(r.id)
344
- },
345
- })
346
- )
347
- })
348
- /*#__PURE__*/ return o.createElement(y.Provider, { value: m }, v, n)
349
- }),
350
- (exports.useModals = function () {
351
- return b()
352
- }),
353
- (exports.useModalsContext = b)
1
+ var e=require("react"),n=require("@chakra-ui/react"),t=require("@saas-ui/button");function r(e){if(e&&e.__esModule)return e;var n=Object.create(null);return e&&Object.keys(e).forEach(function(t){if("default"!==t){var r=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(n,t,r.get?r:{enumerable:!0,get:function(){return e[t]}})}}),n.default=e,n}var o=/*#__PURE__*/r(e);function l(){return l=Object.assign||function(e){for(var n=1;n<arguments.length;n++){var t=arguments[n];for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r])}return e},l.apply(this,arguments)}function a(e,n){if(null==e)return{};var t,r,o={},l=Object.keys(e);for(r=0;r<l.length;r++)n.indexOf(t=l[r])>=0||(o[t]=e[t]);return o}var i=["title","cancelLabel","confirmLabel","cancelProps","confirmProps","buttonGroupProps","isOpen","closeOnCancel","closeOnConfirm","leastDestructiveFocus","onClose","onCancel","onConfirm","children"],u=function(e){var r=e.title,u=e.cancelProps,c=e.confirmProps,s=e.buttonGroupProps,d=e.isOpen,f=e.closeOnCancel,p=void 0===f||f,m=e.closeOnConfirm,v=void 0===m||m,C=e.leastDestructiveFocus,h=void 0===C?"cancel":C,O=e.onClose,E=e.onCancel,y=e.onConfirm,M=e.children,D=a(e,i),P=o.useRef(null),g=o.useRef(null);/*#__PURE__*/return o.createElement(n.AlertDialog,l({isOpen:d,onClose:O},D,{leastDestructiveRef:"cancel"===h?P:g}),/*#__PURE__*/o.createElement(n.AlertDialogOverlay,null,/*#__PURE__*/o.createElement(n.AlertDialogContent,null,/*#__PURE__*/o.createElement(n.AlertDialogHeader,null,r),/*#__PURE__*/o.createElement(n.AlertDialogBody,null,M),/*#__PURE__*/o.createElement(n.AlertDialogFooter,null,/*#__PURE__*/o.createElement(t.ButtonGroup,s,/*#__PURE__*/o.createElement(t.Button,l({ref:P},u,{onClick:function(){null==E||E(),p&&O()}}),"Cancel"),/*#__PURE__*/o.createElement(t.Button,l({ref:g},c,{onClick:function(){null==y||y(),v&&O()}}),"Confirm"))))))},c=["title","children","isOpen","onClose","hideCloseButton","hideOverlay"],s=["footer","children"],d=function(e){var t=e.title,r=e.children,i=e.isOpen,u=e.onClose,s=e.hideCloseButton,d=e.hideOverlay,f=a(e,c);/*#__PURE__*/return o.createElement(n.Drawer,l({isOpen:i,onClose:u},f),!d&&/*#__PURE__*/o.createElement(n.DrawerOverlay,null),/*#__PURE__*/o.createElement(n.DrawerContent,null,/*#__PURE__*/o.createElement(n.DrawerHeader,null,t),!s&&/*#__PURE__*/o.createElement(n.DrawerCloseButton,null),r))},f=function(e){var t=e.footer,r=e.children,l=a(e,s);/*#__PURE__*/return o.createElement(d,l,/*#__PURE__*/o.createElement(n.DrawerBody,null,r),t&&/*#__PURE__*/o.createElement(n.DrawerFooter,null,t))},p=["title","footer","children","isOpen","onClose","hideCloseButton","hideOverlay"],m=["children","footer"],v=function(e){var t=e.title,r=e.footer,i=e.children,u=e.isOpen,c=e.onClose,s=e.hideCloseButton,d=e.hideOverlay,f=a(e,p);/*#__PURE__*/return o.createElement(n.Modal,l({isOpen:u,onClose:c},f),!d&&/*#__PURE__*/o.createElement(n.ModalOverlay,null),/*#__PURE__*/o.createElement(n.ModalContent,null,t&&/*#__PURE__*/o.createElement(n.ModalHeader,null,t),!s&&/*#__PURE__*/o.createElement(n.ModalCloseButton,null),i,r&&/*#__PURE__*/o.createElement(n.ModalFooter,null,r)))},C=function(e){var t=e.children,r=a(e,m);/*#__PURE__*/return o.createElement(v,r,/*#__PURE__*/o.createElement(n.ModalBody,null,t))},h=["children","footer","isOpen","onClose"],O=["descendants"],E=["rootProps"],y=function(e){var t=e.children,r=e.footer,i=e.isOpen,u=e.onClose,c=a(e,h),s=n.useMultiStyleConfig("Menu",e),d=n.useTheme(),f=n.useMenu({onClose:u,autoSelect:!0,defaultIsOpen:!0,closeOnBlur:!1,direction:d.direction}),p=f.descendants,m=a(f,O),C=o.useMemo(function(){return m},[m]);return o.useEffect(function(){m.openAndFocusFirstItem()},[e.isOpen]),/*#__PURE__*/o.createElement(v,l({isOpen:i,onClose:u,initialFocusRef:m.menuRef},c),/*#__PURE__*/o.createElement(n.MenuDescendantsProvider,{value:p},/*#__PURE__*/o.createElement(n.MenuProvider,{value:C},/*#__PURE__*/o.createElement(n.StylesProvider,{value:s},t))),r&&/*#__PURE__*/o.createElement(n.ModalFooter,null,r))};y.defaultProps={variant:"dialog"};var M=n.forwardRef(function(e,t){var r=a(e,E),i=n.useMenuList(r,t),u=n.useStyles();/*#__PURE__*/return o.createElement(n.chakra.div,l({},i,{__css:l({outline:0,maxHeight:"80vh",overflowY:"auto"},u.list,{boxShadow:"none",border:0})}))}),D=["id","type","scope"],P=["title","children"],g=o.createContext({}),b={id:null,props:null,type:"modal"},w={alert:u,confirm:u,drawer:f,modal:C,menu:y},x=function(){return o.useContext(g)};exports.BaseDrawer=d,exports.BaseModal=v,exports.ConfirmDialog=u,exports.Drawer=f,exports.MenuDialog=y,exports.MenuDialogList=M,exports.Modal=C,exports.ModalsContext=g,exports.ModalsProvider=function(e){var n=e.children,t=e.modals,r=o.useMemo(function(){return new Set},[]),i=o.useState({modal:b}),u=i[0],c=i[1],s=o.useMemo(function(){var e=l({},w,t);return function(n){return void 0===n&&(n="modal"),e[n]||e.modal}},[t]),d=function(e,n){if(!n)return c({modal:e});c(function(t){var r;return l({},t,((r={})[n]=e,r))})},f=function(e){var n=e.id,t=void 0===n?r.size+1:n,o=e.type,i=void 0===o?"modal":o,u=e.scope,c=void 0===u?"modal":u,s=a(e,D),f={id:t,props:l({},s,{children:s.body||s.children}),type:i,scope:c};return r.add(f),d(f,c),t},p=function(e,n){try{var t,o=[].concat(r),l=o.filter(function(n){return n.id===e})[0];return l?Promise.resolve(null==(t=l.props)||null==t.onClose?void 0:t.onClose({force:n})).then(function(e){if(!1!==e){r.delete(l);var n=o.filter(function(e){return e.scope===l.scope});d(n[n.length-2]||{id:null,props:null,type:l.type},l.scope)}}):Promise.resolve()}catch(e){return Promise.reject(e)}},m={open:f,drawer:function(e){return f(l({},e,{type:"drawer"}))},alert:function(e){return f(l({},e,{scope:"alert",type:"alert",cancelProps:{display:"none"},confirmProps:{label:"OK"},leastDestructiveFocus:"confirm"}))},confirm:function(e){return f(l({},e,{scope:"alert",type:"confirm"}))},menu:function(e){return f(l({},e,{type:"menu"}))},close:p,closeAll:function(){r.forEach(function(e){var n;return null==(n=e.props)||null==n.onClose?void 0:n.onClose({force:!0})}),r.clear(),d(b)}},v=Object.entries(u).map(function(e){var n=e[0],t=e[1],i=s(t.type),u=t.props||{},c=u.title,d=u.children,f=a(u,P);/*#__PURE__*/return o.createElement(i,l({key:n,title:c,children:d},f,{isOpen:!(!t.id||!r.size),onClose:function(){return p(t.id)}}))});/*#__PURE__*/return o.createElement(g.Provider,{value:m},v,n)},exports.useModals=function(){return x()},exports.useModalsContext=x;
354
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/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 * 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 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 <ModalHeader>{title}</ModalHeader>\n {!hideCloseButton && <ModalCloseButton />}\n {children}\n </ModalContent>\n </ChakraModal>\n )\n}\n\nexport interface ModalProps extends BaseModalProps {\n /**\n * The modal footer, wrapped with `ModalFooter`\n */\n footer?: React.ReactNode\n}\n\nexport const Modal: React.FC<ModalProps> = (props) => {\n const { children, footer, ...rest } = props\n return (\n <BaseModal {...rest}>\n <ModalBody>{children}</ModalBody>\n\n {footer && <ModalFooter>{footer}</ModalFooter>}\n </BaseModal>\n )\n}\n","import * as React from 'react'\n\nimport { Modal, ModalProps } from './modal'\nimport { Drawer, DrawerProps } from './drawer'\nimport { ConfirmDialog, ConfirmDialogProps } from './dialog'\n\nexport interface ModalsContextValue {\n open?: (options: OpenOptions) => ModalId\n drawer?: (options: ModalOptions) => ModalId\n alert?: (options: ModalOptions) => ModalId\n confirm?: (options: ModalOptions) => 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<\n (ModalProps & DrawerProps & ConfirmDialogProps) & {\n body?: React.ReactNode\n },\n 'onClose' | 'isOpen' | 'children'\n > {\n onClose?: (args: { force?: boolean }) => Promise<boolean | undefined> | void\n children?: React.ReactNode\n}\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'\n\nexport interface ModalConfig {\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?: ModalOptions | 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}\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 = (options: OpenOptions): ModalId => {\n const {\n id = _instances.size + 1,\n type = 'modal',\n scope = 'modal',\n ...props\n } = options\n\n const modal: ModalConfig = {\n id,\n props: {\n ...props,\n children: props.body || props.children,\n },\n type,\n scope,\n }\n\n _instances.add(modal)\n setActiveModal(modal, scope)\n\n return id\n }\n\n const drawer = (options: ModalOptions): ModalId => {\n return open({\n ...options,\n type: 'drawer',\n })\n }\n\n const alert = (options: ModalOptions): 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: ModalOptions): ModalId => {\n return open({\n ...options,\n scope: 'alert',\n type: 'confirm',\n })\n }\n\n const close = async (id?: ModalId | null, force?: boolean) => {\n const modals = [..._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 close,\n closeAll,\n }\n\n const content = Object.entries(activeModals).map(([scope, config]) => {\n const Component = getModalComponent(config.type)\n\n const { title, children, ...props } = config.props || {}\n\n return (\n <Component\n key={scope}\n title={title}\n children={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","Modal","ModalBody","ModalFooter","ModalsContext","createContext","initialModalState","id","type","defaultModals","alert","confirm","drawer","modal","useModalsContext","useContext","modals","_instances","useMemo","Set","useState","activeModals","setActiveModals","getModalComponent","_modals","setActiveModal","scope","prevState","open","options","size","body","add","close","force","filter","_modal$props","shouldClose","scoped","length","context","display","label","closeAll","forEach","_modal$props2","clear","content","Object","entries","map","config","Component","key","Provider","value"],"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/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 { Modal, BaseModalProps } from './modal'\nimport { Drawer, DrawerProps } from './drawer'\nimport { ConfirmDialog, ConfirmDialogProps } from './dialog'\nimport { MenuDialog, MenuDialogProps } from './menu'\n\nexport interface ModalsContextValue {\n open?: (options: OpenOptions) => ModalId\n drawer?: (options: ModalOptions) => ModalId\n alert?: (options: ModalOptions) => ModalId\n confirm?: (options: ModalOptions) => ModalId\n menu?: (options: ModalOptions) => 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<\n (BaseModalProps & DrawerProps & ConfirmDialogProps) & {\n body?: React.ReactNode\n },\n 'onClose' | 'isOpen' | 'children'\n > {\n onClose?: (args: { force?: boolean }) => Promise<boolean | undefined> | void\n children?: React.ReactNode\n}\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 /**\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?: ModalOptions | 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}\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 = (options: OpenOptions): ModalId => {\n const {\n id = _instances.size + 1,\n type = 'modal',\n scope = 'modal',\n ...props\n } = options\n\n const modal: ModalConfig = {\n id,\n props: {\n ...props,\n children: props.body || props.children,\n },\n type,\n scope,\n }\n\n _instances.add(modal)\n setActiveModal(modal, scope)\n\n return id\n }\n\n const drawer = (options: ModalOptions): ModalId => {\n return open({\n ...options,\n type: 'drawer',\n })\n }\n\n const alert = (options: ModalOptions): 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: ModalOptions): ModalId => {\n return open({\n ...options,\n scope: 'alert',\n type: 'confirm',\n })\n }\n\n const menu = (options: ModalOptions): ModalId => {\n return open({\n ...options,\n type: 'menu',\n })\n }\n\n const close = async (id?: ModalId | null, force?: boolean) => {\n const modals = [..._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 close,\n closeAll,\n }\n\n const content = Object.entries(activeModals).map(([scope, config]) => {\n const Component = getModalComponent(config.type)\n\n const { title, children, ...props } = config.props || {}\n\n return (\n <Component\n key={scope}\n title={title}\n children={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","ModalsContext","createContext","initialModalState","id","type","defaultModals","alert","confirm","drawer","modal","menu","useModalsContext","useContext","modals","_instances","Set","useState","activeModals","setActiveModals","getModalComponent","_modals","setActiveModal","scope","prevState","open","options","size","body","add","close","force","filter","_modal$props","shouldClose","scoped","length","display","label","closeAll","forEach","_modal$props2","clear","content","Object","entries","map","config","Component","key","Provider"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import*as e from"react";import{AlertDialog as n,AlertDialogOverlay as l,AlertDialogContent as t,AlertDialogHeader as r,AlertDialogBody as o,AlertDialogFooter as c,Drawer as a,DrawerOverlay as s,DrawerContent as i,DrawerHeader as u,DrawerCloseButton as p,DrawerBody as m,DrawerFooter as d,Modal as f,ModalOverlay as C,ModalContent as h,ModalHeader as E,ModalCloseButton as O,ModalBody as y,ModalFooter as v}from"@chakra-ui/react";import{ButtonGroup as b,Button as P}from"@saas-ui/button";function w(){return w=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},w.apply(this,arguments)}function k(e,n){if(null==e)return{};var l,t,r={},o=Object.keys(e);for(t=0;t<o.length;t++)n.indexOf(l=o[t])>=0||(r[l]=e[l]);return r}const D=["title","cancelLabel","confirmLabel","cancelProps","confirmProps","buttonGroupProps","isOpen","closeOnCancel","closeOnConfirm","leastDestructiveFocus","onClose","onCancel","onConfirm","children"],g=a=>{const{title:s,cancelLabel:i="Cancel",confirmLabel:u="Confirm",cancelProps:p,confirmProps:m,buttonGroupProps:d,isOpen:f,closeOnCancel:C=!0,closeOnConfirm:h=!0,leastDestructiveFocus:E="cancel",onClose:O,onCancel:y,onConfirm:v,children:g}=a,j=k(a,D),x=e.useRef(null),B=e.useRef(null);/*#__PURE__*/return e.createElement(n,w({isOpen:f,onClose:O},j,{leastDestructiveRef:"cancel"===E?x:B}),/*#__PURE__*/e.createElement(l,null,/*#__PURE__*/e.createElement(t,null,/*#__PURE__*/e.createElement(r,null,s),/*#__PURE__*/e.createElement(o,null,g),/*#__PURE__*/e.createElement(c,null,/*#__PURE__*/e.createElement(b,d,/*#__PURE__*/e.createElement(P,w({ref:x},p,{onClick:()=>{null==y||y(),C&&O()}}),"Cancel"),/*#__PURE__*/e.createElement(P,w({ref:B},m,{onClick:()=>{null==v||v(),h&&O()}}),"Confirm"))))))},j=["title","children","isOpen","onClose","hideCloseButton","hideOverlay"],x=["footer","children"],B=n=>{const{title:l,children:t,isOpen:r,onClose:o,hideCloseButton:c,hideOverlay:m}=n,d=k(n,j);/*#__PURE__*/return e.createElement(a,w({isOpen:r,onClose:o},d),!m&&/*#__PURE__*/e.createElement(s,null),/*#__PURE__*/e.createElement(i,null,/*#__PURE__*/e.createElement(u,null,l),!c&&/*#__PURE__*/e.createElement(p,null),t))},L=n=>{const{footer:l,children:t}=n,r=k(n,x);/*#__PURE__*/return e.createElement(B,r,/*#__PURE__*/e.createElement(m,null,t),l&&/*#__PURE__*/e.createElement(d,null,l))},F=["title","children","isOpen","onClose","hideCloseButton","hideOverlay"],M=["children","footer"],R=n=>{const{title:l,children:t,isOpen:r,onClose:o,hideCloseButton:c,hideOverlay:a}=n,s=k(n,F);/*#__PURE__*/return e.createElement(f,w({isOpen:r,onClose:o},s),!a&&/*#__PURE__*/e.createElement(C,null),/*#__PURE__*/e.createElement(h,null,/*#__PURE__*/e.createElement(E,null,l),!c&&/*#__PURE__*/e.createElement(O,null),t))},z=n=>{const{children:l,footer:t}=n,r=k(n,M);/*#__PURE__*/return e.createElement(R,r,/*#__PURE__*/e.createElement(y,null,l),t&&/*#__PURE__*/e.createElement(v,null,t))},G=["id","type","scope"],S=["title","children"],A=e.createContext({}),K={id:null,props:null,type:"modal"},q={alert:g,confirm:g,drawer:L,modal:z};function H({children:n,modals:l}){const t=e.useMemo(()=>new Set,[]),[r,o]=e.useState({modal:K}),c=e.useMemo(()=>{const e=w({},q,l);return(n="modal")=>e[n]||e.modal},[l]),a=(e,n)=>{if(!n)return o({modal:e});o(l=>w({},l,{[n]:e}))},s=e=>{const{id:n=t.size+1,type:l="modal",scope:r="modal"}=e,o=k(e,G),c={id:n,props:w({},o,{children:o.body||o.children}),type:l,scope:r};return t.add(c),a(c,r),n},i=async(e,n)=>{var l;const r=[...t],o=r.filter(n=>n.id===e)[0];if(!o)return;if(!1===await(null==(l=o.props)||null==l.onClose?void 0:l.onClose({force:n})))return;t.delete(o);const c=r.filter(({scope:e})=>e===o.scope);a(c[c.length-2]||{id:null,props:null,type:o.type},o.scope)},u={open:s,drawer:e=>s(w({},e,{type:"drawer"})),alert:e=>s(w({},e,{scope:"alert",type:"alert",cancelProps:{display:"none"},confirmProps:{label:"OK"},leastDestructiveFocus:"confirm"})),confirm:e=>s(w({},e,{scope:"alert",type:"confirm"})),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(K)}},p=Object.entries(r).map(([n,l])=>{const r=c(l.type),o=l.props||{},{title:a,children:s}=o,u=k(o,S);/*#__PURE__*/return e.createElement(r,w({key:n,title:a,children:s},u,{isOpen:!(!l.id||!t.size),onClose:()=>i(l.id)}))});/*#__PURE__*/return e.createElement(A.Provider,{value:u},p,n)}const I=()=>e.useContext(A),J=()=>I();export{B as BaseDrawer,R as BaseModal,g as ConfirmDialog,L as Drawer,z as Modal,A as ModalsContext,H as ModalsProvider,J as useModals,I as useModalsContext};
1
+ import*as e from"react";import{AlertDialog as n,AlertDialogOverlay as l,AlertDialogContent as t,AlertDialogHeader as r,AlertDialogBody as o,AlertDialogFooter as c,Drawer as s,DrawerOverlay as a,DrawerContent as i,DrawerHeader as u,DrawerCloseButton as m,DrawerBody as p,DrawerFooter as d,Modal as f,ModalOverlay as C,ModalContent as h,ModalHeader as E,ModalCloseButton as O,ModalFooter as v,ModalBody as y,forwardRef as b,useMenuList as P,useStyles as w,chakra as g,useMultiStyleConfig as x,useTheme as F,useMenu as k,MenuDescendantsProvider as B,MenuProvider as D,StylesProvider as M}from"@chakra-ui/react";import{ButtonGroup as R,Button as j}from"@saas-ui/button";function L(){return L=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},L.apply(this,arguments)}function S(e,n){if(null==e)return{};var l,t,r={},o=Object.keys(e);for(t=0;t<o.length;t++)n.indexOf(l=o[t])>=0||(r[l]=e[l]);return r}const z=["title","cancelLabel","confirmLabel","cancelProps","confirmProps","buttonGroupProps","isOpen","closeOnCancel","closeOnConfirm","leastDestructiveFocus","onClose","onCancel","onConfirm","children"],A=s=>{const{title:a,cancelLabel:i="Cancel",confirmLabel:u="Confirm",cancelProps:m,confirmProps:p,buttonGroupProps:d,isOpen:f,closeOnCancel:C=!0,closeOnConfirm:h=!0,leastDestructiveFocus:E="cancel",onClose:O,onCancel:v,onConfirm:y,children:b}=s,P=S(s,z),w=e.useRef(null),g=e.useRef(null);/*#__PURE__*/return e.createElement(n,L({isOpen:f,onClose:O},P,{leastDestructiveRef:"cancel"===E?w:g}),/*#__PURE__*/e.createElement(l,null,/*#__PURE__*/e.createElement(t,null,/*#__PURE__*/e.createElement(r,null,a),/*#__PURE__*/e.createElement(o,null,b),/*#__PURE__*/e.createElement(c,null,/*#__PURE__*/e.createElement(R,d,/*#__PURE__*/e.createElement(j,L({ref:w},m,{onClick:()=>{null==v||v(),C&&O()}}),"Cancel"),/*#__PURE__*/e.createElement(j,L({ref:g},p,{onClick:()=>{null==y||y(),h&&O()}}),"Confirm"))))))},G=["title","children","isOpen","onClose","hideCloseButton","hideOverlay"],I=["footer","children"],_=n=>{const{title:l,children:t,isOpen:r,onClose:o,hideCloseButton:c,hideOverlay:p}=n,d=S(n,G);/*#__PURE__*/return e.createElement(s,L({isOpen:r,onClose:o},d),!p&&/*#__PURE__*/e.createElement(a,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,r=S(n,I);/*#__PURE__*/return e.createElement(_,r,/*#__PURE__*/e.createElement(p,null,t),l&&/*#__PURE__*/e.createElement(d,null,l))},K=["title","footer","children","isOpen","onClose","hideCloseButton","hideOverlay"],Y=["children","footer"],q=n=>{const{title:l,footer:t,children:r,isOpen:o,onClose:c,hideCloseButton:s,hideOverlay:a}=n,i=S(n,K);/*#__PURE__*/return e.createElement(f,L({isOpen:o,onClose:c},i),!a&&/*#__PURE__*/e.createElement(C,null),/*#__PURE__*/e.createElement(h,null,l&&/*#__PURE__*/e.createElement(E,null,l),!s&&/*#__PURE__*/e.createElement(O,null),r,t&&/*#__PURE__*/e.createElement(v,null,t)))},J=n=>{const{children:l}=n,t=S(n,Y);/*#__PURE__*/return e.createElement(q,t,/*#__PURE__*/e.createElement(y,null,l))},N=["children","footer","isOpen","onClose"],Q=["descendants"],T=["rootProps"],U=n=>{const{children:l,footer:t,isOpen:r,onClose:o}=n,c=S(n,N),s=x("Menu",n),{direction:a}=F(),i=k({onClose:o,autoSelect:!0,defaultIsOpen:!0,closeOnBlur:!1,direction:a}),{descendants:u}=i,m=S(i,Q),p=e.useMemo(()=>m,[m]);return e.useEffect(()=>{m.openAndFocusFirstItem()},[n.isOpen]),/*#__PURE__*/e.createElement(q,L({isOpen:r,onClose:o,initialFocusRef:m.menuRef},c),/*#__PURE__*/e.createElement(B,{value:u},/*#__PURE__*/e.createElement(D,{value:p},/*#__PURE__*/e.createElement(M,{value:s},l))),t&&/*#__PURE__*/e.createElement(v,null,t))};U.defaultProps={variant:"dialog"};const V=b((n,l)=>{const t=S(n,T),r=P(t,l),o=w();/*#__PURE__*/return e.createElement(g.div,L({},r,{__css:L({outline:0,maxHeight:"80vh",overflowY:"auto"},o.list,{boxShadow:"none",border:0})}))}),W=["id","type","scope"],X=["title","children"],Z=e.createContext({}),$={id:null,props:null,type:"modal"},ee={alert:A,confirm:A,drawer:H,modal:J,menu:U};function ne({children:n,modals:l}){const t=e.useMemo(()=>new Set,[]),[r,o]=e.useState({modal:$}),c=e.useMemo(()=>{const e=L({},ee,l);return(n="modal")=>e[n]||e.modal},[l]),s=(e,n)=>{if(!n)return o({modal:e});o(l=>L({},l,{[n]:e}))},a=e=>{const{id:n=t.size+1,type:l="modal",scope:r="modal"}=e,o=S(e,W),c={id:n,props:L({},o,{children:o.body||o.children}),type:l,scope:r};return t.add(c),s(c,r),n},i=async(e,n)=>{var l;const r=[...t],o=r.filter(n=>n.id===e)[0];if(!o)return;if(!1===await(null==(l=o.props)||null==l.onClose?void 0:l.onClose({force:n})))return;t.delete(o);const c=r.filter(({scope:e})=>e===o.scope);s(c[c.length-2]||{id:null,props:null,type:o.type},o.scope)},u={open:a,drawer:e=>a(L({},e,{type:"drawer"})),alert:e=>a(L({},e,{scope:"alert",type:"alert",cancelProps:{display:"none"},confirmProps:{label:"OK"},leastDestructiveFocus:"confirm"})),confirm:e=>a(L({},e,{scope:"alert",type:"confirm"})),menu:e=>a(L({},e,{type:"menu"})),close:i,closeAll:()=>{t.forEach(e=>{var n;return null==(n=e.props)||null==n.onClose?void 0:n.onClose({force:!0})}),t.clear(),s($)}},m=Object.entries(r).map(([n,l])=>{const r=c(l.type),o=l.props||{},{title:s,children:a}=o,u=S(o,X);/*#__PURE__*/return e.createElement(r,L({key:n,title:s,children:a},u,{isOpen:!(!l.id||!t.size),onClose:()=>i(l.id)}))});/*#__PURE__*/return e.createElement(Z.Provider,{value:u},m,n)}const le=()=>e.useContext(Z),te=()=>le();export{_ as BaseDrawer,q as BaseModal,A as ConfirmDialog,H as Drawer,U as MenuDialog,V as MenuDialogList,J as Modal,Z as ModalsContext,ne as ModalsProvider,te as useModals,le 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/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 * 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 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 <ModalHeader>{title}</ModalHeader>\n {!hideCloseButton && <ModalCloseButton />}\n {children}\n </ModalContent>\n </ChakraModal>\n )\n}\n\nexport interface ModalProps extends BaseModalProps {\n /**\n * The modal footer, wrapped with `ModalFooter`\n */\n footer?: React.ReactNode\n}\n\nexport const Modal: React.FC<ModalProps> = (props) => {\n const { children, footer, ...rest } = props\n return (\n <BaseModal {...rest}>\n <ModalBody>{children}</ModalBody>\n\n {footer && <ModalFooter>{footer}</ModalFooter>}\n </BaseModal>\n )\n}\n","import * as React from 'react'\n\nimport { Modal, ModalProps } from './modal'\nimport { Drawer, DrawerProps } from './drawer'\nimport { ConfirmDialog, ConfirmDialogProps } from './dialog'\n\nexport interface ModalsContextValue {\n open?: (options: OpenOptions) => ModalId\n drawer?: (options: ModalOptions) => ModalId\n alert?: (options: ModalOptions) => ModalId\n confirm?: (options: ModalOptions) => 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<\n (ModalProps & DrawerProps & ConfirmDialogProps) & {\n body?: React.ReactNode\n },\n 'onClose' | 'isOpen' | 'children'\n > {\n onClose?: (args: { force?: boolean }) => Promise<boolean | undefined> | void\n children?: React.ReactNode\n}\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'\n\nexport interface ModalConfig {\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?: ModalOptions | 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}\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 = (options: OpenOptions): ModalId => {\n const {\n id = _instances.size + 1,\n type = 'modal',\n scope = 'modal',\n ...props\n } = options\n\n const modal: ModalConfig = {\n id,\n props: {\n ...props,\n children: props.body || props.children,\n },\n type,\n scope,\n }\n\n _instances.add(modal)\n setActiveModal(modal, scope)\n\n return id\n }\n\n const drawer = (options: ModalOptions): ModalId => {\n return open({\n ...options,\n type: 'drawer',\n })\n }\n\n const alert = (options: ModalOptions): 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: ModalOptions): ModalId => {\n return open({\n ...options,\n scope: 'alert',\n type: 'confirm',\n })\n }\n\n const close = async (id?: ModalId | null, force?: boolean) => {\n const modals = [..._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 close,\n closeAll,\n }\n\n const content = Object.entries(activeModals).map(([scope, config]) => {\n const Component = getModalComponent(config.type)\n\n const { title, children, ...props } = config.props || {}\n\n return (\n <Component\n key={scope}\n title={title}\n children={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","Modal","ModalBody","ModalFooter","ModalsContext","createContext","initialModalState","id","type","defaultModals","alert","confirm","drawer","modal","ModalsProvider","modals","_instances","useMemo","Set","activeModals","setActiveModals","useState","getModalComponent","_modals","setActiveModal","scope","prevState","open","options","size","body","add","close","async","force","filter","_modal$props","delete","scoped","length","context","display","label","closeAll","forEach","_modal$props2","clear","content","Object","entries","map","config","Component","key","Provider","value","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/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 { Modal, BaseModalProps } from './modal'\nimport { Drawer, DrawerProps } from './drawer'\nimport { ConfirmDialog, ConfirmDialogProps } from './dialog'\nimport { MenuDialog, MenuDialogProps } from './menu'\n\nexport interface ModalsContextValue {\n open?: (options: OpenOptions) => ModalId\n drawer?: (options: ModalOptions) => ModalId\n alert?: (options: ModalOptions) => ModalId\n confirm?: (options: ModalOptions) => ModalId\n menu?: (options: ModalOptions) => 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<\n (BaseModalProps & DrawerProps & ConfirmDialogProps) & {\n body?: React.ReactNode\n },\n 'onClose' | 'isOpen' | 'children'\n > {\n onClose?: (args: { force?: boolean }) => Promise<boolean | undefined> | void\n children?: React.ReactNode\n}\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 /**\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?: ModalOptions | 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}\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 = (options: OpenOptions): ModalId => {\n const {\n id = _instances.size + 1,\n type = 'modal',\n scope = 'modal',\n ...props\n } = options\n\n const modal: ModalConfig = {\n id,\n props: {\n ...props,\n children: props.body || props.children,\n },\n type,\n scope,\n }\n\n _instances.add(modal)\n setActiveModal(modal, scope)\n\n return id\n }\n\n const drawer = (options: ModalOptions): ModalId => {\n return open({\n ...options,\n type: 'drawer',\n })\n }\n\n const alert = (options: ModalOptions): 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: ModalOptions): ModalId => {\n return open({\n ...options,\n scope: 'alert',\n type: 'confirm',\n })\n }\n\n const menu = (options: ModalOptions): ModalId => {\n return open({\n ...options,\n type: 'menu',\n })\n }\n\n const close = async (id?: ModalId | null, force?: boolean) => {\n const modals = [..._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 close,\n closeAll,\n }\n\n const content = Object.entries(activeModals).map(([scope, config]) => {\n const Component = getModalComponent(config.type)\n\n const { title, children, ...props } = config.props || {}\n\n return (\n <Component\n key={scope}\n title={title}\n children={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","ModalsContext","createContext","initialModalState","id","type","defaultModals","alert","confirm","drawer","modal","menu","ModalsProvider","modals","_instances","Set","activeModals","setActiveModals","useState","getModalComponent","_modals","setActiveModal","scope","prevState","open","options","size","body","add","close","async","force","filter","_modal$props","delete","scoped","length","display","label","closeAll","forEach","_modal$props2","clear","content","Object","entries","map","config","Component","key","Provider","useModalsContext","useContext","useModals"],"mappings":"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"}
package/dist/menu.d.ts ADDED
@@ -0,0 +1,12 @@
1
+ import * as React from 'react';
2
+ import { MenuListProps } from '@chakra-ui/react';
3
+ import { BaseModalProps } from './modal';
4
+ export interface MenuDialogProps extends BaseModalProps {
5
+ /**
6
+ * The modal footer, wrapped with `ModalFooter`
7
+ */
8
+ footer?: React.ReactNode;
9
+ }
10
+ export declare const MenuDialog: React.FC<MenuDialogProps>;
11
+ export declare const MenuDialogList: import("@chakra-ui/react").ComponentWithAs<"div", MenuListProps>;
12
+ //# sourceMappingURL=menu.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"menu.d.ts","sourceRoot":"","sources":["../src/menu.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,EAIL,aAAa,EASd,MAAM,kBAAkB,CAAA;AAEzB,OAAO,EAAa,cAAc,EAAE,MAAM,SAAS,CAAA;AAEnD,MAAM,WAAW,eAAgB,SAAQ,cAAc;IACrD;;OAEG;IACH,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CACzB;AAED,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CAkChD,CAAA;AAMD,eAAO,MAAM,cAAc,kEAoBzB,CAAA"}
package/dist/modal.d.ts CHANGED
@@ -4,7 +4,11 @@ export interface BaseModalProps extends ChakraModalProps {
4
4
  /**
5
5
  * The modal title
6
6
  */
7
- title: React.ReactNode;
7
+ title?: React.ReactNode;
8
+ /**
9
+ * The modal footer
10
+ */
11
+ footer?: React.ReactNode;
8
12
  /**
9
13
  * Hide the close button
10
14
  */
@@ -15,11 +19,5 @@ export interface BaseModalProps extends ChakraModalProps {
15
19
  hideOverlay?: boolean;
16
20
  }
17
21
  export declare const BaseModal: React.FC<BaseModalProps>;
18
- export interface ModalProps extends BaseModalProps {
19
- /**
20
- * The modal footer, wrapped with `ModalFooter`
21
- */
22
- footer?: React.ReactNode;
23
- }
24
- export declare const Modal: React.FC<ModalProps>;
22
+ export declare const Modal: React.FC<BaseModalProps>;
25
23
  //# sourceMappingURL=modal.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"modal.d.ts","sourceRoot":"","sources":["../src/modal.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,EAQL,UAAU,IAAI,gBAAgB,EAC/B,MAAM,kBAAkB,CAAA;AAEzB,MAAM,WAAW,cAAe,SAAQ,gBAAgB;IACtD;;OAEG;IACH,KAAK,EAAE,KAAK,CAAC,SAAS,CAAA;IACtB;;OAEG;IACH,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB;;OAEG;IACH,WAAW,CAAC,EAAE,OAAO,CAAA;CACtB;AAED,eAAO,MAAM,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC,cAAc,CAoB9C,CAAA;AAED,MAAM,WAAW,UAAW,SAAQ,cAAc;IAChD;;OAEG;IACH,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CACzB;AAED,eAAO,MAAM,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC,UAAU,CAStC,CAAA"}
1
+ {"version":3,"file":"modal.d.ts","sourceRoot":"","sources":["../src/modal.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,EAQL,UAAU,IAAI,gBAAgB,EAC/B,MAAM,kBAAkB,CAAA;AAEzB,MAAM,WAAW,cAAe,SAAQ,gBAAgB;IACtD;;OAEG;IACH,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IACvB;;OAEG;IACH,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IACxB;;OAEG;IACH,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB;;OAEG;IACH,WAAW,CAAC,EAAE,OAAO,CAAA;CACtB;AAED,eAAO,MAAM,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC,cAAc,CAsB9C,CAAA;AAED,eAAO,MAAM,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC,cAAc,CAO1C,CAAA"}
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import { ModalProps } from './modal';
2
+ import { BaseModalProps } from './modal';
3
3
  import { DrawerProps } from './drawer';
4
4
  import { ConfirmDialogProps } from './dialog';
5
5
  export interface ModalsContextValue {
@@ -7,6 +7,7 @@ export interface ModalsContextValue {
7
7
  drawer?: (options: ModalOptions) => ModalId;
8
8
  alert?: (options: ModalOptions) => ModalId;
9
9
  confirm?: (options: ModalOptions) => ModalId;
10
+ menu?: (options: ModalOptions) => ModalId;
10
11
  close?: (id: ModalId) => void;
11
12
  closeAll?: () => void;
12
13
  }
@@ -16,7 +17,7 @@ interface ModalsProviderProps {
16
17
  modals?: Record<string, React.FC<any>>;
17
18
  }
18
19
  export declare type ModalId = string | number;
19
- interface ModalOptions extends Omit<(ModalProps & DrawerProps & ConfirmDialogProps) & {
20
+ interface ModalOptions extends Omit<(BaseModalProps & DrawerProps & ConfirmDialogProps) & {
20
21
  body?: React.ReactNode;
21
22
  }, 'onClose' | 'isOpen' | 'children'> {
22
23
  onClose?: (args: {
@@ -29,7 +30,7 @@ export interface OpenOptions extends ModalOptions {
29
30
  scope?: ModalScopes;
30
31
  }
31
32
  export declare type ModalScopes = 'modal' | 'alert';
32
- export declare type ModalTypes = 'modal' | 'drawer' | 'alert' | 'confirm';
33
+ export declare type ModalTypes = 'modal' | 'drawer' | 'alert' | 'confirm' | 'menu';
33
34
  export interface ModalConfig {
34
35
  /**
35
36
  * The modal id, autogenerated when not set.
@@ -1 +1 @@
1
- {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,EAAS,UAAU,EAAE,MAAM,SAAS,CAAA;AAC3C,OAAO,EAAU,WAAW,EAAE,MAAM,UAAU,CAAA;AAC9C,OAAO,EAAiB,kBAAkB,EAAE,MAAM,UAAU,CAAA;AAE5D,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,OAAO,CAAA;IACxC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,OAAO,CAAA;IAC3C,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,OAAO,CAAA;IAC1C,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,OAAO,CAAA;IAC5C,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,OAAO,KAAK,IAAI,CAAA;IAC7B,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;CACtB;AAED,eAAO,MAAM,aAAa,mCAA8C,CAAA;AAExE,UAAU,mBAAmB;IAC3B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAA;CACvC;AAED,oBAAY,OAAO,GAAG,MAAM,GAAG,MAAM,CAAA;AAErC,UAAU,YACR,SAAQ,IAAI,CACV,CAAC,UAAU,GAAG,WAAW,GAAG,kBAAkB,CAAC,GAAG;IAChD,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CACvB,EACD,SAAS,GAAG,QAAQ,GAAG,UAAU,CAClC;IACD,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC,GAAG,IAAI,CAAA;IAC5E,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CAC3B;AAED,MAAM,WAAW,WAAY,SAAQ,YAAY;IAC/C,IAAI,CAAC,EAAE,UAAU,GAAG,MAAM,CAAA;IAC1B,KAAK,CAAC,EAAE,WAAW,CAAA;CACpB;AAED,oBAAY,WAAW,GAAG,OAAO,GAAG,OAAO,CAAA;AAE3C,oBAAY,UAAU,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAA;AAEjE,MAAM,WAAW,WAAW;IAC1B;;;OAGG;IACH,EAAE,CAAC,EAAE,OAAO,GAAG,IAAI,CAAA;IACnB;;OAEG;IACH,KAAK,CAAC,EAAE,YAAY,GAAG,IAAI,CAAA;IAC3B;;;;OAIG;IACH,KAAK,CAAC,EAAE,WAAW,GAAG,MAAM,CAAA;IAC5B;;;;;OAKG;IACH,IAAI,CAAC,EAAE,UAAU,GAAG,MAAM,CAAA;CAC3B;AAeD,wBAAgB,cAAc,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,mBAAmB,eA4JvE;AAED,eAAO,MAAM,gBAAgB,QAAO,kBACH,CAAA;AAEjC,eAAO,MAAM,SAAS,0BAErB,CAAA"}
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,EAAS,cAAc,EAAE,MAAM,SAAS,CAAA;AAC/C,OAAO,EAAU,WAAW,EAAE,MAAM,UAAU,CAAA;AAC9C,OAAO,EAAiB,kBAAkB,EAAE,MAAM,UAAU,CAAA;AAG5D,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,OAAO,CAAA;IACxC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,OAAO,CAAA;IAC3C,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,OAAO,CAAA;IAC1C,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,OAAO,CAAA;IAC5C,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,OAAO,CAAA;IACzC,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,OAAO,KAAK,IAAI,CAAA;IAC7B,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;CACtB;AAED,eAAO,MAAM,aAAa,mCAA8C,CAAA;AAExE,UAAU,mBAAmB;IAC3B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAA;CACvC;AAED,oBAAY,OAAO,GAAG,MAAM,GAAG,MAAM,CAAA;AAErC,UAAU,YACR,SAAQ,IAAI,CACV,CAAC,cAAc,GAAG,WAAW,GAAG,kBAAkB,CAAC,GAAG;IACpD,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CACvB,EACD,SAAS,GAAG,QAAQ,GAAG,UAAU,CAClC;IACD,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC,GAAG,IAAI,CAAA;IAC5E,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CAC3B;AAED,MAAM,WAAW,WAAY,SAAQ,YAAY;IAC/C,IAAI,CAAC,EAAE,UAAU,GAAG,MAAM,CAAA;IAC1B,KAAK,CAAC,EAAE,WAAW,CAAA;CACpB;AAED,oBAAY,WAAW,GAAG,OAAO,GAAG,OAAO,CAAA;AAE3C,oBAAY,UAAU,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAA;AAE1E,MAAM,WAAW,WAAW;IAC1B;;;OAGG;IACH,EAAE,CAAC,EAAE,OAAO,GAAG,IAAI,CAAA;IACnB;;OAEG;IACH,KAAK,CAAC,EAAE,YAAY,GAAG,IAAI,CAAA;IAC3B;;;;OAIG;IACH,KAAK,CAAC,EAAE,WAAW,GAAG,MAAM,CAAA;IAC5B;;;;;OAKG;IACH,IAAI,CAAC,EAAE,UAAU,GAAG,MAAM,CAAA;CAC3B;AAgBD,wBAAgB,cAAc,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,mBAAmB,eAoKvE;AAED,eAAO,MAAM,gBAAgB,QAAO,kBACH,CAAA;AAEjC,eAAO,MAAM,SAAS,0BAErB,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@saas-ui/modals",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "description": "A modal manager for Chakra UI",
5
5
  "source": "src/index.ts",
6
6
  "exports": {
package/src/index.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from './dialog'
2
2
  export * from './drawer'
3
3
  export * from './modal'
4
+ export * from './menu'
4
5
  export * from './provider'
package/src/menu.tsx ADDED
@@ -0,0 +1,87 @@
1
+ import * as React from 'react'
2
+
3
+ import {
4
+ ModalFooter,
5
+ MenuDescendantsProvider,
6
+ MenuProvider,
7
+ MenuListProps,
8
+ useMenu,
9
+ useMenuList,
10
+ chakra,
11
+ StylesProvider,
12
+ useMultiStyleConfig,
13
+ useTheme,
14
+ useStyles,
15
+ forwardRef,
16
+ } from '@chakra-ui/react'
17
+
18
+ import { BaseModal, BaseModalProps } from './modal'
19
+
20
+ export interface MenuDialogProps extends BaseModalProps {
21
+ /**
22
+ * The modal footer, wrapped with `ModalFooter`
23
+ */
24
+ footer?: React.ReactNode
25
+ }
26
+
27
+ export const MenuDialog: React.FC<MenuDialogProps> = (props) => {
28
+ const { children, footer, isOpen, onClose, ...rest } = props
29
+
30
+ const styles = useMultiStyleConfig('Menu', props)
31
+ const { direction } = useTheme()
32
+ const { descendants, ...ctx } = useMenu({
33
+ onClose,
34
+ autoSelect: true,
35
+ defaultIsOpen: true,
36
+ closeOnBlur: false,
37
+ direction,
38
+ })
39
+ const context = React.useMemo(() => ctx, [ctx])
40
+
41
+ React.useEffect(() => {
42
+ ctx.openAndFocusFirstItem()
43
+ }, [props.isOpen])
44
+
45
+ return (
46
+ <BaseModal
47
+ isOpen={isOpen}
48
+ onClose={onClose}
49
+ initialFocusRef={ctx.menuRef}
50
+ {...rest}
51
+ >
52
+ <MenuDescendantsProvider value={descendants}>
53
+ <MenuProvider value={context}>
54
+ <StylesProvider value={styles}>{children}</StylesProvider>
55
+ </MenuProvider>
56
+ </MenuDescendantsProvider>
57
+
58
+ {footer && <ModalFooter>{footer}</ModalFooter>}
59
+ </BaseModal>
60
+ )
61
+ }
62
+
63
+ MenuDialog.defaultProps = {
64
+ variant: 'dialog',
65
+ }
66
+
67
+ export const MenuDialogList = forwardRef<MenuListProps, 'div'>((props, ref) => {
68
+ const { rootProps, ...rest } = props
69
+
70
+ const ownProps = useMenuList(rest, ref) as any
71
+
72
+ const styles = useStyles()
73
+
74
+ return (
75
+ <chakra.div
76
+ {...ownProps}
77
+ __css={{
78
+ outline: 0,
79
+ maxHeight: '80vh', // can override this in theme
80
+ overflowY: 'auto', // can override this in theme
81
+ ...styles.list,
82
+ boxShadow: 'none',
83
+ border: 0,
84
+ }}
85
+ />
86
+ )
87
+ })
package/src/modal.tsx CHANGED
@@ -15,7 +15,11 @@ export interface BaseModalProps extends ChakraModalProps {
15
15
  /**
16
16
  * The modal title
17
17
  */
18
- title: React.ReactNode
18
+ title?: React.ReactNode
19
+ /**
20
+ * The modal footer
21
+ */
22
+ footer?: React.ReactNode
19
23
  /**
20
24
  * Hide the close button
21
25
  */
@@ -29,6 +33,7 @@ export interface BaseModalProps extends ChakraModalProps {
29
33
  export const BaseModal: React.FC<BaseModalProps> = (props) => {
30
34
  const {
31
35
  title,
36
+ footer,
32
37
  children,
33
38
  isOpen,
34
39
  onClose,
@@ -40,28 +45,20 @@ export const BaseModal: React.FC<BaseModalProps> = (props) => {
40
45
  <ChakraModal isOpen={isOpen} onClose={onClose} {...rest}>
41
46
  {!hideOverlay && <ModalOverlay />}
42
47
  <ModalContent>
43
- <ModalHeader>{title}</ModalHeader>
48
+ {title && <ModalHeader>{title}</ModalHeader>}
44
49
  {!hideCloseButton && <ModalCloseButton />}
45
50
  {children}
51
+ {footer && <ModalFooter>{footer}</ModalFooter>}
46
52
  </ModalContent>
47
53
  </ChakraModal>
48
54
  )
49
55
  }
50
56
 
51
- export interface ModalProps extends BaseModalProps {
52
- /**
53
- * The modal footer, wrapped with `ModalFooter`
54
- */
55
- footer?: React.ReactNode
56
- }
57
-
58
- export const Modal: React.FC<ModalProps> = (props) => {
57
+ export const Modal: React.FC<BaseModalProps> = (props) => {
59
58
  const { children, footer, ...rest } = props
60
59
  return (
61
60
  <BaseModal {...rest}>
62
61
  <ModalBody>{children}</ModalBody>
63
-
64
- {footer && <ModalFooter>{footer}</ModalFooter>}
65
62
  </BaseModal>
66
63
  )
67
64
  }
package/src/provider.tsx CHANGED
@@ -1,14 +1,16 @@
1
1
  import * as React from 'react'
2
2
 
3
- import { Modal, ModalProps } from './modal'
3
+ import { Modal, BaseModalProps } from './modal'
4
4
  import { Drawer, DrawerProps } from './drawer'
5
5
  import { ConfirmDialog, ConfirmDialogProps } from './dialog'
6
+ import { MenuDialog, MenuDialogProps } from './menu'
6
7
 
7
8
  export interface ModalsContextValue {
8
9
  open?: (options: OpenOptions) => ModalId
9
10
  drawer?: (options: ModalOptions) => ModalId
10
11
  alert?: (options: ModalOptions) => ModalId
11
12
  confirm?: (options: ModalOptions) => ModalId
13
+ menu?: (options: ModalOptions) => ModalId
12
14
  close?: (id: ModalId) => void
13
15
  closeAll?: () => void
14
16
  }
@@ -24,7 +26,7 @@ export type ModalId = string | number
24
26
 
25
27
  interface ModalOptions
26
28
  extends Omit<
27
- (ModalProps & DrawerProps & ConfirmDialogProps) & {
29
+ (BaseModalProps & DrawerProps & ConfirmDialogProps) & {
28
30
  body?: React.ReactNode
29
31
  },
30
32
  'onClose' | 'isOpen' | 'children'
@@ -40,7 +42,7 @@ export interface OpenOptions extends ModalOptions {
40
42
 
41
43
  export type ModalScopes = 'modal' | 'alert'
42
44
 
43
- export type ModalTypes = 'modal' | 'drawer' | 'alert' | 'confirm'
45
+ export type ModalTypes = 'modal' | 'drawer' | 'alert' | 'confirm' | 'menu'
44
46
 
45
47
  export interface ModalConfig {
46
48
  /**
@@ -78,6 +80,7 @@ const defaultModals = {
78
80
  confirm: ConfirmDialog,
79
81
  drawer: Drawer,
80
82
  modal: Modal,
83
+ menu: MenuDialog,
81
84
  }
82
85
 
83
86
  export function ModalsProvider({ children, modals }: ModalsProviderProps) {
@@ -170,6 +173,13 @@ export function ModalsProvider({ children, modals }: ModalsProviderProps) {
170
173
  })
171
174
  }
172
175
 
176
+ const menu = (options: ModalOptions): ModalId => {
177
+ return open({
178
+ ...options,
179
+ type: 'menu',
180
+ })
181
+ }
182
+
173
183
  const close = async (id?: ModalId | null, force?: boolean) => {
174
184
  const modals = [..._instances]
175
185
  const modal = modals.filter((modal) => modal.id === id)[0]
@@ -209,6 +219,7 @@ export function ModalsProvider({ children, modals }: ModalsProviderProps) {
209
219
  drawer,
210
220
  alert,
211
221
  confirm,
222
+ menu,
212
223
  close,
213
224
  closeAll,
214
225
  }
@@ -0,0 +1,139 @@
1
+ import * as React from 'react'
2
+ import {
3
+ Stack,
4
+ Container,
5
+ MenuItem,
6
+ MenuGroup,
7
+ useDisclosure,
8
+ } from '@chakra-ui/react'
9
+
10
+ import { MenuDialog, MenuDialogList } from '../src/menu'
11
+
12
+ import { FiArchive, FiTag, FiUsers, FiSettings } from 'react-icons/fi'
13
+
14
+ import { Button } from '@saas-ui/button'
15
+
16
+ export default {
17
+ title: 'Components/Overlay/MenuDialog',
18
+ decorators: [
19
+ (Story: any) => (
20
+ <Container mt="40px">
21
+ <Story />
22
+ </Container>
23
+ ),
24
+ ],
25
+ }
26
+
27
+ export const basic = () => {
28
+ const disclosure = useDisclosure()
29
+
30
+ return (
31
+ <Stack>
32
+ <Button
33
+ onClick={() => {
34
+ disclosure.onOpen()
35
+ }}
36
+ >
37
+ Open menu
38
+ </Button>
39
+
40
+ <MenuDialog title="Menu" {...disclosure}>
41
+ <MenuDialogList>
42
+ <MenuItem>Item 1</MenuItem>
43
+ <MenuItem>Item 2</MenuItem>
44
+ <MenuItem>Item 3</MenuItem>
45
+ </MenuDialogList>
46
+ </MenuDialog>
47
+ </Stack>
48
+ )
49
+ }
50
+
51
+ export const iconAndCommand = () => {
52
+ const disclosure = useDisclosure()
53
+
54
+ return (
55
+ <Stack>
56
+ <Button
57
+ onClick={() => {
58
+ disclosure.onOpen()
59
+ }}
60
+ >
61
+ Open menu
62
+ </Button>
63
+
64
+ <MenuDialog title="Commands" {...disclosure}>
65
+ <MenuDialogList>
66
+ <MenuItem icon={<FiUsers />} command="A">
67
+ Assign
68
+ </MenuItem>
69
+ <MenuItem icon={<FiTag />} command="L">
70
+ Add label
71
+ </MenuItem>
72
+ <MenuItem icon={<FiArchive />} command="C">
73
+ Close
74
+ </MenuItem>
75
+ </MenuDialogList>
76
+ </MenuDialog>
77
+ </Stack>
78
+ )
79
+ }
80
+
81
+ export const menuGroup = () => {
82
+ const disclosure = useDisclosure()
83
+
84
+ return (
85
+ <Stack>
86
+ <Button
87
+ onClick={() => {
88
+ disclosure.onOpen()
89
+ }}
90
+ >
91
+ Open menu
92
+ </Button>
93
+
94
+ <MenuDialog title="Commands" {...disclosure}>
95
+ <MenuDialogList>
96
+ <MenuGroup title="Message">
97
+ <MenuItem icon={<FiUsers />} command="A">
98
+ Assign
99
+ </MenuItem>
100
+ <MenuItem icon={<FiTag />} command="L">
101
+ Add label
102
+ </MenuItem>
103
+ <MenuItem icon={<FiArchive />} command="C">
104
+ Close
105
+ </MenuItem>
106
+ </MenuGroup>
107
+ <MenuGroup title="Settings">
108
+ <MenuItem icon={<FiSettings />}>Change theme</MenuItem>
109
+ </MenuGroup>
110
+ </MenuDialogList>
111
+ </MenuDialog>
112
+ </Stack>
113
+ )
114
+ }
115
+
116
+ export const overflow = () => {
117
+ const disclosure = useDisclosure()
118
+
119
+ const items = []
120
+ for (let i = 0; i < 50; i++) {
121
+ items.push(<MenuItem key={i}>Item {i}</MenuItem>)
122
+ }
123
+
124
+ return (
125
+ <Stack>
126
+ <Button
127
+ onClick={() => {
128
+ disclosure.onOpen()
129
+ }}
130
+ >
131
+ Open menu
132
+ </Button>
133
+
134
+ <MenuDialog title="Menu" {...disclosure}>
135
+ <MenuDialogList>{items}</MenuDialogList>
136
+ </MenuDialog>
137
+ </Stack>
138
+ )
139
+ }
@@ -1,7 +1,9 @@
1
1
  import * as React from 'react'
2
- import { Stack, Container } from '@chakra-ui/react'
2
+ import { Stack, Container, MenuItem } from '@chakra-ui/react'
3
3
  import { ModalsProvider, useModals } from '../src/provider'
4
4
 
5
+ import { MenuDialogList } from '../src/menu'
6
+
5
7
  import { Button } from '@saas-ui/button'
6
8
 
7
9
  const CustomModal: React.FC<{ title: string }> = ({ title, children }) => (
@@ -113,6 +115,21 @@ export const basic = () => {
113
115
  >
114
116
  Open drawer
115
117
  </Button>
118
+ <Button
119
+ onClick={() =>
120
+ modals.menu({
121
+ title: 'Menu',
122
+ body: (
123
+ <MenuDialogList>
124
+ <MenuItem>Item 1</MenuItem>
125
+ <MenuItem>Item 1</MenuItem>
126
+ </MenuDialogList>
127
+ ),
128
+ })
129
+ }
130
+ >
131
+ Open menu
132
+ </Button>
116
133
  </Stack>
117
134
  )
118
135
  }