brew-js-react 0.5.1 → 0.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dialog.d.ts +91 -10
- package/dialog.js +9 -11
- package/dist/brew-js-react.js +23 -13
- package/dist/brew-js-react.js.map +1 -1
- package/dist/brew-js-react.min.js +2 -2
- package/dist/brew-js-react.min.js.map +1 -1
- package/mixins/FlyoutMixin.d.ts +10 -0
- package/mixins/FlyoutMixin.js +9 -1
- package/mixins/FlyoutToggleMixin.js +1 -1
- package/package.json +3 -3
package/dialog.d.ts
CHANGED
|
@@ -1,35 +1,116 @@
|
|
|
1
1
|
export type DialogCloseCallback<T> = (value?: T) => Promise<void>;
|
|
2
2
|
|
|
3
3
|
export interface DialogState<T> {
|
|
4
|
+
/**
|
|
5
|
+
* Gets the root element of the dialog.
|
|
6
|
+
*/
|
|
4
7
|
readonly root: HTMLElement;
|
|
8
|
+
/**
|
|
9
|
+
* Opens the dialog.
|
|
10
|
+
*
|
|
11
|
+
* It will receive result from {@link DialogState.close} or {@link DialogRenderComponentProps.closeDialog} when the dialog is properly closed.
|
|
12
|
+
* Otherwise in cases such as being closed due to lost of focus, result value will always be `undefined`.
|
|
13
|
+
*/
|
|
5
14
|
open: () => Promise<T | undefined>;
|
|
6
|
-
|
|
15
|
+
/**
|
|
16
|
+
* Closes the dialog, with optional result value.
|
|
17
|
+
*
|
|
18
|
+
* This method is different from {@link DialogRenderComponentProps.closeDialog} that {@link DialogBaseProps.onCommit} will not be called.
|
|
19
|
+
*/
|
|
20
|
+
close: (value?: T) => Promise<void>;
|
|
7
21
|
}
|
|
8
22
|
|
|
9
|
-
export interface DialogBaseProps<T> {
|
|
23
|
+
export interface DialogBaseProps<T, V = T> {
|
|
24
|
+
/**
|
|
25
|
+
* Specifies dialog title.
|
|
26
|
+
* This property is intended to be handled by {@link DialogOptions.onRender} or {@link DialogOptions.wrapper}.
|
|
27
|
+
*/
|
|
10
28
|
title?: string;
|
|
29
|
+
/**
|
|
30
|
+
* CSS class names to be added to root element.
|
|
31
|
+
*/
|
|
11
32
|
className?: string;
|
|
33
|
+
/**
|
|
34
|
+
* Whether to show close button in the dialog.
|
|
35
|
+
* This property is intended to be handled by {@link DialogOptions.onRender} or {@link DialogOptions.wrapper}.
|
|
36
|
+
*/
|
|
12
37
|
showCloseButton?: boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Whether confirmation should be prompted when user leaves the page.
|
|
40
|
+
*/
|
|
13
41
|
preventLeave?: boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Whether navigation within single-paged app should be prevented.
|
|
44
|
+
*/
|
|
14
45
|
preventNavigation?: boolean;
|
|
46
|
+
/**
|
|
47
|
+
* Whether the dialog is modal.
|
|
48
|
+
*/
|
|
15
49
|
modal?: boolean;
|
|
16
|
-
|
|
50
|
+
/**
|
|
51
|
+
* Whether flyout content will be initially focused.
|
|
52
|
+
* Default is `true` if source element is not an text input element.
|
|
53
|
+
*
|
|
54
|
+
* If a CSS selector is given, the first matched element will be focused; otherwise
|
|
55
|
+
* the first focusable element will be focused.
|
|
56
|
+
*/
|
|
57
|
+
focus?: boolean | string;
|
|
58
|
+
/**
|
|
59
|
+
* Callback to perform asynchronous action when user confirms the dialog.
|
|
60
|
+
*
|
|
61
|
+
* The callback will receive value sent from {@link DialogRenderComponentProps.closeDialog},
|
|
62
|
+
* and will send resolved value to promise returned by {@link DialogState.open}.
|
|
63
|
+
*
|
|
64
|
+
* The dialog will be held open until the returned promise resolves.
|
|
65
|
+
* When the promise rejects, the dialog will remain open.
|
|
66
|
+
*/
|
|
67
|
+
onCommit?: (value: V | undefined) => T | Promise<T> | void;
|
|
68
|
+
/**
|
|
69
|
+
* Callback to be invoked when dialog has opened.
|
|
70
|
+
*/
|
|
17
71
|
onOpen?: (root: HTMLElement) => void;
|
|
72
|
+
/**
|
|
73
|
+
* Callback to be invoked when dialog has closed, after outro animation and before React DOM is unmounted.
|
|
74
|
+
*/
|
|
18
75
|
onClose?: (root: HTMLElement) => void;
|
|
19
76
|
}
|
|
20
77
|
|
|
21
|
-
export interface DialogRenderComponentProps<T,
|
|
22
|
-
|
|
78
|
+
export interface DialogRenderComponentProps<T, V = T> extends DialogBaseProps<T, V> {
|
|
79
|
+
/**
|
|
80
|
+
* Commits the dialog, with optional result value.
|
|
81
|
+
*
|
|
82
|
+
* When {@link DialogBaseProps.onCommit} is specified, it is invoked with the value passed in.
|
|
83
|
+
* Dialog will be closed when async operation is completed, or remain open if the operation failed.
|
|
84
|
+
*/
|
|
85
|
+
closeDialog: (value?: V) => Promise<void>;
|
|
23
86
|
}
|
|
24
87
|
|
|
25
|
-
export interface DialogOptions<T,
|
|
26
|
-
|
|
88
|
+
export interface DialogOptions<T, V = T> extends DialogBaseProps<T, V> {
|
|
89
|
+
/**
|
|
90
|
+
* A callback that render dialog contents.
|
|
91
|
+
*/
|
|
92
|
+
onRender: React.FC<DialogRenderComponentProps<T, V> & this>;
|
|
93
|
+
/**
|
|
94
|
+
* Specifies wrapper component that envelops content from {@link DialogOptions.onRender},
|
|
95
|
+
* which is useful for reusable layout for dialogs.
|
|
96
|
+
*/
|
|
97
|
+
wrapper?: React.FC<React.PropsWithChildren<DialogRenderComponentProps<T, V> & this>>;
|
|
27
98
|
}
|
|
28
99
|
|
|
29
|
-
export interface DialogProps<T> extends React.PropsWithChildren<DialogBaseProps<T>> {
|
|
100
|
+
export interface DialogProps<T, V = T> extends React.PropsWithChildren<DialogBaseProps<T, V>> {
|
|
101
|
+
/**
|
|
102
|
+
* A boolean flag controlling whether dialog is open.
|
|
103
|
+
*/
|
|
30
104
|
isOpen: boolean;
|
|
31
105
|
}
|
|
32
106
|
|
|
33
|
-
|
|
107
|
+
/**
|
|
108
|
+
* Creates a controller to render dialog.
|
|
109
|
+
* @param props A dictionary containing options.
|
|
110
|
+
*/
|
|
111
|
+
export function createDialog<T = any, V = T>(props: DialogOptions<T, V>): DialogState<T>;
|
|
34
112
|
|
|
35
|
-
|
|
113
|
+
/**
|
|
114
|
+
* Renders a dialog declaratively.
|
|
115
|
+
*/
|
|
116
|
+
export function Dialog<T, V = T>(props: DialogProps<T, V>): JSX.Element;
|
package/dialog.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createElement, useEffect, useState } from "react";
|
|
2
2
|
import ReactDOM from "react-dom";
|
|
3
3
|
import ReactDOMClient from "./include/external/react-dom-client.js";
|
|
4
|
-
import {
|
|
4
|
+
import { either, extend, makeAsync, noop, pick, pipe, resolve } from "./include/zeta-dom/util.js";
|
|
5
5
|
import { containsOrEquals, removeNode, setClass } from "./include/zeta-dom/domUtil.js";
|
|
6
6
|
import dom from "./include/zeta-dom/dom.js";
|
|
7
7
|
import { lock, notifyAsync, preventLeave, subscribeAsync } from "./include/zeta-dom/domLock.js";
|
|
@@ -17,7 +17,11 @@ export function createDialog(props) {
|
|
|
17
17
|
var promise;
|
|
18
18
|
|
|
19
19
|
dom.on(root, {
|
|
20
|
+
flyoutshow: function () {
|
|
21
|
+
(props.onOpen || noop)(root);
|
|
22
|
+
},
|
|
20
23
|
flyouthide: function () {
|
|
24
|
+
promise = null;
|
|
21
25
|
removeNode(root);
|
|
22
26
|
(props.onClose || noop)(root);
|
|
23
27
|
if (props.onRender) {
|
|
@@ -31,7 +35,7 @@ export function createDialog(props) {
|
|
|
31
35
|
setClass(root, 'loading', false);
|
|
32
36
|
}
|
|
33
37
|
});
|
|
34
|
-
subscribeAsync(root);
|
|
38
|
+
subscribeAsync(root, true);
|
|
35
39
|
|
|
36
40
|
return {
|
|
37
41
|
root: root,
|
|
@@ -45,7 +49,6 @@ export function createDialog(props) {
|
|
|
45
49
|
dom.retainFocus(dom.activeElement, root);
|
|
46
50
|
if (props.modal) {
|
|
47
51
|
root.setAttribute('is-modal', '');
|
|
48
|
-
dom.setModal(root);
|
|
49
52
|
}
|
|
50
53
|
if (props.onRender) {
|
|
51
54
|
var dialogProps = extend({}, props, {
|
|
@@ -60,20 +63,15 @@ export function createDialog(props) {
|
|
|
60
63
|
content = createElement(props.wrapper, dialogProps, content);
|
|
61
64
|
}
|
|
62
65
|
reactRoot.render(content);
|
|
63
|
-
setImmediate(function () {
|
|
64
|
-
dom.focus(root);
|
|
65
|
-
});
|
|
66
66
|
}
|
|
67
|
-
promise =
|
|
67
|
+
promise = resolve().then(function () {
|
|
68
|
+
return openFlyout(root, null, pick(props, ['focus']));
|
|
69
|
+
});
|
|
68
70
|
if (props.preventLeave) {
|
|
69
71
|
preventLeave(root, promise);
|
|
70
72
|
} else if (props.preventNavigation) {
|
|
71
73
|
lock(root, promise);
|
|
72
74
|
}
|
|
73
|
-
always(promise, function () {
|
|
74
|
-
promise = null;
|
|
75
|
-
});
|
|
76
|
-
(props.onOpen || noop)(root);
|
|
77
75
|
return promise;
|
|
78
76
|
}
|
|
79
77
|
};
|
package/dist/brew-js-react.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! brew-js-react v0.5.
|
|
1
|
+
/*! brew-js-react v0.5.2 | (c) misonou | https://misonou.github.io */
|
|
2
2
|
(function webpackUniversalModuleDefinition(root, factory) {
|
|
3
3
|
if(typeof exports === 'object' && typeof module === 'object')
|
|
4
4
|
module.exports = factory(require("brew-js"), require("react"), require("react-dom"), require("zeta-dom"), require("zeta-dom-react"), require("waterpipe"), require("jquery"));
|
|
@@ -355,6 +355,7 @@ var domUtil_lib$util = external_commonjs_zeta_dom_commonjs2_zeta_dom_amd_zeta_do
|
|
|
355
355
|
createNodeIterator = domUtil_lib$util.createNodeIterator,
|
|
356
356
|
createTreeWalker = domUtil_lib$util.createTreeWalker,
|
|
357
357
|
bind = domUtil_lib$util.bind,
|
|
358
|
+
bindOnce = domUtil_lib$util.bindOnce,
|
|
358
359
|
bindUntil = domUtil_lib$util.bindUntil,
|
|
359
360
|
dispatchDOMMouseEvent = domUtil_lib$util.dispatchDOMMouseEvent,
|
|
360
361
|
removeNode = domUtil_lib$util.removeNode,
|
|
@@ -443,7 +444,11 @@ function createDialog(props) {
|
|
|
443
444
|
|
|
444
445
|
var promise;
|
|
445
446
|
zeta_dom_dom.on(root, {
|
|
447
|
+
flyoutshow: function flyoutshow() {
|
|
448
|
+
(props.onOpen || noop)(root);
|
|
449
|
+
},
|
|
446
450
|
flyouthide: function flyouthide() {
|
|
451
|
+
promise = null;
|
|
447
452
|
removeNode(root);
|
|
448
453
|
(props.onClose || noop)(root);
|
|
449
454
|
|
|
@@ -458,7 +463,7 @@ function createDialog(props) {
|
|
|
458
463
|
setClass(root, 'loading', false);
|
|
459
464
|
}
|
|
460
465
|
});
|
|
461
|
-
subscribeAsync(root);
|
|
466
|
+
subscribeAsync(root, true);
|
|
462
467
|
return {
|
|
463
468
|
root: root,
|
|
464
469
|
close: _closeDialog,
|
|
@@ -473,7 +478,6 @@ function createDialog(props) {
|
|
|
473
478
|
|
|
474
479
|
if (props.modal) {
|
|
475
480
|
root.setAttribute('is-modal', '');
|
|
476
|
-
zeta_dom_dom.setModal(root);
|
|
477
481
|
}
|
|
478
482
|
|
|
479
483
|
if (props.onRender) {
|
|
@@ -491,12 +495,11 @@ function createDialog(props) {
|
|
|
491
495
|
}
|
|
492
496
|
|
|
493
497
|
reactRoot.render(content);
|
|
494
|
-
setImmediate(function () {
|
|
495
|
-
zeta_dom_dom.focus(root);
|
|
496
|
-
});
|
|
497
498
|
}
|
|
498
499
|
|
|
499
|
-
promise =
|
|
500
|
+
promise = resolve().then(function () {
|
|
501
|
+
return openFlyout(root, null, pick(props, ['focus']));
|
|
502
|
+
});
|
|
500
503
|
|
|
501
504
|
if (props.preventLeave) {
|
|
502
505
|
preventLeave(root, promise);
|
|
@@ -504,10 +507,6 @@ function createDialog(props) {
|
|
|
504
507
|
lock(root, promise);
|
|
505
508
|
}
|
|
506
509
|
|
|
507
|
-
always(promise, function () {
|
|
508
|
-
promise = null;
|
|
509
|
-
});
|
|
510
|
-
(props.onOpen || noop)(root);
|
|
511
510
|
return promise;
|
|
512
511
|
}
|
|
513
512
|
};
|
|
@@ -1636,7 +1635,7 @@ definePrototype(FlyoutToggleMixin, ClassNameMixin, {
|
|
|
1636
1635
|
var self = this;
|
|
1637
1636
|
FlyoutToggleMixinSuper.initElement.call(self, element, state);
|
|
1638
1637
|
self.onDispose(zeta_dom_dom.on(element, 'click', function () {
|
|
1639
|
-
toggleFlyout(self.flyoutMixin.elements()[0], element);
|
|
1638
|
+
toggleFlyout(self.flyoutMixin.elements()[0], element, self.flyoutMixin.flyoutOptions);
|
|
1640
1639
|
}));
|
|
1641
1640
|
}
|
|
1642
1641
|
});
|
|
@@ -1656,6 +1655,7 @@ function FlyoutMixin() {
|
|
|
1656
1655
|
self.isFlyoutOpened = false;
|
|
1657
1656
|
self.animating = false;
|
|
1658
1657
|
self.visible = false;
|
|
1658
|
+
self.initialFocus = undefined;
|
|
1659
1659
|
self.toggle = new FlyoutToggleMixin(self);
|
|
1660
1660
|
self.onDispose(function () {
|
|
1661
1661
|
self.isFlyoutOpened = false;
|
|
@@ -1663,6 +1663,16 @@ function FlyoutMixin() {
|
|
|
1663
1663
|
});
|
|
1664
1664
|
}
|
|
1665
1665
|
definePrototype(FlyoutMixin, ClassNameMixin, {
|
|
1666
|
+
get flyoutOptions() {
|
|
1667
|
+
var options = {};
|
|
1668
|
+
|
|
1669
|
+
if (this.initialFocus !== undefined) {
|
|
1670
|
+
options.focus = this.initialFocus;
|
|
1671
|
+
}
|
|
1672
|
+
|
|
1673
|
+
return options;
|
|
1674
|
+
},
|
|
1675
|
+
|
|
1666
1676
|
next: function next() {
|
|
1667
1677
|
this.effects = undefined;
|
|
1668
1678
|
return FlyoutMixinSuper.next.call(this);
|
|
@@ -1689,7 +1699,7 @@ definePrototype(FlyoutMixin, ClassNameMixin, {
|
|
|
1689
1699
|
open: function open(value) {
|
|
1690
1700
|
var element = this.elements()[0];
|
|
1691
1701
|
valueMap.set(element, value);
|
|
1692
|
-
return openFlyout(element);
|
|
1702
|
+
return openFlyout(element, null, this.flyoutOptions);
|
|
1693
1703
|
},
|
|
1694
1704
|
close: function close(value) {
|
|
1695
1705
|
return closeFlyout(this.elements()[0], value);
|