@khanacademy/wonder-blocks-modal 4.1.0 → 4.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/dist/components/modal-content.d.ts +8 -9
- package/dist/components/modal-footer.d.ts +5 -5
- package/dist/components/modal-header.d.ts +6 -7
- package/dist/components/modal-panel.d.ts +13 -14
- package/dist/es/index.js +189 -173
- package/dist/index.js +188 -172
- package/dist/themes/default.d.ts +22 -0
- package/dist/themes/khanmigo.d.ts +36 -0
- package/dist/themes/themed-modal-dialog.d.ts +22 -0
- package/package.json +3 -3
- package/src/components/modal-content.tsx +53 -54
- package/src/components/modal-footer.tsx +8 -10
- package/src/components/modal-header.tsx +95 -102
- package/src/components/modal-panel.tsx +66 -73
- package/src/themes/default.ts +22 -0
- package/src/themes/khanmigo.ts +15 -0
- package/src/themes/themed-modal-dialog.tsx +2 -1
- package/tsconfig-build.tsbuildinfo +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# @khanacademy/wonder-blocks-modal
|
|
2
2
|
|
|
3
|
+
## 4.2.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [80592e75]
|
|
8
|
+
- @khanacademy/wonder-blocks-theming@1.3.0
|
|
9
|
+
- @khanacademy/wonder-blocks-icon-button@5.1.8
|
|
10
|
+
|
|
11
|
+
## 4.2.0
|
|
12
|
+
|
|
13
|
+
### Minor Changes
|
|
14
|
+
|
|
15
|
+
- b7bae8f2: Add theming support to ModalPanel
|
|
16
|
+
- 09c61d25: Add theming support to ModalHeader and ModalFooter
|
|
17
|
+
|
|
3
18
|
## 4.1.0
|
|
4
19
|
|
|
5
20
|
### Minor Changes
|
|
@@ -8,16 +8,15 @@ type Props = {
|
|
|
8
8
|
/** Optional styling to apply to the contents. */
|
|
9
9
|
style?: StyleType;
|
|
10
10
|
};
|
|
11
|
-
type DefaultProps = {
|
|
12
|
-
scrollOverflow: Props["scrollOverflow"];
|
|
13
|
-
};
|
|
14
11
|
/**
|
|
15
12
|
* The Modal content included after the header
|
|
16
13
|
*/
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
14
|
+
declare function ModalContent(props: Props): JSX.Element;
|
|
15
|
+
declare namespace ModalContent {
|
|
16
|
+
var __IS_MODAL_CONTENT__: boolean;
|
|
17
|
+
var isComponentOf: (instance: any) => boolean;
|
|
18
|
+
var defaultProps: {
|
|
19
|
+
scrollOverflow: boolean;
|
|
20
|
+
};
|
|
22
21
|
}
|
|
23
|
-
export
|
|
22
|
+
export default ModalContent;
|
|
@@ -19,9 +19,9 @@ type Props = {
|
|
|
19
19
|
* </ModalFooter>
|
|
20
20
|
* ```
|
|
21
21
|
*/
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
declare function ModalFooter({ children }: Props): JSX.Element;
|
|
23
|
+
declare namespace ModalFooter {
|
|
24
|
+
var __IS_MODAL_FOOTER__: boolean;
|
|
25
|
+
var isComponentOf: (instance: any) => boolean;
|
|
26
26
|
}
|
|
27
|
-
export
|
|
27
|
+
export default ModalFooter;
|
|
@@ -40,9 +40,6 @@ type WithBreadcrumbs = Common & {
|
|
|
40
40
|
breadcrumbs: React.ReactElement<React.ComponentProps<typeof Breadcrumbs>>;
|
|
41
41
|
};
|
|
42
42
|
type Props = Common | WithSubtitle | WithBreadcrumbs;
|
|
43
|
-
type DefaultProps = {
|
|
44
|
-
light: Props["light"];
|
|
45
|
-
};
|
|
46
43
|
/**
|
|
47
44
|
* This is a helper component that is never rendered by itself. It is always
|
|
48
45
|
* pinned to the top of the dialog, is responsive using the same behavior as its
|
|
@@ -86,8 +83,10 @@ type DefaultProps = {
|
|
|
86
83
|
* />
|
|
87
84
|
* ```
|
|
88
85
|
*/
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
86
|
+
declare function ModalHeader(props: Props): JSX.Element;
|
|
87
|
+
declare namespace ModalHeader {
|
|
88
|
+
var defaultProps: {
|
|
89
|
+
light: boolean;
|
|
90
|
+
};
|
|
92
91
|
}
|
|
93
|
-
export
|
|
92
|
+
export default ModalHeader;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
+
import { PropsFor } from "@khanacademy/wonder-blocks-core";
|
|
2
3
|
import type { StyleType } from "@khanacademy/wonder-blocks-core";
|
|
3
4
|
import ModalContent from "./modal-content";
|
|
4
5
|
import ModalHeader from "./modal-header";
|
|
@@ -8,15 +9,15 @@ type Props = {
|
|
|
8
9
|
* The main contents of the ModalPanel. All other parts of the panel
|
|
9
10
|
* are positioned around it.
|
|
10
11
|
*/
|
|
11
|
-
content: React.ReactElement<
|
|
12
|
+
content: React.ReactElement<PropsFor<typeof ModalContent>> | React.ReactNode;
|
|
12
13
|
/**
|
|
13
14
|
* The modal header to show at the top of the panel.
|
|
14
15
|
*/
|
|
15
|
-
header?: React.ReactElement<
|
|
16
|
+
header?: React.ReactElement<PropsFor<typeof ModalHeader>> | React.ReactNode;
|
|
16
17
|
/**
|
|
17
18
|
* A footer to show beneath the contents.
|
|
18
19
|
*/
|
|
19
|
-
footer?: React.ReactElement<
|
|
20
|
+
footer?: React.ReactElement<PropsFor<typeof ModalFooter>> | React.ReactNode;
|
|
20
21
|
/**
|
|
21
22
|
* When true, the close button is shown; otherwise, the close button is not shown.
|
|
22
23
|
*/
|
|
@@ -51,13 +52,8 @@ type Props = {
|
|
|
51
52
|
*/
|
|
52
53
|
testId?: string;
|
|
53
54
|
};
|
|
54
|
-
type DefaultProps = {
|
|
55
|
-
closeButtonVisible: Props["closeButtonVisible"];
|
|
56
|
-
scrollOverflow: Props["scrollOverflow"];
|
|
57
|
-
light: Props["light"];
|
|
58
|
-
};
|
|
59
55
|
/**
|
|
60
|
-
* ModalPanel is
|
|
56
|
+
* ModalPanel is the content container.
|
|
61
57
|
*
|
|
62
58
|
* **Implementation notes:**
|
|
63
59
|
*
|
|
@@ -76,9 +72,12 @@ type DefaultProps = {
|
|
|
76
72
|
* </ModalDialog>
|
|
77
73
|
* ```
|
|
78
74
|
*/
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
75
|
+
declare function ModalPanel({ closeButtonVisible, scrollOverflow, light, content, footer, header, onClose, style, testId, }: Props): JSX.Element;
|
|
76
|
+
declare namespace ModalPanel {
|
|
77
|
+
var defaultProps: {
|
|
78
|
+
closeButtonVisible: boolean;
|
|
79
|
+
scrollOverflow: boolean;
|
|
80
|
+
light: boolean;
|
|
81
|
+
};
|
|
83
82
|
}
|
|
84
|
-
export
|
|
83
|
+
export default ModalPanel;
|
package/dist/es/index.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { View, IDProvider } from '@khanacademy/wonder-blocks-core';
|
|
3
|
-
import { tokens, createThemeContext, ThemeSwitcherContext, useScopedTheme, useStyles } from '@khanacademy/wonder-blocks-theming';
|
|
3
|
+
import { tokens, mergeTheme, createThemeContext, ThemeSwitcherContext, useScopedTheme, useStyles } from '@khanacademy/wonder-blocks-theming';
|
|
4
4
|
import { StyleSheet } from 'aphrodite';
|
|
5
5
|
import Color from '@khanacademy/wonder-blocks-color';
|
|
6
6
|
import Spacing from '@khanacademy/wonder-blocks-spacing';
|
|
7
|
-
import { MediaLayout } from '@khanacademy/wonder-blocks-layout';
|
|
8
7
|
import { HeadingMedium, LabelSmall } from '@khanacademy/wonder-blocks-typography';
|
|
9
8
|
import * as ReactDOM from 'react-dom';
|
|
10
9
|
import { withActionScheduler } from '@khanacademy/wonder-blocks-timing';
|
|
11
10
|
import xIcon from '@phosphor-icons/core/regular/x.svg';
|
|
12
11
|
import IconButton from '@khanacademy/wonder-blocks-icon-button';
|
|
12
|
+
import { MediaLayout } from '@khanacademy/wonder-blocks-layout';
|
|
13
13
|
|
|
14
14
|
function _extends() {
|
|
15
15
|
_extends = Object.assign ? Object.assign.bind() : function (target) {
|
|
@@ -26,26 +26,57 @@ function _extends() {
|
|
|
26
26
|
return _extends.apply(this, arguments);
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
const theme = {
|
|
29
|
+
const theme$1 = {
|
|
30
|
+
color: {
|
|
31
|
+
bg: {
|
|
32
|
+
inverse: tokens.color.darkBlue
|
|
33
|
+
},
|
|
34
|
+
text: {
|
|
35
|
+
inverse: tokens.color.white,
|
|
36
|
+
secondary: tokens.color.offBlack64
|
|
37
|
+
},
|
|
38
|
+
shadow: {
|
|
39
|
+
default: tokens.color.offBlack16
|
|
40
|
+
}
|
|
41
|
+
},
|
|
30
42
|
border: {
|
|
31
43
|
radius: tokens.border.radius.medium_4
|
|
32
44
|
},
|
|
33
45
|
spacing: {
|
|
34
46
|
dialog: {
|
|
35
47
|
small: tokens.spacing.medium_16
|
|
48
|
+
},
|
|
49
|
+
panel: {
|
|
50
|
+
closeButton: tokens.spacing.medium_16,
|
|
51
|
+
footer: tokens.spacing.xLarge_32
|
|
52
|
+
},
|
|
53
|
+
header: {
|
|
54
|
+
xsmall: tokens.spacing.xSmall_8,
|
|
55
|
+
small: tokens.spacing.medium_16,
|
|
56
|
+
medium: tokens.spacing.large_24,
|
|
57
|
+
large: tokens.spacing.xLarge_32
|
|
36
58
|
}
|
|
37
59
|
}
|
|
38
60
|
};
|
|
39
61
|
|
|
62
|
+
const theme = mergeTheme(theme$1, {
|
|
63
|
+
color: {
|
|
64
|
+
bg: {
|
|
65
|
+
inverse: tokens.color.eggplant
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
|
|
40
70
|
const themes = {
|
|
41
|
-
default: theme
|
|
71
|
+
default: theme$1,
|
|
72
|
+
khanmigo: theme
|
|
42
73
|
};
|
|
43
|
-
const ModalDialogThemeContext = createThemeContext(theme);
|
|
74
|
+
const ModalDialogThemeContext = createThemeContext(theme$1);
|
|
44
75
|
function ThemeModalDialog(props) {
|
|
45
76
|
const currentTheme = React.useContext(ThemeSwitcherContext);
|
|
46
|
-
const theme
|
|
77
|
+
const theme = themes[currentTheme] || theme$1;
|
|
47
78
|
return React.createElement(ModalDialogThemeContext.Provider, {
|
|
48
|
-
value: theme
|
|
79
|
+
value: theme
|
|
49
80
|
}, props.children);
|
|
50
81
|
}
|
|
51
82
|
|
|
@@ -63,7 +94,7 @@ const ModalDialogCore = React.forwardRef(function ModalDialogCore(props, ref) {
|
|
|
63
94
|
const {
|
|
64
95
|
theme
|
|
65
96
|
} = useScopedTheme(ModalDialogThemeContext);
|
|
66
|
-
const styles = useStyles(themedStylesFn, theme);
|
|
97
|
+
const styles = useStyles(themedStylesFn$3, theme);
|
|
67
98
|
return React.createElement(View, {
|
|
68
99
|
style: [styles.wrapper, style]
|
|
69
100
|
}, below && React.createElement(View, {
|
|
@@ -85,8 +116,8 @@ const ModalDialog = React.forwardRef(function ModalDialog(props, ref) {
|
|
|
85
116
|
ref: ref
|
|
86
117
|
})));
|
|
87
118
|
});
|
|
88
|
-
const small = "@media (max-width: 767px)";
|
|
89
|
-
const themedStylesFn = theme => ({
|
|
119
|
+
const small$2 = "@media (max-width: 767px)";
|
|
120
|
+
const themedStylesFn$3 = theme => ({
|
|
90
121
|
wrapper: {
|
|
91
122
|
display: "flex",
|
|
92
123
|
flexDirection: "row",
|
|
@@ -94,7 +125,7 @@ const themedStylesFn = theme => ({
|
|
|
94
125
|
width: "100%",
|
|
95
126
|
height: "100%",
|
|
96
127
|
position: "relative",
|
|
97
|
-
[small]: {
|
|
128
|
+
[small$2]: {
|
|
98
129
|
padding: theme.spacing.dialog.small,
|
|
99
130
|
flexDirection: "column"
|
|
100
131
|
}
|
|
@@ -126,21 +157,18 @@ const themedStylesFn = theme => ({
|
|
|
126
157
|
});
|
|
127
158
|
ModalDialog.displayName = "ModalDialog";
|
|
128
159
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
children
|
|
136
|
-
} = this.props;
|
|
137
|
-
return React.createElement(View, {
|
|
138
|
-
style: styles$3.footer
|
|
139
|
-
}, children);
|
|
140
|
-
}
|
|
160
|
+
function ModalFooter({
|
|
161
|
+
children
|
|
162
|
+
}) {
|
|
163
|
+
return React.createElement(View, {
|
|
164
|
+
style: styles$2.footer
|
|
165
|
+
}, children);
|
|
141
166
|
}
|
|
142
167
|
ModalFooter.__IS_MODAL_FOOTER__ = true;
|
|
143
|
-
|
|
168
|
+
ModalFooter.isComponentOf = instance => {
|
|
169
|
+
return instance && instance.type && instance.type.__IS_MODAL_FOOTER__;
|
|
170
|
+
};
|
|
171
|
+
const styles$2 = StyleSheet.create({
|
|
144
172
|
footer: {
|
|
145
173
|
flex: "0 0 auto",
|
|
146
174
|
boxSizing: "border-box",
|
|
@@ -157,77 +185,72 @@ const styles$3 = StyleSheet.create({
|
|
|
157
185
|
}
|
|
158
186
|
});
|
|
159
187
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
throw new Error("'subtitle' and 'breadcrumbs' can't be used together");
|
|
172
|
-
}
|
|
173
|
-
return React.createElement(MediaLayout, {
|
|
174
|
-
styleSheets: styleSheets$2
|
|
175
|
-
}, ({
|
|
176
|
-
styles
|
|
177
|
-
}) => React.createElement(View, {
|
|
178
|
-
style: [styles.header, !light && styles.dark],
|
|
179
|
-
testId: testId
|
|
180
|
-
}, breadcrumbs && React.createElement(View, {
|
|
181
|
-
style: styles.breadcrumbs
|
|
182
|
-
}, breadcrumbs), React.createElement(HeadingMedium, {
|
|
183
|
-
style: styles.title,
|
|
184
|
-
id: titleId,
|
|
185
|
-
testId: testId && `${testId}-title`
|
|
186
|
-
}, title), subtitle && React.createElement(LabelSmall, {
|
|
187
|
-
style: light && styles.subtitle,
|
|
188
|
-
testId: testId && `${testId}-subtitle`
|
|
189
|
-
}, subtitle)));
|
|
188
|
+
function ModalHeader(props) {
|
|
189
|
+
const {
|
|
190
|
+
breadcrumbs = undefined,
|
|
191
|
+
light,
|
|
192
|
+
subtitle = undefined,
|
|
193
|
+
testId,
|
|
194
|
+
title,
|
|
195
|
+
titleId
|
|
196
|
+
} = props;
|
|
197
|
+
if (subtitle && breadcrumbs) {
|
|
198
|
+
throw new Error("'subtitle' and 'breadcrumbs' can't be used together");
|
|
190
199
|
}
|
|
200
|
+
const {
|
|
201
|
+
theme
|
|
202
|
+
} = useScopedTheme(ModalDialogThemeContext);
|
|
203
|
+
const styles = useStyles(themedStylesFn$2, theme);
|
|
204
|
+
return React.createElement(View, {
|
|
205
|
+
style: [styles.header, !light && styles.dark],
|
|
206
|
+
testId: testId
|
|
207
|
+
}, breadcrumbs && React.createElement(View, {
|
|
208
|
+
style: styles.breadcrumbs
|
|
209
|
+
}, breadcrumbs), React.createElement(HeadingMedium, {
|
|
210
|
+
style: styles.title,
|
|
211
|
+
id: titleId,
|
|
212
|
+
testId: testId && `${testId}-title`
|
|
213
|
+
}, title), subtitle && React.createElement(LabelSmall, {
|
|
214
|
+
style: light && styles.subtitle,
|
|
215
|
+
testId: testId && `${testId}-subtitle`
|
|
216
|
+
}, subtitle));
|
|
191
217
|
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
},
|
|
206
|
-
dark: {
|
|
207
|
-
background: Color.darkBlue,
|
|
208
|
-
color: Color.white
|
|
209
|
-
},
|
|
210
|
-
breadcrumbs: {
|
|
211
|
-
color: Color.offBlack64,
|
|
212
|
-
marginBottom: Spacing.xSmall_8
|
|
213
|
-
},
|
|
214
|
-
title: {
|
|
215
|
-
paddingRight: Spacing.medium_16
|
|
216
|
-
},
|
|
217
|
-
subtitle: {
|
|
218
|
-
color: Color.offBlack64,
|
|
219
|
-
marginTop: Spacing.xSmall_8
|
|
218
|
+
const small$1 = "@media (max-width: 767px)";
|
|
219
|
+
const themedStylesFn$2 = theme => ({
|
|
220
|
+
header: {
|
|
221
|
+
boxShadow: `0px 1px 0px ${theme.color.shadow.default}`,
|
|
222
|
+
display: "flex",
|
|
223
|
+
flexDirection: "column",
|
|
224
|
+
minHeight: 66,
|
|
225
|
+
padding: `${theme.spacing.header.medium}px ${theme.spacing.header.large}px`,
|
|
226
|
+
position: "relative",
|
|
227
|
+
width: "100%",
|
|
228
|
+
[small$1]: {
|
|
229
|
+
paddingLeft: theme.spacing.header.small,
|
|
230
|
+
paddingRight: theme.spacing.header.small
|
|
220
231
|
}
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
232
|
+
},
|
|
233
|
+
dark: {
|
|
234
|
+
background: theme.color.bg.inverse,
|
|
235
|
+
color: theme.color.text.inverse
|
|
236
|
+
},
|
|
237
|
+
breadcrumbs: {
|
|
238
|
+
color: theme.color.text.secondary,
|
|
239
|
+
marginBottom: theme.spacing.header.xsmall
|
|
240
|
+
},
|
|
241
|
+
title: {
|
|
242
|
+
paddingRight: theme.spacing.header.small,
|
|
243
|
+
[small$1]: {
|
|
244
|
+
paddingRight: theme.spacing.header.large
|
|
229
245
|
}
|
|
230
|
-
}
|
|
246
|
+
},
|
|
247
|
+
subtitle: {
|
|
248
|
+
color: theme.color.text.secondary,
|
|
249
|
+
marginTop: theme.spacing.header.xsmall
|
|
250
|
+
}
|
|
251
|
+
});
|
|
252
|
+
ModalHeader.defaultProps = {
|
|
253
|
+
light: true
|
|
231
254
|
};
|
|
232
255
|
|
|
233
256
|
const FOCUSABLE_ELEMENTS$1 = 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])';
|
|
@@ -353,14 +376,14 @@ class ModalBackdrop extends React.Component {
|
|
|
353
376
|
[ModalLauncherPortalAttributeName]: true
|
|
354
377
|
};
|
|
355
378
|
return React.createElement(View, _extends({
|
|
356
|
-
style: styles$
|
|
379
|
+
style: styles$1.modalPositioner,
|
|
357
380
|
onMouseDown: this.handleMouseDown,
|
|
358
381
|
onMouseUp: this.handleMouseUp,
|
|
359
382
|
testId: testId
|
|
360
383
|
}, backdropProps), children);
|
|
361
384
|
}
|
|
362
385
|
}
|
|
363
|
-
const styles$
|
|
386
|
+
const styles$1 = StyleSheet.create({
|
|
364
387
|
modalPositioner: {
|
|
365
388
|
position: "fixed",
|
|
366
389
|
left: 0,
|
|
@@ -531,7 +554,7 @@ class ModalLauncher extends React.Component {
|
|
|
531
554
|
closeModal: this.handleCloseModal
|
|
532
555
|
}
|
|
533
556
|
}, renderedChildren, this.state.opened && ReactDOM.createPortal(React.createElement(FocusTrap, {
|
|
534
|
-
style: styles
|
|
557
|
+
style: styles.container
|
|
535
558
|
}, React.createElement(ModalBackdrop, {
|
|
536
559
|
initialFocusId: this.props.initialFocusId,
|
|
537
560
|
testId: this.props.testId,
|
|
@@ -565,59 +588,54 @@ class ModalLauncherKeypressListener extends React.Component {
|
|
|
565
588
|
return null;
|
|
566
589
|
}
|
|
567
590
|
}
|
|
568
|
-
const styles
|
|
591
|
+
const styles = StyleSheet.create({
|
|
569
592
|
container: {
|
|
570
593
|
zIndex: 1080
|
|
571
594
|
}
|
|
572
595
|
});
|
|
573
596
|
var modalLauncher = withActionScheduler(ModalLauncher);
|
|
574
597
|
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
style: [styles.wrapper, scrollOverflow && styles.scrollOverflow]
|
|
591
|
-
}, React.createElement(View, {
|
|
592
|
-
style: [styles.content, style]
|
|
593
|
-
}, children)));
|
|
594
|
-
}
|
|
598
|
+
function ModalContent(props) {
|
|
599
|
+
const {
|
|
600
|
+
scrollOverflow,
|
|
601
|
+
style,
|
|
602
|
+
children
|
|
603
|
+
} = props;
|
|
604
|
+
const {
|
|
605
|
+
theme
|
|
606
|
+
} = useScopedTheme(ModalDialogThemeContext);
|
|
607
|
+
const styles = useStyles(themedStylesFn$1, theme);
|
|
608
|
+
return React.createElement(View, {
|
|
609
|
+
style: [styles.wrapper, scrollOverflow && styles.scrollOverflow]
|
|
610
|
+
}, React.createElement(View, {
|
|
611
|
+
style: [styles.content, style]
|
|
612
|
+
}, children));
|
|
595
613
|
}
|
|
596
|
-
ModalContent.defaultProps = {
|
|
597
|
-
scrollOverflow: true
|
|
598
|
-
};
|
|
599
614
|
ModalContent.__IS_MODAL_CONTENT__ = true;
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
615
|
+
ModalContent.isComponentOf = instance => {
|
|
616
|
+
return instance && instance.type && instance.type.__IS_MODAL_CONTENT__;
|
|
617
|
+
};
|
|
618
|
+
const small = "@media (max-width: 767px)";
|
|
619
|
+
const themedStylesFn$1 = theme => ({
|
|
620
|
+
wrapper: {
|
|
621
|
+
flex: 1,
|
|
622
|
+
display: "block"
|
|
623
|
+
},
|
|
624
|
+
scrollOverflow: {
|
|
625
|
+
overflow: "auto"
|
|
626
|
+
},
|
|
627
|
+
content: {
|
|
628
|
+
flex: 1,
|
|
629
|
+
minHeight: "100%",
|
|
630
|
+
padding: Spacing.xLarge_32,
|
|
631
|
+
boxSizing: "border-box",
|
|
632
|
+
[small]: {
|
|
618
633
|
padding: `${Spacing.xLarge_32}px ${Spacing.medium_16}px`
|
|
619
634
|
}
|
|
620
|
-
}
|
|
635
|
+
}
|
|
636
|
+
});
|
|
637
|
+
ModalContent.defaultProps = {
|
|
638
|
+
scrollOverflow: true
|
|
621
639
|
};
|
|
622
640
|
|
|
623
641
|
class CloseButton extends React.Component {
|
|
@@ -647,14 +665,23 @@ class CloseButton extends React.Component {
|
|
|
647
665
|
}
|
|
648
666
|
}
|
|
649
667
|
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
668
|
+
function ModalPanel({
|
|
669
|
+
closeButtonVisible = true,
|
|
670
|
+
scrollOverflow = true,
|
|
671
|
+
light = true,
|
|
672
|
+
content,
|
|
673
|
+
footer,
|
|
674
|
+
header,
|
|
675
|
+
onClose,
|
|
676
|
+
style,
|
|
677
|
+
testId
|
|
678
|
+
}) {
|
|
679
|
+
const {
|
|
680
|
+
theme
|
|
681
|
+
} = useScopedTheme(ModalDialogThemeContext);
|
|
682
|
+
const styles = useStyles(themedStylesFn, theme);
|
|
683
|
+
const renderMainContent = React.useCallback(() => {
|
|
684
|
+
const mainContent = ModalContent.isComponentOf(content) ? content : React.createElement(ModalContent, null, content);
|
|
658
685
|
if (!mainContent) {
|
|
659
686
|
return mainContent;
|
|
660
687
|
}
|
|
@@ -662,35 +689,24 @@ class ModalPanel extends React.Component {
|
|
|
662
689
|
scrollOverflow,
|
|
663
690
|
style: [!!footer && styles.hasFooter, mainContent.props.style]
|
|
664
691
|
});
|
|
665
|
-
}
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
const mainContent = this.renderMainContent();
|
|
677
|
-
return React.createElement(View, {
|
|
678
|
-
style: [styles.wrapper, !light && styles.dark, style],
|
|
679
|
-
testId: testId && `${testId}-panel`
|
|
680
|
-
}, closeButtonVisible && React.createElement(CloseButton, {
|
|
681
|
-
light: !light,
|
|
682
|
-
onClick: onClose,
|
|
683
|
-
style: styles.closeButton,
|
|
684
|
-
testId: testId && `${testId}-close`
|
|
685
|
-
}), header, mainContent, !footer || ModalFooter.isClassOf(footer) ? footer : React.createElement(ModalFooter, null, footer));
|
|
686
|
-
}
|
|
692
|
+
}, [content, footer, scrollOverflow, styles.hasFooter]);
|
|
693
|
+
const mainContent = renderMainContent();
|
|
694
|
+
return React.createElement(View, {
|
|
695
|
+
style: [styles.wrapper, !light && styles.dark, style],
|
|
696
|
+
testId: testId && `${testId}-panel`
|
|
697
|
+
}, closeButtonVisible && React.createElement(CloseButton, {
|
|
698
|
+
light: !light,
|
|
699
|
+
onClick: onClose,
|
|
700
|
+
style: styles.closeButton,
|
|
701
|
+
testId: testId && `${testId}-close`
|
|
702
|
+
}), header, mainContent, !footer || ModalFooter.isComponentOf(footer) ? footer : React.createElement(ModalFooter, null, footer));
|
|
687
703
|
}
|
|
688
704
|
ModalPanel.defaultProps = {
|
|
689
705
|
closeButtonVisible: true,
|
|
690
706
|
scrollOverflow: true,
|
|
691
707
|
light: true
|
|
692
708
|
};
|
|
693
|
-
const
|
|
709
|
+
const themedStylesFn = theme => ({
|
|
694
710
|
wrapper: {
|
|
695
711
|
flex: "1 1 auto",
|
|
696
712
|
position: "relative",
|
|
@@ -704,16 +720,16 @@ const styles = StyleSheet.create({
|
|
|
704
720
|
},
|
|
705
721
|
closeButton: {
|
|
706
722
|
position: "absolute",
|
|
707
|
-
right:
|
|
708
|
-
top:
|
|
723
|
+
right: theme.spacing.panel.closeButton,
|
|
724
|
+
top: theme.spacing.panel.closeButton,
|
|
709
725
|
zIndex: 1
|
|
710
726
|
},
|
|
711
727
|
dark: {
|
|
712
|
-
background:
|
|
713
|
-
color:
|
|
728
|
+
background: theme.color.bg.inverse,
|
|
729
|
+
color: theme.color.text.inverse
|
|
714
730
|
},
|
|
715
731
|
hasFooter: {
|
|
716
|
-
paddingBottom:
|
|
732
|
+
paddingBottom: theme.spacing.panel.footer
|
|
717
733
|
}
|
|
718
734
|
});
|
|
719
735
|
|