@via-profit/ui-kit 0.1.0-rc.28 → 0.1.0-rc.30

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.
Files changed (46) hide show
  1. package/Calendar/CalendarPaper.js +1 -1
  2. package/Menu/MenuItemInner.js +1 -1
  3. package/Menu/MenuWrapper.js +3 -1
  4. package/Modal/BaseModal/ModalInner.d.ts +13 -0
  5. package/Modal/BaseModal/ModalInner.js +47 -0
  6. package/Modal/BaseModal/ModalOverlay.d.ts +17 -0
  7. package/Modal/BaseModal/ModalOverlay.js +33 -0
  8. package/Modal/BaseModal/ModalWrapper.d.ts +14 -0
  9. package/Modal/BaseModal/ModalWrapper.js +177 -0
  10. package/Modal/BaseModal/RenderModal.d.ts +12 -0
  11. package/Modal/BaseModal/RenderModal.js +20 -0
  12. package/Modal/BaseModal/context.d.ts +30 -0
  13. package/Modal/BaseModal/context.js +44 -0
  14. package/Modal/BaseModal/index.d.ts +46 -0
  15. package/Modal/BaseModal/index.js +66 -0
  16. package/Modal/ConfirmBox/ConfirmBoxContainer.js +2 -2
  17. package/Modal/ConfirmBox/ConfirmBoxContent.js +2 -2
  18. package/Modal/ConfirmBox/ConfirmBoxFooter.js +2 -2
  19. package/Modal/ConfirmBox/ConfirmBoxHeader.js +4 -4
  20. package/Modal/ConfirmBox/index.d.ts +5 -5
  21. package/Modal/ConfirmBox/index.js +5 -54
  22. package/Modal/Dialog/DialogInner.d.ts +10 -0
  23. package/Modal/Dialog/DialogInner.js +49 -0
  24. package/Modal/Dialog/index.d.ts +4 -4
  25. package/Modal/Dialog/index.js +12 -56
  26. package/Modal/{CloseIcon.js → Drawer/DrawerCloseIcon.js} +2 -2
  27. package/Modal/Drawer/DrawerContainer.js +5 -3
  28. package/Modal/Drawer/DrawerContent.js +4 -3
  29. package/Modal/Drawer/DrawerFooter.js +2 -2
  30. package/Modal/Drawer/DrawerHeader.js +10 -10
  31. package/Modal/Drawer/DrawerInner.d.ts +18 -0
  32. package/Modal/Drawer/DrawerInner.js +141 -0
  33. package/Modal/Drawer/index.d.ts +12 -4
  34. package/Modal/Drawer/index.js +15 -52
  35. package/Modal/MessageBox/index.d.ts +5 -5
  36. package/Modal/MessageBox/index.js +5 -53
  37. package/Modal/index.d.ts +2 -3
  38. package/Modal/index.js +6 -6
  39. package/README.md +1 -2
  40. package/Surface/SurfaceContainer.d.ts +2 -2
  41. package/Surface/SurfaceContainer.js +3 -9
  42. package/Surface/SurfaceSubheader.js +1 -1
  43. package/Surface/index.d.ts +8 -8
  44. package/Surface/index.js +2 -2
  45. package/package.json +1 -4
  46. /package/Modal/{CloseIcon.d.ts → Drawer/DrawerCloseIcon.d.ts} +0 -0
@@ -10,7 +10,7 @@ const CalendarPaper = styled_1.default.div `
10
10
  flex-direction: column;
11
11
  justify-content: stretch;
12
12
  background-color: ${({ theme }) => theme.color.surface.toString()};
13
- border-radius: ${({ theme }) => theme.shape.radiusFactor * 1}em;
13
+ border-radius: ${({ theme }) => theme.shape.radiusFactor}em;
14
14
  padding: 0.4em;
15
15
  max-width: 17.6em;
16
16
  max-height: 20.4em;
@@ -21,7 +21,7 @@ const InnerContainer = styled_1.default.div `
21
21
  user-select: none;
22
22
  padding: 0.4em 0.8em;
23
23
  transition: all 240ms ease-out;
