@instructure/ui-modal 10.11.1-snapshot-14 → 10.11.1-snapshot-17
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 +5 -2
- package/es/Modal/ModalHeader/props.js +2 -1
- package/es/Modal/ModalHeader/styles.js +5 -1
- package/es/Modal/index.js +101 -34
- package/es/Modal/styles.js +4 -0
- package/lib/Modal/ModalHeader/props.js +2 -1
- package/lib/Modal/ModalHeader/styles.js +5 -1
- package/lib/Modal/index.js +101 -34
- package/lib/Modal/styles.js +4 -0
- package/package.json +19 -19
- package/src/Modal/ModalHeader/props.ts +3 -1
- package/src/Modal/ModalHeader/styles.ts +2 -1
- package/src/Modal/README.md +1 -0
- package/src/Modal/index.tsx +81 -7
- package/src/Modal/props.ts +4 -1
- package/src/Modal/styles.ts +4 -0
- package/tsconfig.build.tsbuildinfo +1 -1
- package/types/Modal/ModalHeader/index.d.ts +2 -0
- package/types/Modal/ModalHeader/index.d.ts.map +1 -1
- package/types/Modal/ModalHeader/props.d.ts +1 -0
- package/types/Modal/ModalHeader/props.d.ts.map +1 -1
- package/types/Modal/ModalHeader/styles.d.ts.map +1 -1
- package/types/Modal/index.d.ts +6 -1
- package/types/Modal/index.d.ts.map +1 -1
- package/types/Modal/props.d.ts +2 -1
- package/types/Modal/props.d.ts.map +1 -1
- package/types/Modal/styles.d.ts.map +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,9 +3,12 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
-
## [10.11.1-snapshot-
|
|
6
|
+
## [10.11.1-snapshot-17](https://github.com/instructure/instructure-ui/compare/v10.11.0...v10.11.1-snapshot-17) (2025-02-21)
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* **ui-modal:** make Modal's header non-sticky with small window height ([db5c708](https://github.com/instructure/instructure-ui/commit/db5c7082ec4834793d83cf7d6f469c4fbaa83eed))
|
|
9
12
|
|
|
10
13
|
|
|
11
14
|
|
|
@@ -26,7 +26,8 @@ import PropTypes from 'prop-types';
|
|
|
26
26
|
const propTypes = {
|
|
27
27
|
children: PropTypes.node,
|
|
28
28
|
variant: PropTypes.oneOf(['default', 'inverse']),
|
|
29
|
-
spacing: PropTypes.oneOf(['default', 'compact'])
|
|
29
|
+
spacing: PropTypes.oneOf(['default', 'compact']),
|
|
30
|
+
smallViewPort: PropTypes.bool
|
|
30
31
|
};
|
|
31
32
|
const allowedProps = ['children', 'variant', 'spacing'];
|
|
32
33
|
export { propTypes, allowedProps };
|
|
@@ -34,7 +34,8 @@
|
|
|
34
34
|
*/
|
|
35
35
|
const generateStyle = (componentTheme, props, state) => {
|
|
36
36
|
const variant = props.variant,
|
|
37
|
-
spacing = props.spacing
|
|
37
|
+
spacing = props.spacing,
|
|
38
|
+
smallViewPort = props.smallViewPort;
|
|
38
39
|
const withCloseButton = state.withCloseButton;
|
|
39
40
|
const sizeVariants = {
|
|
40
41
|
default: {
|
|
@@ -63,6 +64,9 @@ const generateStyle = (componentTheme, props, state) => {
|
|
|
63
64
|
borderBottomWidth: '0.0625rem',
|
|
64
65
|
borderBottomStyle: 'solid',
|
|
65
66
|
borderBottomColor: componentTheme.borderColor,
|
|
67
|
+
...(smallViewPort ? {
|
|
68
|
+
position: 'relative'
|
|
69
|
+
} : {}),
|
|
66
70
|
...sizeVariants[spacing],
|
|
67
71
|
...inverseStyle
|
|
68
72
|
}
|
package/es/Modal/index.js
CHANGED
|
@@ -30,6 +30,7 @@ import { Children, Component, isValidElement } from 'react';
|
|
|
30
30
|
import { passthroughProps, safeCloneElement } from '@instructure/ui-react-utils';
|
|
31
31
|
import { createChainedFunction } from '@instructure/ui-utils';
|
|
32
32
|
import { testable } from '@instructure/ui-testable';
|
|
33
|
+
import { canUseDOM } from '@instructure/ui-dom-utils';
|
|
33
34
|
import { Transition } from '@instructure/ui-motion';
|
|
34
35
|
import { Portal } from '@instructure/ui-portal';
|
|
35
36
|
import { Dialog } from '@instructure/ui-dialog';
|
|
@@ -57,6 +58,11 @@ let Modal = (_dec = withStyle(generateStyle, generateComponentTheme), _dec2 = te
|
|
|
57
58
|
this.handleRef = el => {
|
|
58
59
|
this.ref = el;
|
|
59
60
|
};
|
|
61
|
+
this.updateHeight = () => {
|
|
62
|
+
this.setState({
|
|
63
|
+
windowHeight: window.innerHeight
|
|
64
|
+
});
|
|
65
|
+
};
|
|
60
66
|
this.handlePortalOpen = DOMNode => {
|
|
61
67
|
this.DOMNode = DOMNode;
|
|
62
68
|
};
|
|
@@ -71,14 +77,27 @@ let Modal = (_dec = withStyle(generateStyle, generateComponentTheme), _dec2 = te
|
|
|
71
77
|
this.props.contentRef(el);
|
|
72
78
|
}
|
|
73
79
|
};
|
|
80
|
+
this.getWindowHeightInRem = () => {
|
|
81
|
+
var _getComputedStyle;
|
|
82
|
+
if (!canUseDOM) {
|
|
83
|
+
return Infinity;
|
|
84
|
+
}
|
|
85
|
+
const rootFontSize = parseFloat(((_getComputedStyle = getComputedStyle(document.documentElement)) === null || _getComputedStyle === void 0 ? void 0 : _getComputedStyle.fontSize) || '16');
|
|
86
|
+
if (isNaN(rootFontSize) || rootFontSize <= 0) {
|
|
87
|
+
return Infinity;
|
|
88
|
+
}
|
|
89
|
+
return window.innerHeight / rootFontSize;
|
|
90
|
+
};
|
|
74
91
|
this.state = {
|
|
75
92
|
transitioning: false,
|
|
76
|
-
open: (_props$open = props.open) !== null && _props$open !== void 0 ? _props$open : false
|
|
93
|
+
open: (_props$open = props.open) !== null && _props$open !== void 0 ? _props$open : false,
|
|
94
|
+
windowHeight: 99999
|
|
77
95
|
};
|
|
78
96
|
}
|
|
79
97
|
componentDidMount() {
|
|
80
98
|
var _this$props$makeStyle, _this$props;
|
|
81
99
|
(_this$props$makeStyle = (_this$props = this.props).makeStyles) === null || _this$props$makeStyle === void 0 ? void 0 : _this$props$makeStyle.call(_this$props);
|
|
100
|
+
window.addEventListener('resize', this.updateHeight);
|
|
82
101
|
}
|
|
83
102
|
componentDidUpdate(prevProps) {
|
|
84
103
|
var _this$props$makeStyle2, _this$props2;
|
|
@@ -90,6 +109,9 @@ let Modal = (_dec = withStyle(generateStyle, generateComponentTheme), _dec2 = te
|
|
|
90
109
|
}
|
|
91
110
|
(_this$props$makeStyle2 = (_this$props2 = this.props).makeStyles) === null || _this$props$makeStyle2 === void 0 ? void 0 : _this$props$makeStyle2.call(_this$props2);
|
|
92
111
|
}
|
|
112
|
+
componentWillUnmount() {
|
|
113
|
+
window.removeEventListener('resize', this.updateHeight);
|
|
114
|
+
}
|
|
93
115
|
get defaultFocusElement() {
|
|
94
116
|
return this.props.defaultFocusElement;
|
|
95
117
|
}
|
|
@@ -111,31 +133,76 @@ let Modal = (_dec = withStyle(generateStyle, generateComponentTheme), _dec2 = te
|
|
|
111
133
|
children = _this$props3.children,
|
|
112
134
|
variant = _this$props3.variant,
|
|
113
135
|
overflow = _this$props3.overflow;
|
|
136
|
+
|
|
137
|
+
// header should be non-sticky for small viewport height (ca. 320px)
|
|
138
|
+
if (this.getWindowHeightInRem() <= 20) {
|
|
139
|
+
return this.renderForSmallViewportHeight();
|
|
140
|
+
}
|
|
114
141
|
return Children.map(children, child => {
|
|
115
142
|
if (!child) return; // ignore null, falsy children
|
|
143
|
+
return this.cloneChildWithProps(child, variant, overflow);
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
renderForSmallViewportHeight() {
|
|
147
|
+
const _this$props4 = this.props,
|
|
148
|
+
children = _this$props4.children,
|
|
149
|
+
variant = _this$props4.variant,
|
|
150
|
+
overflow = _this$props4.overflow,
|
|
151
|
+
styles = _this$props4.styles;
|
|
152
|
+
const headerAndBody = [];
|
|
153
|
+
const childrenArray = Children.toArray(children);
|
|
116
154
|
|
|
155
|
+
// Separate header and body elements
|
|
156
|
+
const filteredChildren = childrenArray.filter(child => {
|
|
117
157
|
if (/*#__PURE__*/isValidElement(child)) {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
158
|
+
if (child.type === Modal.Header || child.type === Modal.Body) {
|
|
159
|
+
if (child.type === Modal.Header) {
|
|
160
|
+
const headerWithProp = safeCloneElement(child, {
|
|
161
|
+
smallViewPort: true
|
|
162
|
+
});
|
|
163
|
+
headerAndBody.push(headerWithProp);
|
|
164
|
+
} else {
|
|
165
|
+
headerAndBody.push(child);
|
|
166
|
+
}
|
|
167
|
+
return false;
|
|
168
|
+
}
|
|
125
169
|
}
|
|
170
|
+
return true;
|
|
126
171
|
});
|
|
172
|
+
|
|
173
|
+
// Adds the <div> to the beginning of the filteredChildren array
|
|
174
|
+
if (headerAndBody.length > 0) {
|
|
175
|
+
filteredChildren.unshift(jsx("div", {
|
|
176
|
+
css: styles === null || styles === void 0 ? void 0 : styles.joinedHeaderAndBody
|
|
177
|
+
}, headerAndBody));
|
|
178
|
+
}
|
|
179
|
+
return Children.map(filteredChildren, child => {
|
|
180
|
+
if (!child) return; // ignore null, falsy children
|
|
181
|
+
return this.cloneChildWithProps(child, variant, overflow);
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
cloneChildWithProps(child, variant, overflow) {
|
|
185
|
+
if (/*#__PURE__*/isValidElement(child)) {
|
|
186
|
+
var _child$props;
|
|
187
|
+
return safeCloneElement(child, {
|
|
188
|
+
variant: variant,
|
|
189
|
+
overflow: (child === null || child === void 0 ? void 0 : (_child$props = child.props) === null || _child$props === void 0 ? void 0 : _child$props.overflow) || overflow
|
|
190
|
+
});
|
|
191
|
+
} else {
|
|
192
|
+
return child;
|
|
193
|
+
}
|
|
127
194
|
}
|
|
128
195
|
renderDialog(props) {
|
|
129
|
-
const _this$
|
|
130
|
-
onDismiss = _this$
|
|
131
|
-
label = _this$
|
|
132
|
-
shouldCloseOnDocumentClick = _this$
|
|
133
|
-
shouldReturnFocus = _this$
|
|
134
|
-
liveRegion = _this$
|
|
135
|
-
size = _this$
|
|
136
|
-
constrain = _this$
|
|
137
|
-
as = _this$
|
|
138
|
-
styles = _this$
|
|
196
|
+
const _this$props5 = this.props,
|
|
197
|
+
onDismiss = _this$props5.onDismiss,
|
|
198
|
+
label = _this$props5.label,
|
|
199
|
+
shouldCloseOnDocumentClick = _this$props5.shouldCloseOnDocumentClick,
|
|
200
|
+
shouldReturnFocus = _this$props5.shouldReturnFocus,
|
|
201
|
+
liveRegion = _this$props5.liveRegion,
|
|
202
|
+
size = _this$props5.size,
|
|
203
|
+
constrain = _this$props5.constrain,
|
|
204
|
+
as = _this$props5.as,
|
|
205
|
+
styles = _this$props5.styles;
|
|
139
206
|
const isFullScreen = size === 'fullscreen';
|
|
140
207
|
const dialog = jsx(Dialog, Object.assign({}, passthroughProps(props), {
|
|
141
208
|
as: as,
|
|
@@ -163,22 +230,22 @@ let Modal = (_dec = withStyle(generateStyle, generateComponentTheme), _dec2 = te
|
|
|
163
230
|
}
|
|
164
231
|
render() {
|
|
165
232
|
var _this$props$styles;
|
|
166
|
-
const _this$
|
|
167
|
-
open = _this$
|
|
168
|
-
onOpen = _this$
|
|
169
|
-
onClose = _this$
|
|
170
|
-
mountNode = _this$
|
|
171
|
-
insertAt = _this$
|
|
172
|
-
transition = _this$
|
|
173
|
-
onEnter = _this$
|
|
174
|
-
onEntering = _this$
|
|
175
|
-
onEntered = _this$
|
|
176
|
-
onExit = _this$
|
|
177
|
-
onExiting = _this$
|
|
178
|
-
onExited = _this$
|
|
179
|
-
constrain = _this$
|
|
180
|
-
overflow = _this$
|
|
181
|
-
passthroughProps = _objectWithoutProperties(_this$
|
|
233
|
+
const _this$props6 = this.props,
|
|
234
|
+
open = _this$props6.open,
|
|
235
|
+
onOpen = _this$props6.onOpen,
|
|
236
|
+
onClose = _this$props6.onClose,
|
|
237
|
+
mountNode = _this$props6.mountNode,
|
|
238
|
+
insertAt = _this$props6.insertAt,
|
|
239
|
+
transition = _this$props6.transition,
|
|
240
|
+
onEnter = _this$props6.onEnter,
|
|
241
|
+
onEntering = _this$props6.onEntering,
|
|
242
|
+
onEntered = _this$props6.onEntered,
|
|
243
|
+
onExit = _this$props6.onExit,
|
|
244
|
+
onExiting = _this$props6.onExiting,
|
|
245
|
+
onExited = _this$props6.onExited,
|
|
246
|
+
constrain = _this$props6.constrain,
|
|
247
|
+
overflow = _this$props6.overflow,
|
|
248
|
+
passthroughProps = _objectWithoutProperties(_this$props6, _excluded);
|
|
182
249
|
const portalIsOpen = this.state.open || this.state.transitioning;
|
|
183
250
|
return jsx(Portal, {
|
|
184
251
|
mountNode: mountNode,
|
package/es/Modal/styles.js
CHANGED
|
@@ -33,6 +33,7 @@ var _propTypes = _interopRequireDefault(require("prop-types"));
|
|
|
33
33
|
const propTypes = exports.propTypes = {
|
|
34
34
|
children: _propTypes.default.node,
|
|
35
35
|
variant: _propTypes.default.oneOf(['default', 'inverse']),
|
|
36
|
-
spacing: _propTypes.default.oneOf(['default', 'compact'])
|
|
36
|
+
spacing: _propTypes.default.oneOf(['default', 'compact']),
|
|
37
|
+
smallViewPort: _propTypes.default.bool
|
|
37
38
|
};
|
|
38
39
|
const allowedProps = exports.allowedProps = ['children', 'variant', 'spacing'];
|
|
@@ -40,7 +40,8 @@ exports.default = void 0;
|
|
|
40
40
|
*/
|
|
41
41
|
const generateStyle = (componentTheme, props, state) => {
|
|
42
42
|
const variant = props.variant,
|
|
43
|
-
spacing = props.spacing
|
|
43
|
+
spacing = props.spacing,
|
|
44
|
+
smallViewPort = props.smallViewPort;
|
|
44
45
|
const withCloseButton = state.withCloseButton;
|
|
45
46
|
const sizeVariants = {
|
|
46
47
|
default: {
|
|
@@ -69,6 +70,9 @@ const generateStyle = (componentTheme, props, state) => {
|
|
|
69
70
|
borderBottomWidth: '0.0625rem',
|
|
70
71
|
borderBottomStyle: 'solid',
|
|
71
72
|
borderBottomColor: componentTheme.borderColor,
|
|
73
|
+
...(smallViewPort ? {
|
|
74
|
+
position: 'relative'
|
|
75
|
+
} : {}),
|
|
72
76
|
...sizeVariants[spacing],
|
|
73
77
|
...inverseStyle
|
|
74
78
|
}
|
package/lib/Modal/index.js
CHANGED
|
@@ -30,6 +30,7 @@ var _passthroughProps = require("@instructure/ui-react-utils/lib/passthroughProp
|
|
|
30
30
|
var _safeCloneElement = require("@instructure/ui-react-utils/lib/safeCloneElement.js");
|
|
31
31
|
var _createChainedFunction = require("@instructure/ui-utils/lib/createChainedFunction.js");
|
|
32
32
|
var _testable = require("@instructure/ui-testable/lib/testable.js");
|
|
33
|
+
var _canUseDOM = require("@instructure/ui-dom-utils/lib/canUseDOM.js");
|
|
33
34
|
var _Transition = require("@instructure/ui-motion/lib/Transition");
|
|
34
35
|
var _Portal = require("@instructure/ui-portal/lib/Portal");
|
|
35
36
|
var _Dialog = require("@instructure/ui-dialog/lib/Dialog");
|
|
@@ -83,6 +84,11 @@ let Modal = exports.Modal = (_dec = (0, _emotion.withStyle)(_styles.default, _th
|
|
|
83
84
|
this.handleRef = el => {
|
|
84
85
|
this.ref = el;
|
|
85
86
|
};
|
|
87
|
+
this.updateHeight = () => {
|
|
88
|
+
this.setState({
|
|
89
|
+
windowHeight: window.innerHeight
|
|
90
|
+
});
|
|
91
|
+
};
|
|
86
92
|
this.handlePortalOpen = DOMNode => {
|
|
87
93
|
this.DOMNode = DOMNode;
|
|
88
94
|
};
|
|
@@ -97,14 +103,27 @@ let Modal = exports.Modal = (_dec = (0, _emotion.withStyle)(_styles.default, _th
|
|
|
97
103
|
this.props.contentRef(el);
|
|
98
104
|
}
|
|
99
105
|
};
|
|
106
|
+
this.getWindowHeightInRem = () => {
|
|
107
|
+
var _getComputedStyle;
|
|
108
|
+
if (!_canUseDOM.canUseDOM) {
|
|
109
|
+
return Infinity;
|
|
110
|
+
}
|
|
111
|
+
const rootFontSize = parseFloat(((_getComputedStyle = getComputedStyle(document.documentElement)) === null || _getComputedStyle === void 0 ? void 0 : _getComputedStyle.fontSize) || '16');
|
|
112
|
+
if (isNaN(rootFontSize) || rootFontSize <= 0) {
|
|
113
|
+
return Infinity;
|
|
114
|
+
}
|
|
115
|
+
return window.innerHeight / rootFontSize;
|
|
116
|
+
};
|
|
100
117
|
this.state = {
|
|
101
118
|
transitioning: false,
|
|
102
|
-
open: (_props$open = props.open) !== null && _props$open !== void 0 ? _props$open : false
|
|
119
|
+
open: (_props$open = props.open) !== null && _props$open !== void 0 ? _props$open : false,
|
|
120
|
+
windowHeight: 99999
|
|
103
121
|
};
|
|
104
122
|
}
|
|
105
123
|
componentDidMount() {
|
|
106
124
|
var _this$props$makeStyle, _this$props;
|
|
107
125
|
(_this$props$makeStyle = (_this$props = this.props).makeStyles) === null || _this$props$makeStyle === void 0 ? void 0 : _this$props$makeStyle.call(_this$props);
|
|
126
|
+
window.addEventListener('resize', this.updateHeight);
|
|
108
127
|
}
|
|
109
128
|
componentDidUpdate(prevProps) {
|
|
110
129
|
var _this$props$makeStyle2, _this$props2;
|
|
@@ -116,6 +135,9 @@ let Modal = exports.Modal = (_dec = (0, _emotion.withStyle)(_styles.default, _th
|
|
|
116
135
|
}
|
|
117
136
|
(_this$props$makeStyle2 = (_this$props2 = this.props).makeStyles) === null || _this$props$makeStyle2 === void 0 ? void 0 : _this$props$makeStyle2.call(_this$props2);
|
|
118
137
|
}
|
|
138
|
+
componentWillUnmount() {
|
|
139
|
+
window.removeEventListener('resize', this.updateHeight);
|
|
140
|
+
}
|
|
119
141
|
get defaultFocusElement() {
|
|
120
142
|
return this.props.defaultFocusElement;
|
|
121
143
|
}
|
|
@@ -137,31 +159,76 @@ let Modal = exports.Modal = (_dec = (0, _emotion.withStyle)(_styles.default, _th
|
|
|
137
159
|
children = _this$props3.children,
|
|
138
160
|
variant = _this$props3.variant,
|
|
139
161
|
overflow = _this$props3.overflow;
|
|
162
|
+
|
|
163
|
+
// header should be non-sticky for small viewport height (ca. 320px)
|
|
164
|
+
if (this.getWindowHeightInRem() <= 20) {
|
|
165
|
+
return this.renderForSmallViewportHeight();
|
|
166
|
+
}
|
|
140
167
|
return _react.Children.map(children, child => {
|
|
141
168
|
if (!child) return; // ignore null, falsy children
|
|
169
|
+
return this.cloneChildWithProps(child, variant, overflow);
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
renderForSmallViewportHeight() {
|
|
173
|
+
const _this$props4 = this.props,
|
|
174
|
+
children = _this$props4.children,
|
|
175
|
+
variant = _this$props4.variant,
|
|
176
|
+
overflow = _this$props4.overflow,
|
|
177
|
+
styles = _this$props4.styles;
|
|
178
|
+
const headerAndBody = [];
|
|
179
|
+
const childrenArray = _react.Children.toArray(children);
|
|
142
180
|
|
|
181
|
+
// Separate header and body elements
|
|
182
|
+
const filteredChildren = childrenArray.filter(child => {
|
|
143
183
|
if (/*#__PURE__*/(0, _react.isValidElement)(child)) {
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
184
|
+
if (child.type === Modal.Header || child.type === Modal.Body) {
|
|
185
|
+
if (child.type === Modal.Header) {
|
|
186
|
+
const headerWithProp = (0, _safeCloneElement.safeCloneElement)(child, {
|
|
187
|
+
smallViewPort: true
|
|
188
|
+
});
|
|
189
|
+
headerAndBody.push(headerWithProp);
|
|
190
|
+
} else {
|
|
191
|
+
headerAndBody.push(child);
|
|
192
|
+
}
|
|
193
|
+
return false;
|
|
194
|
+
}
|
|
151
195
|
}
|
|
196
|
+
return true;
|
|
152
197
|
});
|
|
198
|
+
|
|
199
|
+
// Adds the <div> to the beginning of the filteredChildren array
|
|
200
|
+
if (headerAndBody.length > 0) {
|
|
201
|
+
filteredChildren.unshift((0, _emotion.jsx)("div", {
|
|
202
|
+
css: styles === null || styles === void 0 ? void 0 : styles.joinedHeaderAndBody
|
|
203
|
+
}, headerAndBody));
|
|
204
|
+
}
|
|
205
|
+
return _react.Children.map(filteredChildren, child => {
|
|
206
|
+
if (!child) return; // ignore null, falsy children
|
|
207
|
+
return this.cloneChildWithProps(child, variant, overflow);
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
cloneChildWithProps(child, variant, overflow) {
|
|
211
|
+
if (/*#__PURE__*/(0, _react.isValidElement)(child)) {
|
|
212
|
+
var _child$props;
|
|
213
|
+
return (0, _safeCloneElement.safeCloneElement)(child, {
|
|
214
|
+
variant: variant,
|
|
215
|
+
overflow: (child === null || child === void 0 ? void 0 : (_child$props = child.props) === null || _child$props === void 0 ? void 0 : _child$props.overflow) || overflow
|
|
216
|
+
});
|
|
217
|
+
} else {
|
|
218
|
+
return child;
|
|
219
|
+
}
|
|
153
220
|
}
|
|
154
221
|
renderDialog(props) {
|
|
155
|
-
const _this$
|
|
156
|
-
onDismiss = _this$
|
|
157
|
-
label = _this$
|
|
158
|
-
shouldCloseOnDocumentClick = _this$
|
|
159
|
-
shouldReturnFocus = _this$
|
|
160
|
-
liveRegion = _this$
|
|
161
|
-
size = _this$
|
|
162
|
-
constrain = _this$
|
|
163
|
-
as = _this$
|
|
164
|
-
styles = _this$
|
|
222
|
+
const _this$props5 = this.props,
|
|
223
|
+
onDismiss = _this$props5.onDismiss,
|
|
224
|
+
label = _this$props5.label,
|
|
225
|
+
shouldCloseOnDocumentClick = _this$props5.shouldCloseOnDocumentClick,
|
|
226
|
+
shouldReturnFocus = _this$props5.shouldReturnFocus,
|
|
227
|
+
liveRegion = _this$props5.liveRegion,
|
|
228
|
+
size = _this$props5.size,
|
|
229
|
+
constrain = _this$props5.constrain,
|
|
230
|
+
as = _this$props5.as,
|
|
231
|
+
styles = _this$props5.styles;
|
|
165
232
|
const isFullScreen = size === 'fullscreen';
|
|
166
233
|
const dialog = (0, _emotion.jsx)(_Dialog.Dialog, Object.assign({}, (0, _passthroughProps.passthroughProps)(props), {
|
|
167
234
|
as: as,
|
|
@@ -189,22 +256,22 @@ let Modal = exports.Modal = (_dec = (0, _emotion.withStyle)(_styles.default, _th
|
|
|
189
256
|
}
|
|
190
257
|
render() {
|
|
191
258
|
var _this$props$styles;
|
|
192
|
-
const _this$
|
|
193
|
-
open = _this$
|
|
194
|
-
onOpen = _this$
|
|
195
|
-
onClose = _this$
|
|
196
|
-
mountNode = _this$
|
|
197
|
-
insertAt = _this$
|
|
198
|
-
transition = _this$
|
|
199
|
-
onEnter = _this$
|
|
200
|
-
onEntering = _this$
|
|
201
|
-
onEntered = _this$
|
|
202
|
-
onExit = _this$
|
|
203
|
-
onExiting = _this$
|
|
204
|
-
onExited = _this$
|
|
205
|
-
constrain = _this$
|
|
206
|
-
overflow = _this$
|
|
207
|
-
passthroughProps = (0, _objectWithoutProperties2.default)(_this$
|
|
259
|
+
const _this$props6 = this.props,
|
|
260
|
+
open = _this$props6.open,
|
|
261
|
+
onOpen = _this$props6.onOpen,
|
|
262
|
+
onClose = _this$props6.onClose,
|
|
263
|
+
mountNode = _this$props6.mountNode,
|
|
264
|
+
insertAt = _this$props6.insertAt,
|
|
265
|
+
transition = _this$props6.transition,
|
|
266
|
+
onEnter = _this$props6.onEnter,
|
|
267
|
+
onEntering = _this$props6.onEntering,
|
|
268
|
+
onEntered = _this$props6.onEntered,
|
|
269
|
+
onExit = _this$props6.onExit,
|
|
270
|
+
onExiting = _this$props6.onExiting,
|
|
271
|
+
onExited = _this$props6.onExited,
|
|
272
|
+
constrain = _this$props6.constrain,
|
|
273
|
+
overflow = _this$props6.overflow,
|
|
274
|
+
passthroughProps = (0, _objectWithoutProperties2.default)(_this$props6, _excluded);
|
|
208
275
|
const portalIsOpen = this.state.open || this.state.transitioning;
|
|
209
276
|
return (0, _emotion.jsx)(_Portal.Portal, {
|
|
210
277
|
mountNode: mountNode,
|
package/lib/Modal/styles.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@instructure/ui-modal",
|
|
3
|
-
"version": "10.11.1-snapshot-
|
|
3
|
+
"version": "10.11.1-snapshot-17",
|
|
4
4
|
"description": "A component for displaying content in a dialog overlay",
|
|
5
5
|
"author": "Instructure, Inc. Engineering and Product Design",
|
|
6
6
|
"module": "./es/index.js",
|
|
@@ -24,30 +24,30 @@
|
|
|
24
24
|
"license": "MIT",
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"@babel/runtime": "^7.26.0",
|
|
27
|
-
"@instructure/console": "10.11.1-snapshot-
|
|
28
|
-
"@instructure/emotion": "10.11.1-snapshot-
|
|
29
|
-
"@instructure/shared-types": "10.11.1-snapshot-
|
|
30
|
-
"@instructure/ui-buttons": "10.11.1-snapshot-
|
|
31
|
-
"@instructure/ui-dialog": "10.11.1-snapshot-
|
|
32
|
-
"@instructure/ui-dom-utils": "10.11.1-snapshot-
|
|
33
|
-
"@instructure/ui-motion": "10.11.1-snapshot-
|
|
34
|
-
"@instructure/ui-overlays": "10.11.1-snapshot-
|
|
35
|
-
"@instructure/ui-portal": "10.11.1-snapshot-
|
|
36
|
-
"@instructure/ui-prop-types": "10.11.1-snapshot-
|
|
37
|
-
"@instructure/ui-react-utils": "10.11.1-snapshot-
|
|
38
|
-
"@instructure/ui-testable": "10.11.1-snapshot-
|
|
39
|
-
"@instructure/ui-utils": "10.11.1-snapshot-
|
|
40
|
-
"@instructure/ui-view": "10.11.1-snapshot-
|
|
27
|
+
"@instructure/console": "10.11.1-snapshot-17",
|
|
28
|
+
"@instructure/emotion": "10.11.1-snapshot-17",
|
|
29
|
+
"@instructure/shared-types": "10.11.1-snapshot-17",
|
|
30
|
+
"@instructure/ui-buttons": "10.11.1-snapshot-17",
|
|
31
|
+
"@instructure/ui-dialog": "10.11.1-snapshot-17",
|
|
32
|
+
"@instructure/ui-dom-utils": "10.11.1-snapshot-17",
|
|
33
|
+
"@instructure/ui-motion": "10.11.1-snapshot-17",
|
|
34
|
+
"@instructure/ui-overlays": "10.11.1-snapshot-17",
|
|
35
|
+
"@instructure/ui-portal": "10.11.1-snapshot-17",
|
|
36
|
+
"@instructure/ui-prop-types": "10.11.1-snapshot-17",
|
|
37
|
+
"@instructure/ui-react-utils": "10.11.1-snapshot-17",
|
|
38
|
+
"@instructure/ui-testable": "10.11.1-snapshot-17",
|
|
39
|
+
"@instructure/ui-utils": "10.11.1-snapshot-17",
|
|
40
|
+
"@instructure/ui-view": "10.11.1-snapshot-17",
|
|
41
41
|
"prop-types": "^15.8.1"
|
|
42
42
|
},
|
|
43
43
|
"peerDependencies": {
|
|
44
44
|
"react": ">=16.14 <=18"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
|
-
"@instructure/ui-babel-preset": "10.11.1-snapshot-
|
|
48
|
-
"@instructure/ui-color-utils": "10.11.1-snapshot-
|
|
49
|
-
"@instructure/ui-position": "10.11.1-snapshot-
|
|
50
|
-
"@instructure/ui-themes": "10.11.1-snapshot-
|
|
47
|
+
"@instructure/ui-babel-preset": "10.11.1-snapshot-17",
|
|
48
|
+
"@instructure/ui-color-utils": "10.11.1-snapshot-17",
|
|
49
|
+
"@instructure/ui-position": "10.11.1-snapshot-17",
|
|
50
|
+
"@instructure/ui-themes": "10.11.1-snapshot-17",
|
|
51
51
|
"@testing-library/jest-dom": "^6.6.3",
|
|
52
52
|
"@testing-library/react": "^16.0.1",
|
|
53
53
|
"@testing-library/user-event": "^14.5.2",
|
|
@@ -36,6 +36,7 @@ type ModalHeaderOwnProps = {
|
|
|
36
36
|
children?: React.ReactNode
|
|
37
37
|
variant?: 'default' | 'inverse'
|
|
38
38
|
spacing?: 'default' | 'compact'
|
|
39
|
+
smallViewPort?: boolean
|
|
39
40
|
}
|
|
40
41
|
|
|
41
42
|
type ModalHeaderStyleProps = {
|
|
@@ -55,7 +56,8 @@ type ModalHeaderStyle = ComponentStyle<'modalHeader'>
|
|
|
55
56
|
const propTypes: PropValidators<PropKeys> = {
|
|
56
57
|
children: PropTypes.node,
|
|
57
58
|
variant: PropTypes.oneOf(['default', 'inverse']),
|
|
58
|
-
spacing: PropTypes.oneOf(['default', 'compact'])
|
|
59
|
+
spacing: PropTypes.oneOf(['default', 'compact']),
|
|
60
|
+
smallViewPort: PropTypes.bool
|
|
59
61
|
}
|
|
60
62
|
|
|
61
63
|
const allowedProps: AllowedPropKeys = ['children', 'variant', 'spacing']
|
|
@@ -44,7 +44,7 @@ const generateStyle = (
|
|
|
44
44
|
props: ModalHeaderProps,
|
|
45
45
|
state: ModalHeaderStyleProps
|
|
46
46
|
): ModalHeaderStyle => {
|
|
47
|
-
const { variant, spacing } = props
|
|
47
|
+
const { variant, spacing, smallViewPort } = props
|
|
48
48
|
const { withCloseButton } = state
|
|
49
49
|
|
|
50
50
|
const sizeVariants = {
|
|
@@ -83,6 +83,7 @@ const generateStyle = (
|
|
|
83
83
|
borderBottomWidth: '0.0625rem',
|
|
84
84
|
borderBottomStyle: 'solid',
|
|
85
85
|
borderBottomColor: componentTheme.borderColor,
|
|
86
|
+
...(smallViewPort ? { position: 'relative' } : {}),
|
|
86
87
|
...sizeVariants[spacing!],
|
|
87
88
|
...inverseStyle
|
|
88
89
|
}
|
package/src/Modal/README.md
CHANGED
|
@@ -1180,6 +1180,7 @@ type: embed
|
|
|
1180
1180
|
<Figure.Item>When a user closes a modal, focus must return to a logical place within the page. This is usually the element that triggered opening the modal</Figure.Item>
|
|
1181
1181
|
<Figure.Item>Modals should be able to be closed by clicking away, esc key and/or a close button</Figure.Item>
|
|
1182
1182
|
<Figure.Item>We recommend that modals begin with a heading (typically H2)</Figure.Item>
|
|
1183
|
+
<Figure.Item>The Modal's header currently becomes non-sticky when the window height is too small, improving navigation of the Modal.Body, e.g., at higher zoom levels</Figure.Item>
|
|
1183
1184
|
</Figure>
|
|
1184
1185
|
</Guidelines>
|
|
1185
1186
|
```
|