24
- border-radius: ${({ theme }) => theme.shape.radiusFactor * 1}em;
24
+ border-radius: ${({ theme }) => theme.shape.radiusFactor}em;
25
25
  background-color: ${({ theme, selected, hovered }) => {
26
26
  if (selected && hovered) {
27
27
  return theme.color.accentPrimary.darken(0.1).toString();
@@ -22,7 +22,9 @@ const StyledMenuWrapper = styled_1.default.div `
22
22
  flex-direction: column;
23
23
  display: flex;
24
24
  flex-direction: column;
25
- transition: visibility 120ms ease-out, opacity 120ms ease-out;
25
+ transition:
26
+ visibility 120ms ease-out,
27
+ opacity 120ms ease-out;
26
28
  opacity: ${props => (props.$isOpen ? 1 : 0)};
27
29
  visibility: ${props => (props.$isOpen ? 'visible' : 'hidden')};
28
30
  background-color: ${({ theme }) => theme.color.surface.toString()};
@@ -0,0 +1,13 @@
1
+ import React from 'react';
2
+ export interface ModalInnerProps extends React.HTMLAttributes<HTMLDivElement> {
3
+ /**
4
+ * The dialog will remain open as long as the value is true
5
+ */
6
+ readonly isOpen: boolean;
7
+ /**
8
+ * The function that will be called to close the dialog
9
+ */
10
+ readonly onRequestClose: () => void;
11
+ }
12
+ declare const _default: React.ForwardRefExoticComponent<ModalInnerProps & React.RefAttributes<HTMLDivElement>>;
13
+ export default _default;
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ var __rest = (this && this.__rest) || function (s, e) {
3
+ var t = {};
4
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
5
+ t[p] = s[p];
6
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
7
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
8
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
9
+ t[p[i]] = s[p[i]];
10
+ }
11
+ return t;
12
+ };
13
+ var __importDefault = (this && this.__importDefault) || function (mod) {
14
+ return (mod && mod.__esModule) ? mod : { "default": mod };
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ const react_1 = __importDefault(require("react"));
18
+ const styled_1 = __importDefault(require("@emotion/styled"));
19
+ const react_2 = require("@emotion/react");
20
+ const StyledModalInner = styled_1.default.div `
21
+ opacity: 0;
22
+ z-index: ${({ theme }) => theme.zIndex.modal};
23
+ position: fixed;
24
+ left: 50%;
25
+ top: 50%;
26
+ outline: none;
27
+ background-color: ${({ theme }) => theme.color.surface.toString()};
28
+ border-radius: ${({ theme }) => theme.shape.radiusFactor * 2}em;
29
+ transform: translate(-50%, -30%);
30
+ transition:
31
+ transform 240ms ease-out,
32
+ opacity 100ms ease-out;
33
+
34
+ ${({ $isOpen }) => $isOpen &&
35
+ (0, react_2.css) `
36
+ opacity: 1;
37
+ transform: translate(-50%, -50%);
38
+ ransition:
39
+ transform 240ms ease-out,
40
+ opacity 100ms ease-out;
41
+ `}
42
+ `;
43
+ const ModalInner = (props, ref) => {
44
+ const { children, isOpen, onRequestClose } = props, restProps = __rest(props, ["children", "isOpen", "onRequestClose"]);
45
+ return (react_1.default.createElement(StyledModalInner, Object.assign({}, restProps, { "$isOpen": isOpen, ref: ref }), children));
46
+ };
47
+ exports.default = react_1.default.forwardRef(ModalInner);
@@ -0,0 +1,17 @@
1
+ import React from 'react';
2
+ export interface ModalOverlayProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children'> {
3
+ /**
4
+ * The dialog will remain open as long as the value is true
5
+ */
6
+ readonly isOpen: boolean;
7
+ /**
8
+ * The function that will be called to close the dialog
9
+ */
10
+ readonly onRequestClose: () => void;
11
+ /**
12
+ * Should the dialog close when overlay mouse click
13
+ */
14
+ readonly closeOnOverlayClick: boolean;
15
+ }
16
+ declare const _default: React.ForwardRefExoticComponent<ModalOverlayProps & React.RefAttributes<HTMLDivElement>>;
17
+ export default _default;
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ var __rest = (this && this.__rest) || function (s, e) {
3
+ var t = {};
4
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
5
+ t[p] = s[p];
6
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
7
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
8
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
9
+ t[p[i]] = s[p[i]];
10
+ }
11
+ return t;
12
+ };
13
+ var __importDefault = (this && this.__importDefault) || function (mod) {
14
+ return (mod && mod.__esModule) ? mod : { "default": mod };
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ const react_1 = __importDefault(require("react"));
18
+ const styled_1 = __importDefault(require("@emotion/styled"));
19
+ const StyledModalOverlay = styled_1.default.div `
20
+ position: fixed;
21
+ inset: 0;
22
+ z-index: ${({ theme }) => theme.zIndex.modal};
23
+ background-color: ${({ theme }) => theme.isDark
24
+ ? theme.color.backgroundPrimary.darken(30).alpha(0.8).rgbString()
25
+ : theme.color.textPrimary.darken(30).alpha(0.8).rgbString()};
26
+ opacity: ${({ $isOpen }) => ($isOpen ? 1 : 0)};
27
+ transition: opacity 120ms ease-out;
28
+ `;
29
+ const ModalOverlay = (props, ref) => {
30
+ const { isOpen, onRequestClose, closeOnOverlayClick } = props, restProps = __rest(props, ["isOpen", "onRequestClose", "closeOnOverlayClick"]);
31
+ return (react_1.default.createElement(StyledModalOverlay, Object.assign({}, restProps, { ref: ref, "$isOpen": isOpen, onClick: closeOnOverlayClick ? () => onRequestClose() : undefined })));
32
+ };
33
+ exports.default = react_1.default.forwardRef(ModalOverlay);
@@ -0,0 +1,14 @@
1
+ import React from 'react';
2
+ export type ModalWrapperProps = {
3
+ /**
4
+ * The dialog will remain open as long as the value is true
5
+ */
6
+ readonly isOpen: boolean;
7
+ /**
8
+ * Timeout (in `milliseconds`), after which the dialog box will be unmounted
9
+ */
10
+ readonly destroyTimeout: number;
11
+ readonly children: React.ReactNode | readonly React.ReactNode[];
12
+ };
13
+ declare const ModalWrapper: React.FC<ModalWrapperProps>;
14
+ export default ModalWrapper;
@@ -0,0 +1,177 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const react_1 = __importDefault(require("react"));
7
+ const react_2 = require("@emotion/react");
8
+ const context_1 = require("./context");
9
+ const ModalWrapper = props => {
10
+ const { children, isOpen: isOpenProp } = props;
11
+ const { state, dispatch } = (0, context_1.useContext)();
12
+ const [alreadyMounted, setMountState] = react_1.default.useState(true);
13
+ const { closeOnEsape, isMounted, isOpen, destroyTimeout, onRequestClose } = state;
14
+ const containerRef = react_1.default.useRef(null);
15
+ const id = react_1.default.useMemo(() => context_1.PORTAL_ID + ':' + new Date().getTime().toString(), []);
16
+ const getScrollWidth = react_1.default.useCallback(() => {
17
+ var _a;
18
+ const outer = window.document.createElement('div');
19
+ const inner = window.document.createElement('div');
20
+ let widthNoScroll = 0;
21
+ let widthWithScroll = 0;
22
+ outer.style.visibility = 'hidden';
23
+ outer.style.width = '100px';
24
+ window.document.body.appendChild(outer);
25
+ widthNoScroll = outer.offsetWidth;
26
+ // force scrollbars
27
+ outer.style.overflow = 'scroll';
28
+ // add innerdiv
29
+ inner.style.width = '100%';
30
+ outer.appendChild(inner);
31
+ widthWithScroll = inner.offsetWidth;
32
+ // remove div
33
+ (_a = outer.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(outer);
34
+ return widthNoScroll - widthWithScroll;
35
+ }, []);
36
+ /**
37
+ * Set focus to the next or prev element
38
+ */
39
+ const lastIndex = react_1.default.useRef(-1);
40
+ const nextFocus = react_1.default.useCallback((reverse) => {
41
+ if (!containerRef.current) {
42
+ return;
43
+ }
44
+ const universe = containerRef.current.querySelectorAll('input, button, select, textarea, a[href]');
45
+ const list = Array.prototype.filter.call(universe, function (item) {
46
+ return item.tabIndex >= '0';
47
+ });
48
+ if (!reverse) {
49
+ const nextIndex = lastIndex.current + 1;
50
+ if (list[nextIndex]) {
51
+ list[nextIndex].focus();
52
+ lastIndex.current = nextIndex;
53
+ return;
54
+ }
55
+ // othrwise
56
+ const nextEl = list[0];
57
+ if (nextEl) {
58
+ lastIndex.current = 0;
59
+ nextEl.focus();
60
+ return;
61
+ }
62
+ }
63
+ if (reverse) {
64
+ const nextIndex = lastIndex.current - 1;
65
+ if (list[nextIndex]) {
66
+ list[nextIndex].focus();
67
+ lastIndex.current = nextIndex;
68
+ return;
69
+ }
70
+ // othrwise
71
+ const nextEl = list[list.length - 1];
72
+ if (nextEl) {
73
+ lastIndex.current = list.length - 1;
74
+ nextEl.focus();
75
+ return;
76
+ }
77
+ }
78
+ }, []);
79
+ react_1.default.useEffect(() => {
80
+ if (containerRef.current) {
81
+ containerRef.current.focus();
82
+ }
83
+ const keydown = (event) => {
84
+ if (event.key.toLowerCase() !== 'tab') {
85
+ return;
86
+ }
87
+ event.preventDefault();
88
+ nextFocus(event.shiftKey);
89
+ };
90
+ const lastFocused = document.activeElement;
91
+ window.document.addEventListener('keydown', keydown);
92
+ return () => {
93
+ if (lastFocused) {
94
+ lastFocused.focus();
95
+ }
96
+ window.document.removeEventListener('keydown', keydown);
97
+ };
98
+ }, [nextFocus]);
99
+ /**
100
+ * Component will unmount
101
+ * Mark component as unmounted
102
+ */
103
+ react_1.default.useEffect(() => () => {
104
+ setMountState(false);
105
+ }, []);
106
+ react_1.default.useEffect(() => {
107
+ /**
108
+ * The last dialog will be found and closed
109
+ */
110
+ const keyDown = (event) => {
111
+ var _a, _b, _c;
112
+ if (event.key.toLocaleLowerCase() === 'escape' && closeOnEsape) {
113
+ const portal = window.document.querySelector(`#${context_1.PORTAL_ID}`);
114
+ const lastID = (_c = (_a = portal === null || portal === void 0 ? void 0 : portal.children) === null || _a === void 0 ? void 0 : _a[((_b = portal === null || portal === void 0 ? void 0 : portal.childNodes) === null || _b === void 0 ? void 0 : _b.length) - 1]) === null || _c === void 0 ? void 0 : _c.id;
115
+ if (lastID === id) {
116
+ onRequestClose();
117
+ }
118
+ }
119
+ };
120
+ window.document.addEventListener('keydown', keyDown);
121
+ return () => {
122
+ window.document.removeEventListener('keydown', keyDown);
123
+ };
124
+ }, [onRequestClose, closeOnEsape, id]);
125
+ /**
126
+ * Controller for visibility state.
127
+ * Waiting n milliseconds after closing the modal, then sets the visibility property to true
128
+ * and sets visibility property to false otherwise
129
+ */
130
+ react_1.default.useEffect(() => {
131
+ var _a;
132
+ if (isOpen !== isOpenProp) {
133
+ /**
134
+ * Mark as mounted and wait minimum loop of event (15ms) then mark as open
135
+ */
136
+ if (isOpenProp) {
137
+ dispatch((0, context_1.actionSetState)({ isMounted: true }));
138
+ (_a = window.document.body) === null || _a === void 0 ? void 0 : _a.classList.add('-modal-over');
139
+ setTimeout(() => {
140
+ if (alreadyMounted) {
141
+ dispatch((0, context_1.actionSetState)({ isOpen: true }));
142
+ }
143
+ }, 15);
144
+ return;
145
+ }
146
+ /**
147
+ * Mark as closed and wait destroyTimeout then mark as unmounted
148
+ */
149
+ if (!isOpenProp) {
150
+ dispatch((0, context_1.actionSetState)({ isOpen: false }));
151
+ setTimeout(() => {
152
+ var _a, _b;
153
+ if (alreadyMounted) {
154
+ const portal = window.document.querySelector(`#${context_1.PORTAL_ID}`);
155
+ if (((_a = portal === null || portal === void 0 ? void 0 : portal.children) === null || _a === void 0 ? void 0 : _a.length) === 1) {
156
+ (_b = window.document.body) === null || _b === void 0 ? void 0 : _b.classList.remove('-modal-over');
157
+ }
158
+ dispatch((0, context_1.actionSetState)({ isMounted: false }));
159
+ }
160
+ }, destroyTimeout);
161
+ return;
162
+ }
163
+ }
164
+ }, [isOpenProp, isOpen, alreadyMounted, destroyTimeout, dispatch, getScrollWidth]);
165
+ return react_1.default.useMemo(() => isMounted ? (react_1.default.createElement("div", { ref: containerRef, tabIndex: -1, id: id },
166
+ children,
167
+ react_1.default.createElement(react_2.Global, { styles: (0, react_2.css) `
168
+ :root {
169
+ --modal-scroll-width: ${getScrollWidth()}px;
170
+ }
171
+ body.-modal-over {
172
+ overflow: hidden;
173
+ margin-right: var(--modal-scroll-width);
174
+ }
175
+ ` }))) : null, [children, getScrollWidth, isMounted, id]);
176
+ };
177
+ exports.default = ModalWrapper;
@@ -0,0 +1,12 @@
1
+ import React from 'react';
2
+ import { ModalOverlayProps } from './ModalOverlay';
3
+ import { ModalInnerProps } from './ModalInner';
4
+ interface RenderModalProps {
5
+ readonly children: React.ReactNode | readonly React.ReactNode[];
6
+ readonly overrides: {
7
+ readonly Overlay?: React.ForwardRefExoticComponent<ModalOverlayProps & React.RefAttributes<HTMLDivElement>>;
8
+ readonly Inner?: React.ForwardRefExoticComponent<ModalInnerProps & React.RefAttributes<HTMLDivElement>>;
9
+ };
10
+ }
11
+ declare const RenderModal: React.FC<RenderModalProps>;
12
+ export default RenderModal;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const react_1 = __importDefault(require("react"));
7
+ const context_1 = require("./context");
8
+ const ModalOverlay_1 = __importDefault(require("./ModalOverlay"));
9
+ const ModalInner_1 = __importDefault(require("./ModalInner"));
10
+ const RenderModal = props => {
11
+ const { children, overrides } = props;
12
+ const { state } = (0, context_1.useContext)();
13
+ const { isOpen, closeOnOverlayClick, onRequestClose } = state;
14
+ const overridesMap = react_1.default.useMemo(() => (Object.assign({ Overlay: ModalOverlay_1.default,
15
+ Inner: ModalInner_1.default }, overrides)), [overrides]);
16
+ return (react_1.default.createElement(react_1.default.Fragment, null,
17
+ react_1.default.useMemo(() => (react_1.default.createElement(overridesMap.Overlay, { isOpen: isOpen, onRequestClose: onRequestClose, closeOnOverlayClick: closeOnOverlayClick })), [overridesMap, isOpen, closeOnOverlayClick, onRequestClose]),
18
+ react_1.default.useMemo(() => (react_1.default.createElement(overridesMap.Inner, { isOpen: isOpen, onRequestClose: onRequestClose }, children)), [children, isOpen, overridesMap, onRequestClose])));
19
+ };
20
+ exports.default = RenderModal;
@@ -0,0 +1,30 @@
1
+ import React from 'react';
2
+ export type State = {
3
+ readonly isOpen: boolean;
4
+ readonly isMounted: boolean;
5
+ readonly destroyTimeout: number;
6
+ readonly onRequestClose: () => void;
7
+ readonly closeOnEsape: boolean;
8
+ readonly closeOnOverlayClick: boolean;
9
+ };
10
+ export type Context = {
11
+ readonly state: State;
12
+ readonly dispatch: React.Dispatch<Action>;
13
+ };
14
+ export type ActionSetState = {
15
+ readonly type: 'setState';
16
+ readonly payload: Partial<State>;
17
+ };
18
+ export type Action = ActionSetState;
19
+ export declare const PORTAL_ID = "modal-portal";
20
+ export declare const defaultState: State;
21
+ export declare const actionSetState: (payload: ActionSetState['payload']) => ActionSetState;
22
+ export interface ContextProviderProps {
23
+ readonly children: React.ReactNode | readonly React.ReactNode[];
24
+ readonly initialState: Omit<State, 'isMounted'>;
25
+ }
26
+ export declare const ContextProvider: React.FC<ContextProviderProps>;
27
+ export declare const useContext: () => {
28
+ state: State;
29
+ dispatch: React.Dispatch<ActionSetState>;
30
+ };
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.useContext = exports.ContextProvider = exports.actionSetState = exports.defaultState = exports.PORTAL_ID = void 0;
7
+ const react_1 = __importDefault(require("react"));
8
+ exports.PORTAL_ID = 'modal-portal';
9
+ exports.defaultState = {
10
+ isOpen: false,
11
+ isMounted: false,
12
+ destroyTimeout: 240,
13
+ closeOnEsape: true,
14
+ closeOnOverlayClick: true,
15
+ onRequestClose: () => undefined,
16
+ };
17
+ const reducer = (state, action) => {
18
+ switch (action.type) {
19
+ case 'setState':
20
+ return Object.assign(Object.assign({}, state), action.payload);
21
+ default:
22
+ return state;
23
+ }
24
+ };
25
+ const actionSetState = (payload) => ({
26
+ type: 'setState',
27
+ payload,
28
+ });
29
+ exports.actionSetState = actionSetState;
30
+ const context = react_1.default.createContext({ state: exports.defaultState, dispatch: () => undefined });
31
+ const ContextProvider = props => {
32
+ const { children, initialState } = props;
33
+ const [state, dispatch] = react_1.default.useReducer(reducer, Object.assign(Object.assign({}, exports.defaultState), initialState));
34
+ return react_1.default.createElement(context.Provider, { value: { state, dispatch } }, children);
35
+ };
36
+ exports.ContextProvider = ContextProvider;
37
+ const useContext = () => {
38
+ const { state, dispatch } = react_1.default.useContext(context);
39
+ return {
40
+ state,
41
+ dispatch,
42
+ };
43
+ };
44
+ exports.useContext = useContext;
@@ -0,0 +1,46 @@
1
+ import React from 'react';
2
+ import { ModalOverlayProps } from './ModalOverlay';
3
+ import { ModalInnerProps } from './ModalInner';
4
+ export interface BaseModalProps {
5
+ /**
6
+ * The dialog will remain open as long as the value is true
7
+ */
8
+ readonly isOpen: boolean;
9
+ /**
10
+ * The function that will be called to close the dialog
11
+ */
12
+ readonly onRequestClose: () => void;
13
+ /**
14
+ * Dialog content
15
+ */
16
+ readonly children: React.ReactNode;
17
+ /**
18
+ * Timeout (in `milliseconds`), after which the dialog box will be unmounted.\
19
+ * Correct if the value is equal to the length of the transition time\
20
+ * \
21
+ * **Default:** `240`
22
+ */
23
+ readonly destroyTimeout?: number;
24
+ /**
25
+ * Should the dialog close when `escape` key press\
26
+ * \
27
+ * **Default**: `true`
28
+ */
29
+ readonly closeOnEsape?: boolean;
30
+ /**
31
+ * Should the dialog close when overlay mouse click\
32
+ * \
33
+ * **Default**: `true`
34
+ */
35
+ readonly closeOnOverlayClick?: boolean;
36
+ /**
37
+ * Overridable components map
38
+ */
39
+ readonly overrides?: BaseModalOverrides;
40
+ }
41
+ export interface BaseModalOverrides {
42
+ readonly Overlay?: React.ForwardRefExoticComponent<ModalOverlayProps & React.RefAttributes<HTMLDivElement>>;
43
+ readonly Inner?: React.ForwardRefExoticComponent<ModalInnerProps & React.RefAttributes<HTMLDivElement>>;
44
+ }
45
+ declare const BaseModal: React.FC<BaseModalProps>;
46
+ export default BaseModal;
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const react_1 = __importDefault(require("react"));
7
+ const react_dom_1 = __importDefault(require("react-dom"));
8
+ const context_1 = require("./context");
9
+ const ModalOverlay_1 = __importDefault(require("./ModalOverlay"));
10
+ const ModalInner_1 = __importDefault(require("./ModalInner"));
11
+ const ModalWrapper_1 = __importDefault(require("./ModalWrapper"));
12
+ const RenderModal_1 = __importDefault(require("./RenderModal"));
13
+ const NoSSR_1 = __importDefault(require("../../NoSSR"));
14
+ const BaseModal = props => {
15
+ const { isOpen, children, overrides, onRequestClose, closeOnOverlayClick = context_1.defaultState.closeOnOverlayClick, closeOnEsape = context_1.defaultState.closeOnEsape, destroyTimeout = context_1.defaultState.destroyTimeout, } = props;
16
+ const destroyTimeoutRef = react_1.default.useRef(null);
17
+ const [domLoaded, setDomLoaded] = react_1.default.useState(false);
18
+ const overridesMap = react_1.default.useMemo(() => (Object.assign({ Overlay: ModalOverlay_1.default,
19
+ Inner: ModalInner_1.default }, overrides)), [overrides]);
20
+ react_1.default.useEffect(() => {
21
+ /**
22
+ * Client render detection
23
+ */
24
+ setDomLoaded(true);
25
+ const timeout = destroyTimeoutRef.current;
26
+ // unload destroy timeout
27
+ return () => {
28
+ if (timeout) {
29
+ clearTimeout(timeout);
30
+ }
31
+ };
32
+ }, []);
33
+ const portalEl = react_1.default.useMemo(() => {
34
+ if (typeof window === 'undefined') {
35
+ return undefined;
36
+ }
37
+ const node = window.document.body.querySelector(`#${context_1.PORTAL_ID}`);
38
+ if (node) {
39
+ return node;
40
+ }
41
+ const newNode = window.document.createElement('div');
42
+ newNode.setAttribute('id', context_1.PORTAL_ID);
43
+ window.document.body.appendChild(newNode);
44
+ return newNode;
45
+ }, []);
46
+ react_1.default.useEffect(() => () => {
47
+ if (typeof window !== 'undefined') {
48
+ const node = window.document.body.querySelector(`#${context_1.PORTAL_ID}`);
49
+ if (node) {
50
+ node.remove();
51
+ }
52
+ }
53
+ }, []);
54
+ return (react_1.default.createElement(NoSSR_1.default, null, domLoaded &&
55
+ portalEl &&
56
+ react_dom_1.default.createPortal(react_1.default.createElement(context_1.ContextProvider, { initialState: {
57
+ isOpen,
58
+ destroyTimeout,
59
+ closeOnEsape,
60
+ closeOnOverlayClick,
61
+ onRequestClose,
62
+ } },
63
+ react_1.default.createElement(ModalWrapper_1.default, { isOpen: isOpen, destroyTimeout: destroyTimeout },
64
+ react_1.default.createElement(RenderModal_1.default, { overrides: overridesMap }, children))), portalEl, 'ui-modal-portal')));
65
+ };
66
+ exports.default = BaseModal;
@@ -16,13 +16,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  const react_1 = __importDefault(require("react"));
18
18
  const styled_1 = __importDefault(require("@emotion/styled"));
19
- const Container = styled_1.default.div `
19
+ const StyledConfirmBoxContainer = styled_1.default.div `
20
20
  display: flex;
21
21
  flex-flow: column;
22
22
  min-width: 20em;
23
23
  `;
24
24
  const ConfirmBoxContainer = (props, ref) => {
25
25
  const { children, dialogID } = props, nativeProps = __rest(props, ["children", "dialogID"]);
26
- return (react_1.default.createElement(Container, Object.assign({ role: "modal-confirmbox", "aria-labelledby": `${dialogID}-title`, "aria-describedby": `${dialogID}-description` }, nativeProps, { ref: ref }), children));
26
+ return (react_1.default.createElement(StyledConfirmBoxContainer, Object.assign({ role: "modal-confirmbox", "aria-labelledby": `${dialogID}-title`, "aria-describedby": `${dialogID}-description` }, nativeProps, { ref: ref }), children));
27
27
  };
28
28
  exports.default = react_1.default.forwardRef(ConfirmBoxContainer);
@@ -16,12 +16,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  const react_1 = __importDefault(require("react"));
18
18
  const styled_1 = __importDefault(require("@emotion/styled"));
19
- const Content = styled_1.default.div `
19
+ const StyledConfirmBoxContent = styled_1.default.div `
20
20
  flex: 1;
21
21
  padding: 1em 1em;
22
22
  `;
23
23
  const ConfirmBoxContent = (props, ref) => {
24
24
  const { children, dialogID } = props, nativeProps = __rest(props, ["children", "dialogID"]);
25
- return (react_1.default.createElement(Content, Object.assign({ id: `${dialogID}-description` }, nativeProps, { ref: ref }), children));
25
+ return (react_1.default.createElement(StyledConfirmBoxContent, Object.assign({ id: `${dialogID}-description` }, nativeProps, { ref: ref }), children));
26
26
  };
27
27
  exports.default = react_1.default.forwardRef(ConfirmBoxContent);
@@ -17,7 +17,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
17
17
  const react_1 = __importDefault(require("react"));
18
18
  const styled_1 = __importDefault(require("@emotion/styled"));
19
19
  const Button_1 = __importDefault(require("../../Button"));
20
- const Footer = styled_1.default.div `
20
+ const StyledConfirmBoxFooter = styled_1.default.div `
21
21
  display: flex;
22
22
  justify-content: flex-end;
23
23
  align-items: center;
@@ -39,7 +39,7 @@ const Footer = styled_1.default.div `
39
39
  `;
40
40
  const ConfirmBoxFooter = (props, ref) => {
41
41
  const { onRequestClose, onRequestYes, dismissButtonLabel, confirmButtonLabel } = props, nativeProps = __rest(props, ["onRequestClose", "onRequestYes", "dismissButtonLabel", "confirmButtonLabel"]);
42
- return (react_1.default.createElement(Footer, Object.assign({}, nativeProps, { ref: ref }),
42
+ return (react_1.default.createElement(StyledConfirmBoxFooter, Object.assign({}, nativeProps, { ref: ref }),
43
43
  react_1.default.createElement(Button_1.default, { onClick: onRequestClose }, typeof dismissButtonLabel === 'undefined' ? 'Dismiss' : dismissButtonLabel),
44
44
  react_1.default.createElement(Button_1.default, { color: "primary", onClick: onRequestYes }, typeof confirmButtonLabel === 'undefined' ? 'Confirm' : confirmButtonLabel)));
45
45
  };
@@ -16,16 +16,16 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  const react_1 = __importDefault(require("react"));
18
18
  const styled_1 = __importDefault(require("@emotion/styled"));
19
- const Header = styled_1.default.div `
19
+ const StyedConfirmBoxHeader = styled_1.default.div `
20
20
  padding: 1em 1em 0 1em;
21
21
  `;
22
- const HeaderTitle = styled_1.default.div `
22
+ const ConfirmBoxTitle = styled_1.default.div `
23
23
  font-size: 1.4rem;
24
24
  font-weight: 600;
25
25
  `;
26
26
  const ConfirmBoxHeader = (props, ref) => {
27
27
  const { children, dialogID } = props, nativeProps = __rest(props, ["children", "dialogID"]);
28
- return (react_1.default.createElement(Header, Object.assign({}, nativeProps, { ref: ref }),
29
- react_1.default.createElement(HeaderTitle, { id: `${dialogID}-title` }, children)));
28
+ return (react_1.default.createElement(StyedConfirmBoxHeader, Object.assign({}, nativeProps, { ref: ref }),
29
+ react_1.default.createElement(ConfirmBoxTitle, { id: `${dialogID}-title` }, children)));
30
30
  };
31
31
  exports.default = react_1.default.forwardRef(ConfirmBoxHeader);