@telus-uds/components-web 1.6.0 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -2
- package/lib/Modal/Modal.js +5 -1
- package/lib/Modal/ModalContent.js +3 -1
- package/lib/PreviewCard/PreviewCard.js +5 -1
- package/lib/Spinner/Spinner.js +234 -0
- package/lib/Spinner/SpinnerContent.js +107 -0
- package/lib/Spinner/constants.js +14 -0
- package/lib/Spinner/index.js +13 -0
- package/lib/index.js +10 -1
- package/lib-module/Modal/Modal.js +5 -1
- package/lib-module/Modal/ModalContent.js +3 -1
- package/lib-module/PreviewCard/PreviewCard.js +5 -1
- package/lib-module/Spinner/Spinner.js +213 -0
- package/lib-module/Spinner/SpinnerContent.js +90 -0
- package/lib-module/Spinner/constants.js +4 -0
- package/lib-module/Spinner/index.js +2 -0
- package/lib-module/index.js +1 -0
- package/package.json +3 -3
- package/src/Modal/Modal.jsx +12 -2
- package/src/Modal/ModalContent.jsx +3 -0
- package/src/PreviewCard/PreviewCard.jsx +5 -1
- package/src/Spinner/Spinner.jsx +186 -0
- package/src/Spinner/SpinnerContent.jsx +76 -0
- package/src/Spinner/constants.js +4 -0
- package/src/Spinner/index.js +3 -0
- package/src/index.js +1 -0
- package/types/Spinner.d.ts +16 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,12 +1,34 @@
|
|
|
1
1
|
# Change Log - @telus-uds/components-web
|
|
2
2
|
|
|
3
|
-
This log was last generated on
|
|
3
|
+
This log was last generated on Thu, 20 Apr 2023 19:05:54 GMT and should not be manually modified.
|
|
4
4
|
|
|
5
5
|
<!-- Start content -->
|
|
6
6
|
|
|
7
|
+
## 1.7.0
|
|
8
|
+
|
|
9
|
+
Thu, 20 Apr 2023 19:05:54 GMT
|
|
10
|
+
|
|
11
|
+
### Minor changes
|
|
12
|
+
|
|
13
|
+
- web modal to accept children (srikanthkhari@gmail.com)
|
|
14
|
+
- Added Spinner (wlsdud194@hotmail.com)
|
|
15
|
+
- update snapshots (kyle.king2@telus.com)
|
|
16
|
+
- Bump @telus-uds/components-base to v1.36.0
|
|
17
|
+
- Bump @telus-uds/system-theme-tokens to v2.21.0
|
|
18
|
+
|
|
19
|
+
## 1.6.1
|
|
20
|
+
|
|
21
|
+
Wed, 19 Apr 2023 18:49:51 GMT
|
|
22
|
+
|
|
23
|
+
### Patches
|
|
24
|
+
|
|
25
|
+
- Update default token to Preview Card (carlos.jeronimo@telus.com)
|
|
26
|
+
- Bump @telus-uds/components-base to v1.35.0
|
|
27
|
+
- Bump @telus-uds/system-theme-tokens to v2.20.0
|
|
28
|
+
|
|
7
29
|
## 1.6.0
|
|
8
30
|
|
|
9
|
-
Wed, 19 Apr 2023 11:
|
|
31
|
+
Wed, 19 Apr 2023 11:32:31 GMT
|
|
10
32
|
|
|
11
33
|
### Minor changes
|
|
12
34
|
|
package/lib/Modal/Modal.js
CHANGED
|
@@ -19,6 +19,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
|
|
|
19
19
|
|
|
20
20
|
const Modal = _ref => {
|
|
21
21
|
let {
|
|
22
|
+
children,
|
|
22
23
|
isOpen,
|
|
23
24
|
onClose,
|
|
24
25
|
maxWidth,
|
|
@@ -40,6 +41,7 @@ const Modal = _ref => {
|
|
|
40
41
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_componentsBase.Modal, {
|
|
41
42
|
isOpen: isOpen,
|
|
42
43
|
onClose: onClose,
|
|
44
|
+
variant: variant,
|
|
43
45
|
maxWidth: maxWidth,
|
|
44
46
|
...nonContentProps,
|
|
45
47
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_ModalContent.default, {
|
|
@@ -55,12 +57,14 @@ const Modal = _ref => {
|
|
|
55
57
|
confirmButtonText: confirmButtonText,
|
|
56
58
|
confirmButtonVariant: confirmButtonVariant,
|
|
57
59
|
cancelButtonText: cancelButtonText,
|
|
58
|
-
cancelButtonType: cancelButtonType
|
|
60
|
+
cancelButtonType: cancelButtonType,
|
|
61
|
+
children: children
|
|
59
62
|
})
|
|
60
63
|
});
|
|
61
64
|
};
|
|
62
65
|
|
|
63
66
|
Modal.propTypes = {
|
|
67
|
+
children: _propTypes.default.node,
|
|
64
68
|
tokens: _propTypes.default.object,
|
|
65
69
|
variant: _propTypes.default.object,
|
|
66
70
|
|
|
@@ -92,6 +92,7 @@ const ModalContent = _ref4 => {
|
|
|
92
92
|
variant,
|
|
93
93
|
cancelButtonText,
|
|
94
94
|
cancelButtonType: CancelButton = _componentsBase.TextButton,
|
|
95
|
+
children,
|
|
95
96
|
onCancel
|
|
96
97
|
} = _ref4;
|
|
97
98
|
const {
|
|
@@ -152,7 +153,7 @@ const ModalContent = _ref4 => {
|
|
|
152
153
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_componentsBase.Typography, {
|
|
153
154
|
children: bodyText
|
|
154
155
|
})
|
|
155
|
-
}), (hasConfirmButton || hasCancelButton) && /*#__PURE__*/(0, _jsxRuntime.jsxs)(StyledFooter, { ...themeTokens,
|
|
156
|
+
}), children, (hasConfirmButton || hasCancelButton) && /*#__PURE__*/(0, _jsxRuntime.jsxs)(StyledFooter, { ...themeTokens,
|
|
156
157
|
hasBorder: isContentOverflowing,
|
|
157
158
|
viewport: viewport,
|
|
158
159
|
children: [hasConfirmButton && /*#__PURE__*/(0, _jsxRuntime.jsx)(_componentsBase.Button, {
|
|
@@ -189,6 +190,7 @@ ModalContent.propTypes = {
|
|
|
189
190
|
cancelButtonText: _propTypes.default.string,
|
|
190
191
|
cancelButtonType: _propTypes.default.elementType,
|
|
191
192
|
// TODO: figure out a way of passing an icon to the TextButton
|
|
193
|
+
children: _propTypes.default.node,
|
|
192
194
|
onCancel: _propTypes.default.func
|
|
193
195
|
};
|
|
194
196
|
var _default = ModalContent;
|
|
@@ -60,7 +60,11 @@ const FullBleedOffsetInner = /*#__PURE__*/_styledComponents.default.div.withConf
|
|
|
60
60
|
|
|
61
61
|
const defaultTokens = {
|
|
62
62
|
minWidth: 0,
|
|
63
|
-
shadow: null
|
|
63
|
+
shadow: null,
|
|
64
|
+
contentAlignItems: 'stretch',
|
|
65
|
+
contentJustifyContent: 'flex-start',
|
|
66
|
+
contentFlexGrow: 0,
|
|
67
|
+
contentFlexShrink: 0
|
|
64
68
|
};
|
|
65
69
|
/**
|
|
66
70
|
* Showcase and guide users to another page, with a preview containing title and a footer.
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
|
|
8
|
+
var _react = _interopRequireDefault(require("react"));
|
|
9
|
+
|
|
10
|
+
var _propTypes = _interopRequireDefault(require("prop-types"));
|
|
11
|
+
|
|
12
|
+
var _styledComponents = _interopRequireDefault(require("styled-components"));
|
|
13
|
+
|
|
14
|
+
var _componentsBase = require("@telus-uds/components-base");
|
|
15
|
+
|
|
16
|
+
var _SpinnerContent = _interopRequireDefault(require("./SpinnerContent"));
|
|
17
|
+
|
|
18
|
+
var _utils = require("../utils");
|
|
19
|
+
|
|
20
|
+
var _constants = require("./constants");
|
|
21
|
+
|
|
22
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
23
|
+
|
|
24
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
25
|
+
|
|
26
|
+
const [selectProps, selectedSystemPropTypes] = (0, _componentsBase.selectSystemProps)([_utils.htmlAttrs]);
|
|
27
|
+
|
|
28
|
+
const SpinnerContainer = /*#__PURE__*/_styledComponents.default.div.withConfig({
|
|
29
|
+
displayName: "Spinner__SpinnerContainer",
|
|
30
|
+
componentId: "components-web__sc-116rqck-0"
|
|
31
|
+
})(_ref => {
|
|
32
|
+
let {
|
|
33
|
+
inline,
|
|
34
|
+
fullScreen
|
|
35
|
+
} = _ref;
|
|
36
|
+
return {
|
|
37
|
+
position: 'relative',
|
|
38
|
+
...(inline && {
|
|
39
|
+
display: 'block',
|
|
40
|
+
...(0, _utils.media)().from('md').css({
|
|
41
|
+
display: 'inline-block'
|
|
42
|
+
})
|
|
43
|
+
}),
|
|
44
|
+
...(fullScreen && {
|
|
45
|
+
top: '50%',
|
|
46
|
+
transform: 'translateY(-50%)'
|
|
47
|
+
})
|
|
48
|
+
};
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
const ContentOverlay = /*#__PURE__*/_styledComponents.default.div.withConfig({
|
|
52
|
+
displayName: "Spinner__ContentOverlay",
|
|
53
|
+
componentId: "components-web__sc-116rqck-1"
|
|
54
|
+
})({
|
|
55
|
+
position: 'absolute',
|
|
56
|
+
width: '100%',
|
|
57
|
+
height: '100%',
|
|
58
|
+
zIndex: _constants.BACKDROP_Z_INDEX
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
const FullscreenOverlay = /*#__PURE__*/_styledComponents.default.div.withConfig({
|
|
62
|
+
displayName: "Spinner__FullscreenOverlay",
|
|
63
|
+
componentId: "components-web__sc-116rqck-2"
|
|
64
|
+
})(_ref2 => {
|
|
65
|
+
let {
|
|
66
|
+
fullScreenOverLayBackground
|
|
67
|
+
} = _ref2;
|
|
68
|
+
return {
|
|
69
|
+
position: 'fixed',
|
|
70
|
+
width: '100vw',
|
|
71
|
+
height: '100vh',
|
|
72
|
+
top: 0,
|
|
73
|
+
left: 0,
|
|
74
|
+
zIndex: _constants.BACKDROP_Z_INDEX,
|
|
75
|
+
backgroundColor: fullScreenOverLayBackground
|
|
76
|
+
};
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
const OpaqueContainer = /*#__PURE__*/_styledComponents.default.div.withConfig({
|
|
80
|
+
displayName: "Spinner__OpaqueContainer",
|
|
81
|
+
componentId: "components-web__sc-116rqck-3"
|
|
82
|
+
})({
|
|
83
|
+
opacity: _constants.BACKDROP_OPACITY
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
const recursiveMap = (children, fn) => _react.default.Children.map(children, child => {
|
|
87
|
+
if (! /*#__PURE__*/_react.default.isValidElement(child)) {
|
|
88
|
+
return child;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (child.props.children) {
|
|
92
|
+
return fn( /*#__PURE__*/_react.default.cloneElement(child, {
|
|
93
|
+
children: recursiveMap(child.props.children, fn)
|
|
94
|
+
}));
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return fn(child);
|
|
98
|
+
});
|
|
99
|
+
/**
|
|
100
|
+
* Loading indicator.
|
|
101
|
+
*/
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
const Spinner = _ref3 => {
|
|
105
|
+
let {
|
|
106
|
+
children,
|
|
107
|
+
fullScreen = false,
|
|
108
|
+
inline = false,
|
|
109
|
+
label,
|
|
110
|
+
show = false,
|
|
111
|
+
isStatic = false,
|
|
112
|
+
tokens,
|
|
113
|
+
variant = {},
|
|
114
|
+
...rest
|
|
115
|
+
} = _ref3;
|
|
116
|
+
const {
|
|
117
|
+
fullScreenOverLayBackground,
|
|
118
|
+
size,
|
|
119
|
+
thickness
|
|
120
|
+
} = (0, _componentsBase.useThemeTokens)('Spinner', tokens, variant);
|
|
121
|
+
const {
|
|
122
|
+
size: sizeVariant = 'large'
|
|
123
|
+
} = variant;
|
|
124
|
+
(0, _componentsBase.useScrollBlocking)([fullScreen, show]);
|
|
125
|
+
|
|
126
|
+
if (!show) {
|
|
127
|
+
return children ?? null;
|
|
128
|
+
} // Full screen spinner
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
if (fullScreen) {
|
|
132
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(FullscreenOverlay, {
|
|
133
|
+
fullScreenOverLayBackground: fullScreenOverLayBackground,
|
|
134
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(SpinnerContainer, {
|
|
135
|
+
inline: inline,
|
|
136
|
+
fullScreen: fullScreen,
|
|
137
|
+
"aria-live": "assertive",
|
|
138
|
+
...selectProps(rest),
|
|
139
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_SpinnerContent.default, {
|
|
140
|
+
label: label,
|
|
141
|
+
overlay: true,
|
|
142
|
+
size: size,
|
|
143
|
+
thickness: thickness,
|
|
144
|
+
sizeVariant: sizeVariant,
|
|
145
|
+
isStatic: isStatic
|
|
146
|
+
})
|
|
147
|
+
})
|
|
148
|
+
});
|
|
149
|
+
} // Overlay spinner
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
if (children) {
|
|
153
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(SpinnerContainer, {
|
|
154
|
+
inline: inline,
|
|
155
|
+
"aria-live": "assertive",
|
|
156
|
+
...selectProps(rest),
|
|
157
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_SpinnerContent.default, {
|
|
158
|
+
label: label,
|
|
159
|
+
overlay: true,
|
|
160
|
+
size: size,
|
|
161
|
+
thickness: thickness,
|
|
162
|
+
sizeVariant: sizeVariant,
|
|
163
|
+
isStatic: isStatic
|
|
164
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(ContentOverlay, {}), /*#__PURE__*/(0, _jsxRuntime.jsx)(OpaqueContainer, {
|
|
165
|
+
inert: "true",
|
|
166
|
+
children: recursiveMap(children, c => {
|
|
167
|
+
if (c) {
|
|
168
|
+
return /*#__PURE__*/_react.default.cloneElement(c, {
|
|
169
|
+
tabIndex: '-1',
|
|
170
|
+
'aria-hidden': 'true'
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return undefined;
|
|
175
|
+
})
|
|
176
|
+
})]
|
|
177
|
+
});
|
|
178
|
+
} // Standalone spinner
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(SpinnerContainer, { ...selectProps(rest),
|
|
182
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_SpinnerContent.default, {
|
|
183
|
+
label: label,
|
|
184
|
+
size: size,
|
|
185
|
+
thickness: thickness,
|
|
186
|
+
sizeVariant: sizeVariant,
|
|
187
|
+
isStatic: isStatic
|
|
188
|
+
})
|
|
189
|
+
});
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
Spinner.propTypes = { ...selectedSystemPropTypes,
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Content to be overlaid while the spinner is active. Can be text, any HTML element,
|
|
196
|
+
* or any component.
|
|
197
|
+
*/
|
|
198
|
+
children: _propTypes.default.node,
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Enables body locking.
|
|
202
|
+
*/
|
|
203
|
+
fullScreen: _propTypes.default.bool,
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Set the inline prop to true if the Spinner should only cover its children; if
|
|
207
|
+
* the Spinner should cover the full width of its parent regardless of the size of
|
|
208
|
+
* its children, inline should be set to false
|
|
209
|
+
*/
|
|
210
|
+
inline: _propTypes.default.bool,
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Communicates a message to assistive technology while visible. This same message
|
|
214
|
+
* will appear underneath the spinner when its `size` is `large`.
|
|
215
|
+
*/
|
|
216
|
+
label: _propTypes.default.string.isRequired,
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* The size of the spinner
|
|
220
|
+
*/
|
|
221
|
+
// size: PropTypes.oneOf(['large', 'small']),
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Whether or not to render the spinner.
|
|
225
|
+
*/
|
|
226
|
+
show: _propTypes.default.bool,
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* If true, it should render a static spinner
|
|
230
|
+
*/
|
|
231
|
+
isStatic: _propTypes.default.bool
|
|
232
|
+
};
|
|
233
|
+
var _default = Spinner;
|
|
234
|
+
exports.default = _default;
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
|
|
8
|
+
var _react = _interopRequireDefault(require("react"));
|
|
9
|
+
|
|
10
|
+
var _propTypes = _interopRequireDefault(require("prop-types"));
|
|
11
|
+
|
|
12
|
+
var _styledComponents = _interopRequireDefault(require("styled-components"));
|
|
13
|
+
|
|
14
|
+
var _componentsBase = require("@telus-uds/components-base");
|
|
15
|
+
|
|
16
|
+
var _utils = require("../utils");
|
|
17
|
+
|
|
18
|
+
var _constants = require("./constants");
|
|
19
|
+
|
|
20
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
21
|
+
|
|
22
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
23
|
+
|
|
24
|
+
const [selectProps, selectedSystemPropTypes] = (0, _componentsBase.selectSystemProps)([_utils.htmlAttrs]);
|
|
25
|
+
|
|
26
|
+
const Container = /*#__PURE__*/_styledComponents.default.div.withConfig({
|
|
27
|
+
displayName: "SpinnerContent__Container",
|
|
28
|
+
componentId: "components-web__sc-1c8bd8e-0"
|
|
29
|
+
})(_ref => {
|
|
30
|
+
let {
|
|
31
|
+
overlay
|
|
32
|
+
} = _ref;
|
|
33
|
+
return {
|
|
34
|
+
display: 'inline-flex',
|
|
35
|
+
flexDirection: 'column',
|
|
36
|
+
alignItems: 'center',
|
|
37
|
+
...(overlay && {
|
|
38
|
+
position: 'absolute',
|
|
39
|
+
top: '50%',
|
|
40
|
+
left: '50%',
|
|
41
|
+
transform: 'translate(-50%, -50%)',
|
|
42
|
+
zIndex: _constants.BACKDROP_Z_INDEX
|
|
43
|
+
})
|
|
44
|
+
};
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
const SpinnerContent = _ref2 => {
|
|
48
|
+
let {
|
|
49
|
+
label,
|
|
50
|
+
overlay = false,
|
|
51
|
+
sizeVariant,
|
|
52
|
+
size,
|
|
53
|
+
thickness,
|
|
54
|
+
isStatic,
|
|
55
|
+
...rest
|
|
56
|
+
} = _ref2;
|
|
57
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(Container, {
|
|
58
|
+
overlay: overlay,
|
|
59
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_componentsBase.StackView, {
|
|
60
|
+
space: 3,
|
|
61
|
+
tokens: {
|
|
62
|
+
alignItems: 'center'
|
|
63
|
+
},
|
|
64
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_componentsBase.ActivityIndicator, {
|
|
65
|
+
label: label,
|
|
66
|
+
tokens: {
|
|
67
|
+
size,
|
|
68
|
+
thickness
|
|
69
|
+
},
|
|
70
|
+
isStatic: isStatic,
|
|
71
|
+
...selectProps(rest)
|
|
72
|
+
}), sizeVariant === _constants.LARGE && /*#__PURE__*/(0, _jsxRuntime.jsx)(_componentsBase.Typography, {
|
|
73
|
+
children: label
|
|
74
|
+
})]
|
|
75
|
+
})
|
|
76
|
+
});
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
SpinnerContent.propTypes = { ...selectedSystemPropTypes,
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Communicates a message to assistive technology while visible. This same message will appear underneath the spinner when its `size` is `large`.
|
|
83
|
+
*/
|
|
84
|
+
label: _propTypes.default.string.isRequired,
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Whether the container has to have an overlay styling.
|
|
88
|
+
*/
|
|
89
|
+
overlay: _propTypes.default.bool,
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Size (width and height) of the spinner.
|
|
93
|
+
*/
|
|
94
|
+
size: _propTypes.default.number,
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* The size of the spinner
|
|
98
|
+
*/
|
|
99
|
+
sizeVariant: _propTypes.default.oneOf(['large', 'small']),
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* If true, it should render a static spinner
|
|
103
|
+
*/
|
|
104
|
+
isStatic: _propTypes.default.bool
|
|
105
|
+
};
|
|
106
|
+
var _default = SpinnerContent;
|
|
107
|
+
exports.default = _default;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.SMALL = exports.LARGE = exports.BACKDROP_Z_INDEX = exports.BACKDROP_OPACITY = void 0;
|
|
7
|
+
const BACKDROP_OPACITY = 0.06;
|
|
8
|
+
exports.BACKDROP_OPACITY = BACKDROP_OPACITY;
|
|
9
|
+
const BACKDROP_Z_INDEX = 1400;
|
|
10
|
+
exports.BACKDROP_Z_INDEX = BACKDROP_Z_INDEX;
|
|
11
|
+
const LARGE = 'large';
|
|
12
|
+
exports.LARGE = LARGE;
|
|
13
|
+
const SMALL = 'small';
|
|
14
|
+
exports.SMALL = SMALL;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
|
|
8
|
+
var _Spinner = _interopRequireDefault(require("./Spinner"));
|
|
9
|
+
|
|
10
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
11
|
+
|
|
12
|
+
var _default = _Spinner.default;
|
|
13
|
+
exports.default = _default;
|
package/lib/index.js
CHANGED
|
@@ -22,7 +22,8 @@ var _exportNames = {
|
|
|
22
22
|
Toast: true,
|
|
23
23
|
Table: true,
|
|
24
24
|
Image: true,
|
|
25
|
-
WaffleGrid: true
|
|
25
|
+
WaffleGrid: true,
|
|
26
|
+
Spinner: true
|
|
26
27
|
};
|
|
27
28
|
Object.defineProperty(exports, "Badge", {
|
|
28
29
|
enumerable: true,
|
|
@@ -114,6 +115,12 @@ Object.defineProperty(exports, "Span", {
|
|
|
114
115
|
return _Span.default;
|
|
115
116
|
}
|
|
116
117
|
});
|
|
118
|
+
Object.defineProperty(exports, "Spinner", {
|
|
119
|
+
enumerable: true,
|
|
120
|
+
get: function () {
|
|
121
|
+
return _Spinner.default;
|
|
122
|
+
}
|
|
123
|
+
});
|
|
117
124
|
Object.defineProperty(exports, "Table", {
|
|
118
125
|
enumerable: true,
|
|
119
126
|
get: function () {
|
|
@@ -177,6 +184,8 @@ var _Image = _interopRequireDefault(require("./Image"));
|
|
|
177
184
|
|
|
178
185
|
var _WaffleGrid = _interopRequireDefault(require("./WaffleGrid"));
|
|
179
186
|
|
|
187
|
+
var _Spinner = _interopRequireDefault(require("./Spinner"));
|
|
188
|
+
|
|
180
189
|
var _baseExports = require("./baseExports");
|
|
181
190
|
|
|
182
191
|
Object.keys(_baseExports).forEach(function (key) {
|
|
@@ -6,6 +6,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
6
6
|
|
|
7
7
|
const Modal = _ref => {
|
|
8
8
|
let {
|
|
9
|
+
children,
|
|
9
10
|
isOpen,
|
|
10
11
|
onClose,
|
|
11
12
|
maxWidth,
|
|
@@ -27,6 +28,7 @@ const Modal = _ref => {
|
|
|
27
28
|
return /*#__PURE__*/_jsx(BaseModal, {
|
|
28
29
|
isOpen: isOpen,
|
|
29
30
|
onClose: onClose,
|
|
31
|
+
variant: variant,
|
|
30
32
|
maxWidth: maxWidth,
|
|
31
33
|
...nonContentProps,
|
|
32
34
|
children: /*#__PURE__*/_jsx(ModalContent, {
|
|
@@ -42,12 +44,14 @@ const Modal = _ref => {
|
|
|
42
44
|
confirmButtonText: confirmButtonText,
|
|
43
45
|
confirmButtonVariant: confirmButtonVariant,
|
|
44
46
|
cancelButtonText: cancelButtonText,
|
|
45
|
-
cancelButtonType: cancelButtonType
|
|
47
|
+
cancelButtonType: cancelButtonType,
|
|
48
|
+
children: children
|
|
46
49
|
})
|
|
47
50
|
});
|
|
48
51
|
};
|
|
49
52
|
|
|
50
53
|
Modal.propTypes = {
|
|
54
|
+
children: PropTypes.node,
|
|
51
55
|
tokens: PropTypes.object,
|
|
52
56
|
variant: PropTypes.object,
|
|
53
57
|
|
|
@@ -72,6 +72,7 @@ const ModalContent = _ref4 => {
|
|
|
72
72
|
variant,
|
|
73
73
|
cancelButtonText,
|
|
74
74
|
cancelButtonType: CancelButton = TextButton,
|
|
75
|
+
children,
|
|
75
76
|
onCancel
|
|
76
77
|
} = _ref4;
|
|
77
78
|
const {
|
|
@@ -132,7 +133,7 @@ const ModalContent = _ref4 => {
|
|
|
132
133
|
children: /*#__PURE__*/_jsx(Typography, {
|
|
133
134
|
children: bodyText
|
|
134
135
|
})
|
|
135
|
-
}), (hasConfirmButton || hasCancelButton) && /*#__PURE__*/_jsxs(StyledFooter, { ...themeTokens,
|
|
136
|
+
}), children, (hasConfirmButton || hasCancelButton) && /*#__PURE__*/_jsxs(StyledFooter, { ...themeTokens,
|
|
136
137
|
hasBorder: isContentOverflowing,
|
|
137
138
|
viewport: viewport,
|
|
138
139
|
children: [hasConfirmButton && /*#__PURE__*/_jsx(Button, {
|
|
@@ -169,6 +170,7 @@ ModalContent.propTypes = {
|
|
|
169
170
|
cancelButtonText: PropTypes.string,
|
|
170
171
|
cancelButtonType: PropTypes.elementType,
|
|
171
172
|
// TODO: figure out a way of passing an icon to the TextButton
|
|
173
|
+
children: PropTypes.node,
|
|
172
174
|
onCancel: PropTypes.func
|
|
173
175
|
};
|
|
174
176
|
export default ModalContent;
|
|
@@ -39,7 +39,11 @@ const FullBleedOffsetInner = /*#__PURE__*/styled.div.withConfig({
|
|
|
39
39
|
});
|
|
40
40
|
const defaultTokens = {
|
|
41
41
|
minWidth: 0,
|
|
42
|
-
shadow: null
|
|
42
|
+
shadow: null,
|
|
43
|
+
contentAlignItems: 'stretch',
|
|
44
|
+
contentJustifyContent: 'flex-start',
|
|
45
|
+
contentFlexGrow: 0,
|
|
46
|
+
contentFlexShrink: 0
|
|
43
47
|
};
|
|
44
48
|
/**
|
|
45
49
|
* Showcase and guide users to another page, with a preview containing title and a footer.
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import styled from 'styled-components';
|
|
4
|
+
import { selectSystemProps, useScrollBlocking, useThemeTokens } from '@telus-uds/components-base';
|
|
5
|
+
import SpinnerContent from './SpinnerContent';
|
|
6
|
+
import { htmlAttrs, media } from '../utils';
|
|
7
|
+
import { BACKDROP_OPACITY, BACKDROP_Z_INDEX } from './constants';
|
|
8
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
9
|
+
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
10
|
+
const [selectProps, selectedSystemPropTypes] = selectSystemProps([htmlAttrs]);
|
|
11
|
+
const SpinnerContainer = /*#__PURE__*/styled.div.withConfig({
|
|
12
|
+
displayName: "Spinner__SpinnerContainer",
|
|
13
|
+
componentId: "components-web__sc-116rqck-0"
|
|
14
|
+
})(_ref => {
|
|
15
|
+
let {
|
|
16
|
+
inline,
|
|
17
|
+
fullScreen
|
|
18
|
+
} = _ref;
|
|
19
|
+
return {
|
|
20
|
+
position: 'relative',
|
|
21
|
+
...(inline && {
|
|
22
|
+
display: 'block',
|
|
23
|
+
...media().from('md').css({
|
|
24
|
+
display: 'inline-block'
|
|
25
|
+
})
|
|
26
|
+
}),
|
|
27
|
+
...(fullScreen && {
|
|
28
|
+
top: '50%',
|
|
29
|
+
transform: 'translateY(-50%)'
|
|
30
|
+
})
|
|
31
|
+
};
|
|
32
|
+
});
|
|
33
|
+
const ContentOverlay = /*#__PURE__*/styled.div.withConfig({
|
|
34
|
+
displayName: "Spinner__ContentOverlay",
|
|
35
|
+
componentId: "components-web__sc-116rqck-1"
|
|
36
|
+
})({
|
|
37
|
+
position: 'absolute',
|
|
38
|
+
width: '100%',
|
|
39
|
+
height: '100%',
|
|
40
|
+
zIndex: BACKDROP_Z_INDEX
|
|
41
|
+
});
|
|
42
|
+
const FullscreenOverlay = /*#__PURE__*/styled.div.withConfig({
|
|
43
|
+
displayName: "Spinner__FullscreenOverlay",
|
|
44
|
+
componentId: "components-web__sc-116rqck-2"
|
|
45
|
+
})(_ref2 => {
|
|
46
|
+
let {
|
|
47
|
+
fullScreenOverLayBackground
|
|
48
|
+
} = _ref2;
|
|
49
|
+
return {
|
|
50
|
+
position: 'fixed',
|
|
51
|
+
width: '100vw',
|
|
52
|
+
height: '100vh',
|
|
53
|
+
top: 0,
|
|
54
|
+
left: 0,
|
|
55
|
+
zIndex: BACKDROP_Z_INDEX,
|
|
56
|
+
backgroundColor: fullScreenOverLayBackground
|
|
57
|
+
};
|
|
58
|
+
});
|
|
59
|
+
const OpaqueContainer = /*#__PURE__*/styled.div.withConfig({
|
|
60
|
+
displayName: "Spinner__OpaqueContainer",
|
|
61
|
+
componentId: "components-web__sc-116rqck-3"
|
|
62
|
+
})({
|
|
63
|
+
opacity: BACKDROP_OPACITY
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
const recursiveMap = (children, fn) => React.Children.map(children, child => {
|
|
67
|
+
if (! /*#__PURE__*/React.isValidElement(child)) {
|
|
68
|
+
return child;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (child.props.children) {
|
|
72
|
+
return fn( /*#__PURE__*/React.cloneElement(child, {
|
|
73
|
+
children: recursiveMap(child.props.children, fn)
|
|
74
|
+
}));
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return fn(child);
|
|
78
|
+
});
|
|
79
|
+
/**
|
|
80
|
+
* Loading indicator.
|
|
81
|
+
*/
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
const Spinner = _ref3 => {
|
|
85
|
+
let {
|
|
86
|
+
children,
|
|
87
|
+
fullScreen = false,
|
|
88
|
+
inline = false,
|
|
89
|
+
label,
|
|
90
|
+
show = false,
|
|
91
|
+
isStatic = false,
|
|
92
|
+
tokens,
|
|
93
|
+
variant = {},
|
|
94
|
+
...rest
|
|
95
|
+
} = _ref3;
|
|
96
|
+
const {
|
|
97
|
+
fullScreenOverLayBackground,
|
|
98
|
+
size,
|
|
99
|
+
thickness
|
|
100
|
+
} = useThemeTokens('Spinner', tokens, variant);
|
|
101
|
+
const {
|
|
102
|
+
size: sizeVariant = 'large'
|
|
103
|
+
} = variant;
|
|
104
|
+
useScrollBlocking([fullScreen, show]);
|
|
105
|
+
|
|
106
|
+
if (!show) {
|
|
107
|
+
return children ?? null;
|
|
108
|
+
} // Full screen spinner
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
if (fullScreen) {
|
|
112
|
+
return /*#__PURE__*/_jsx(FullscreenOverlay, {
|
|
113
|
+
fullScreenOverLayBackground: fullScreenOverLayBackground,
|
|
114
|
+
children: /*#__PURE__*/_jsx(SpinnerContainer, {
|
|
115
|
+
inline: inline,
|
|
116
|
+
fullScreen: fullScreen,
|
|
117
|
+
"aria-live": "assertive",
|
|
118
|
+
...selectProps(rest),
|
|
119
|
+
children: /*#__PURE__*/_jsx(SpinnerContent, {
|
|
120
|
+
label: label,
|
|
121
|
+
overlay: true,
|
|
122
|
+
size: size,
|
|
123
|
+
thickness: thickness,
|
|
124
|
+
sizeVariant: sizeVariant,
|
|
125
|
+
isStatic: isStatic
|
|
126
|
+
})
|
|
127
|
+
})
|
|
128
|
+
});
|
|
129
|
+
} // Overlay spinner
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
if (children) {
|
|
133
|
+
return /*#__PURE__*/_jsxs(SpinnerContainer, {
|
|
134
|
+
inline: inline,
|
|
135
|
+
"aria-live": "assertive",
|
|
136
|
+
...selectProps(rest),
|
|
137
|
+
children: [/*#__PURE__*/_jsx(SpinnerContent, {
|
|
138
|
+
label: label,
|
|
139
|
+
overlay: true,
|
|
140
|
+
size: size,
|
|
141
|
+
thickness: thickness,
|
|
142
|
+
sizeVariant: sizeVariant,
|
|
143
|
+
isStatic: isStatic
|
|
144
|
+
}), /*#__PURE__*/_jsx(ContentOverlay, {}), /*#__PURE__*/_jsx(OpaqueContainer, {
|
|
145
|
+
inert: "true",
|
|
146
|
+
children: recursiveMap(children, c => {
|
|
147
|
+
if (c) {
|
|
148
|
+
return /*#__PURE__*/React.cloneElement(c, {
|
|
149
|
+
tabIndex: '-1',
|
|
150
|
+
'aria-hidden': 'true'
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
return undefined;
|
|
155
|
+
})
|
|
156
|
+
})]
|
|
157
|
+
});
|
|
158
|
+
} // Standalone spinner
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
return /*#__PURE__*/_jsx(SpinnerContainer, { ...selectProps(rest),
|
|
162
|
+
children: /*#__PURE__*/_jsx(SpinnerContent, {
|
|
163
|
+
label: label,
|
|
164
|
+
size: size,
|
|
165
|
+
thickness: thickness,
|
|
166
|
+
sizeVariant: sizeVariant,
|
|
167
|
+
isStatic: isStatic
|
|
168
|
+
})
|
|
169
|
+
});
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
Spinner.propTypes = { ...selectedSystemPropTypes,
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Content to be overlaid while the spinner is active. Can be text, any HTML element,
|
|
176
|
+
* or any component.
|
|
177
|
+
*/
|
|
178
|
+
children: PropTypes.node,
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Enables body locking.
|
|
182
|
+
*/
|
|
183
|
+
fullScreen: PropTypes.bool,
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Set the inline prop to true if the Spinner should only cover its children; if
|
|
187
|
+
* the Spinner should cover the full width of its parent regardless of the size of
|
|
188
|
+
* its children, inline should be set to false
|
|
189
|
+
*/
|
|
190
|
+
inline: PropTypes.bool,
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Communicates a message to assistive technology while visible. This same message
|
|
194
|
+
* will appear underneath the spinner when its `size` is `large`.
|
|
195
|
+
*/
|
|
196
|
+
label: PropTypes.string.isRequired,
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* The size of the spinner
|
|
200
|
+
*/
|
|
201
|
+
// size: PropTypes.oneOf(['large', 'small']),
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Whether or not to render the spinner.
|
|
205
|
+
*/
|
|
206
|
+
show: PropTypes.bool,
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* If true, it should render a static spinner
|
|
210
|
+
*/
|
|
211
|
+
isStatic: PropTypes.bool
|
|
212
|
+
};
|
|
213
|
+
export default Spinner;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import styled from 'styled-components';
|
|
4
|
+
import { ActivityIndicator, StackView, Typography, selectSystemProps } from '@telus-uds/components-base';
|
|
5
|
+
import { htmlAttrs } from '../utils';
|
|
6
|
+
import { BACKDROP_Z_INDEX, LARGE } from './constants';
|
|
7
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
8
|
+
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
9
|
+
const [selectProps, selectedSystemPropTypes] = selectSystemProps([htmlAttrs]);
|
|
10
|
+
const Container = /*#__PURE__*/styled.div.withConfig({
|
|
11
|
+
displayName: "SpinnerContent__Container",
|
|
12
|
+
componentId: "components-web__sc-1c8bd8e-0"
|
|
13
|
+
})(_ref => {
|
|
14
|
+
let {
|
|
15
|
+
overlay
|
|
16
|
+
} = _ref;
|
|
17
|
+
return {
|
|
18
|
+
display: 'inline-flex',
|
|
19
|
+
flexDirection: 'column',
|
|
20
|
+
alignItems: 'center',
|
|
21
|
+
...(overlay && {
|
|
22
|
+
position: 'absolute',
|
|
23
|
+
top: '50%',
|
|
24
|
+
left: '50%',
|
|
25
|
+
transform: 'translate(-50%, -50%)',
|
|
26
|
+
zIndex: BACKDROP_Z_INDEX
|
|
27
|
+
})
|
|
28
|
+
};
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
const SpinnerContent = _ref2 => {
|
|
32
|
+
let {
|
|
33
|
+
label,
|
|
34
|
+
overlay = false,
|
|
35
|
+
sizeVariant,
|
|
36
|
+
size,
|
|
37
|
+
thickness,
|
|
38
|
+
isStatic,
|
|
39
|
+
...rest
|
|
40
|
+
} = _ref2;
|
|
41
|
+
return /*#__PURE__*/_jsx(Container, {
|
|
42
|
+
overlay: overlay,
|
|
43
|
+
children: /*#__PURE__*/_jsxs(StackView, {
|
|
44
|
+
space: 3,
|
|
45
|
+
tokens: {
|
|
46
|
+
alignItems: 'center'
|
|
47
|
+
},
|
|
48
|
+
children: [/*#__PURE__*/_jsx(ActivityIndicator, {
|
|
49
|
+
label: label,
|
|
50
|
+
tokens: {
|
|
51
|
+
size,
|
|
52
|
+
thickness
|
|
53
|
+
},
|
|
54
|
+
isStatic: isStatic,
|
|
55
|
+
...selectProps(rest)
|
|
56
|
+
}), sizeVariant === LARGE && /*#__PURE__*/_jsx(Typography, {
|
|
57
|
+
children: label
|
|
58
|
+
})]
|
|
59
|
+
})
|
|
60
|
+
});
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
SpinnerContent.propTypes = { ...selectedSystemPropTypes,
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Communicates a message to assistive technology while visible. This same message will appear underneath the spinner when its `size` is `large`.
|
|
67
|
+
*/
|
|
68
|
+
label: PropTypes.string.isRequired,
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Whether the container has to have an overlay styling.
|
|
72
|
+
*/
|
|
73
|
+
overlay: PropTypes.bool,
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Size (width and height) of the spinner.
|
|
77
|
+
*/
|
|
78
|
+
size: PropTypes.number,
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* The size of the spinner
|
|
82
|
+
*/
|
|
83
|
+
sizeVariant: PropTypes.oneOf(['large', 'small']),
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* If true, it should render a static spinner
|
|
87
|
+
*/
|
|
88
|
+
isStatic: PropTypes.bool
|
|
89
|
+
};
|
|
90
|
+
export default SpinnerContent;
|
package/lib-module/index.js
CHANGED
|
@@ -17,4 +17,5 @@ export { default as Toast } from './Toast';
|
|
|
17
17
|
export { default as Table } from './Table';
|
|
18
18
|
export { default as Image } from './Image';
|
|
19
19
|
export { default as WaffleGrid } from './WaffleGrid';
|
|
20
|
+
export { default as Spinner } from './Spinner';
|
|
20
21
|
export * from './baseExports';
|
package/package.json
CHANGED
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
],
|
|
6
6
|
"dependencies": {
|
|
7
7
|
"@gorhom/portal": "^1.0.14",
|
|
8
|
-
"@telus-uds/components-base": "1.
|
|
8
|
+
"@telus-uds/components-base": "1.36.0",
|
|
9
9
|
"@telus-uds/system-constants": "^1.2.0",
|
|
10
10
|
"react-dates": "^21.8.0",
|
|
11
11
|
"react-moment-proptypes": "^1.8.1",
|
|
12
|
-
"@telus-uds/system-theme-tokens": "^2.
|
|
12
|
+
"@telus-uds/system-theme-tokens": "^2.21.0",
|
|
13
13
|
"prop-types": "^15.7.2",
|
|
14
14
|
"lodash.omit": "^4.5.0",
|
|
15
15
|
"lodash.throttle": "^4.1.1",
|
|
@@ -59,5 +59,5 @@
|
|
|
59
59
|
"skip": true
|
|
60
60
|
},
|
|
61
61
|
"types": "types/index.d.ts",
|
|
62
|
-
"version": "1.
|
|
62
|
+
"version": "1.7.0"
|
|
63
63
|
}
|
package/src/Modal/Modal.jsx
CHANGED
|
@@ -4,6 +4,7 @@ import PropTypes from 'prop-types'
|
|
|
4
4
|
import ModalContent from './ModalContent'
|
|
5
5
|
|
|
6
6
|
const Modal = ({
|
|
7
|
+
children,
|
|
7
8
|
isOpen,
|
|
8
9
|
onClose,
|
|
9
10
|
maxWidth,
|
|
@@ -23,7 +24,13 @@ const Modal = ({
|
|
|
23
24
|
...nonContentProps
|
|
24
25
|
}) => {
|
|
25
26
|
return (
|
|
26
|
-
<BaseModal
|
|
27
|
+
<BaseModal
|
|
28
|
+
isOpen={isOpen}
|
|
29
|
+
onClose={onClose}
|
|
30
|
+
variant={variant}
|
|
31
|
+
maxWidth={maxWidth}
|
|
32
|
+
{...nonContentProps}
|
|
33
|
+
>
|
|
27
34
|
<ModalContent
|
|
28
35
|
tokens={tokens}
|
|
29
36
|
variant={variant}
|
|
@@ -38,12 +45,15 @@ const Modal = ({
|
|
|
38
45
|
confirmButtonVariant={confirmButtonVariant}
|
|
39
46
|
cancelButtonText={cancelButtonText}
|
|
40
47
|
cancelButtonType={cancelButtonType}
|
|
41
|
-
|
|
48
|
+
>
|
|
49
|
+
{children}
|
|
50
|
+
</ModalContent>
|
|
42
51
|
</BaseModal>
|
|
43
52
|
)
|
|
44
53
|
}
|
|
45
54
|
|
|
46
55
|
Modal.propTypes = {
|
|
56
|
+
children: PropTypes.node,
|
|
47
57
|
tokens: PropTypes.object,
|
|
48
58
|
variant: PropTypes.object,
|
|
49
59
|
/**
|
|
@@ -66,6 +66,7 @@ const ModalContent = ({
|
|
|
66
66
|
variant,
|
|
67
67
|
cancelButtonText,
|
|
68
68
|
cancelButtonType: CancelButton = TextButton,
|
|
69
|
+
children,
|
|
69
70
|
onCancel
|
|
70
71
|
}) => {
|
|
71
72
|
const { headingColor, cancelButtonColor, ...themeTokens } = useThemeTokens(
|
|
@@ -118,6 +119,7 @@ const ModalContent = ({
|
|
|
118
119
|
<Typography>{bodyText}</Typography>
|
|
119
120
|
</Box>
|
|
120
121
|
)}
|
|
122
|
+
{children}
|
|
121
123
|
{(hasConfirmButton || hasCancelButton) && (
|
|
122
124
|
<StyledFooter {...themeTokens} hasBorder={isContentOverflowing} viewport={viewport}>
|
|
123
125
|
{hasConfirmButton && (
|
|
@@ -155,6 +157,7 @@ ModalContent.propTypes = {
|
|
|
155
157
|
onConfirm: PropTypes.func,
|
|
156
158
|
cancelButtonText: PropTypes.string,
|
|
157
159
|
cancelButtonType: PropTypes.elementType, // TODO: figure out a way of passing an icon to the TextButton
|
|
160
|
+
children: PropTypes.node,
|
|
158
161
|
onCancel: PropTypes.func
|
|
159
162
|
}
|
|
160
163
|
|
|
@@ -44,7 +44,11 @@ const FullBleedOffsetInner = styled.div(({ borderOffset }) => ({
|
|
|
44
44
|
|
|
45
45
|
const defaultTokens = {
|
|
46
46
|
minWidth: 0,
|
|
47
|
-
shadow: null
|
|
47
|
+
shadow: null,
|
|
48
|
+
contentAlignItems: 'stretch',
|
|
49
|
+
contentJustifyContent: 'flex-start',
|
|
50
|
+
contentFlexGrow: 0,
|
|
51
|
+
contentFlexShrink: 0
|
|
48
52
|
}
|
|
49
53
|
|
|
50
54
|
/**
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import PropTypes from 'prop-types'
|
|
3
|
+
import styled from 'styled-components'
|
|
4
|
+
import { selectSystemProps, useScrollBlocking, useThemeTokens } from '@telus-uds/components-base'
|
|
5
|
+
import SpinnerContent from './SpinnerContent'
|
|
6
|
+
import { htmlAttrs, media } from '../utils'
|
|
7
|
+
import { BACKDROP_OPACITY, BACKDROP_Z_INDEX } from './constants'
|
|
8
|
+
|
|
9
|
+
const [selectProps, selectedSystemPropTypes] = selectSystemProps([htmlAttrs])
|
|
10
|
+
|
|
11
|
+
const SpinnerContainer = styled.div(({ inline, fullScreen }) => ({
|
|
12
|
+
position: 'relative',
|
|
13
|
+
...(inline && {
|
|
14
|
+
display: 'block',
|
|
15
|
+
...media().from('md').css({
|
|
16
|
+
display: 'inline-block'
|
|
17
|
+
})
|
|
18
|
+
}),
|
|
19
|
+
...(fullScreen && { top: '50%', transform: 'translateY(-50%)' })
|
|
20
|
+
}))
|
|
21
|
+
|
|
22
|
+
const ContentOverlay = styled.div({
|
|
23
|
+
position: 'absolute',
|
|
24
|
+
width: '100%',
|
|
25
|
+
height: '100%',
|
|
26
|
+
zIndex: BACKDROP_Z_INDEX
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
const FullscreenOverlay = styled.div(({ fullScreenOverLayBackground }) => ({
|
|
30
|
+
position: 'fixed',
|
|
31
|
+
width: '100vw',
|
|
32
|
+
height: '100vh',
|
|
33
|
+
top: 0,
|
|
34
|
+
left: 0,
|
|
35
|
+
zIndex: BACKDROP_Z_INDEX,
|
|
36
|
+
backgroundColor: fullScreenOverLayBackground
|
|
37
|
+
}))
|
|
38
|
+
const OpaqueContainer = styled.div({
|
|
39
|
+
opacity: BACKDROP_OPACITY
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
const recursiveMap = (children, fn) =>
|
|
43
|
+
React.Children.map(children, (child) => {
|
|
44
|
+
if (!React.isValidElement(child)) {
|
|
45
|
+
return child
|
|
46
|
+
}
|
|
47
|
+
if (child.props.children) {
|
|
48
|
+
return fn(
|
|
49
|
+
React.cloneElement(child, {
|
|
50
|
+
children: recursiveMap(child.props.children, fn)
|
|
51
|
+
})
|
|
52
|
+
)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return fn(child)
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Loading indicator.
|
|
60
|
+
*/
|
|
61
|
+
const Spinner = ({
|
|
62
|
+
children,
|
|
63
|
+
fullScreen = false,
|
|
64
|
+
inline = false,
|
|
65
|
+
label,
|
|
66
|
+
show = false,
|
|
67
|
+
isStatic = false,
|
|
68
|
+
tokens,
|
|
69
|
+
variant = {},
|
|
70
|
+
...rest
|
|
71
|
+
}) => {
|
|
72
|
+
const { fullScreenOverLayBackground, size, thickness } = useThemeTokens(
|
|
73
|
+
'Spinner',
|
|
74
|
+
tokens,
|
|
75
|
+
variant
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
const { size: sizeVariant = 'large' } = variant
|
|
79
|
+
|
|
80
|
+
useScrollBlocking([fullScreen, show])
|
|
81
|
+
|
|
82
|
+
if (!show) {
|
|
83
|
+
return children ?? null
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Full screen spinner
|
|
87
|
+
if (fullScreen) {
|
|
88
|
+
return (
|
|
89
|
+
<FullscreenOverlay fullScreenOverLayBackground={fullScreenOverLayBackground}>
|
|
90
|
+
<SpinnerContainer
|
|
91
|
+
inline={inline}
|
|
92
|
+
fullScreen={fullScreen}
|
|
93
|
+
aria-live="assertive"
|
|
94
|
+
{...selectProps(rest)}
|
|
95
|
+
>
|
|
96
|
+
<SpinnerContent
|
|
97
|
+
label={label}
|
|
98
|
+
overlay={true}
|
|
99
|
+
size={size}
|
|
100
|
+
thickness={thickness}
|
|
101
|
+
sizeVariant={sizeVariant}
|
|
102
|
+
isStatic={isStatic}
|
|
103
|
+
/>
|
|
104
|
+
</SpinnerContainer>
|
|
105
|
+
</FullscreenOverlay>
|
|
106
|
+
)
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Overlay spinner
|
|
110
|
+
if (children) {
|
|
111
|
+
return (
|
|
112
|
+
<SpinnerContainer inline={inline} aria-live="assertive" {...selectProps(rest)}>
|
|
113
|
+
<SpinnerContent
|
|
114
|
+
label={label}
|
|
115
|
+
overlay={true}
|
|
116
|
+
size={size}
|
|
117
|
+
thickness={thickness}
|
|
118
|
+
sizeVariant={sizeVariant}
|
|
119
|
+
isStatic={isStatic}
|
|
120
|
+
/>
|
|
121
|
+
|
|
122
|
+
<ContentOverlay />
|
|
123
|
+
|
|
124
|
+
<OpaqueContainer inert="true">
|
|
125
|
+
{recursiveMap(children, (c) => {
|
|
126
|
+
if (c) {
|
|
127
|
+
return React.cloneElement(c, { tabIndex: '-1', 'aria-hidden': 'true' })
|
|
128
|
+
}
|
|
129
|
+
return undefined
|
|
130
|
+
})}
|
|
131
|
+
</OpaqueContainer>
|
|
132
|
+
</SpinnerContainer>
|
|
133
|
+
)
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Standalone spinner
|
|
137
|
+
return (
|
|
138
|
+
<SpinnerContainer {...selectProps(rest)}>
|
|
139
|
+
<SpinnerContent
|
|
140
|
+
label={label}
|
|
141
|
+
size={size}
|
|
142
|
+
thickness={thickness}
|
|
143
|
+
sizeVariant={sizeVariant}
|
|
144
|
+
isStatic={isStatic}
|
|
145
|
+
/>
|
|
146
|
+
</SpinnerContainer>
|
|
147
|
+
)
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
Spinner.propTypes = {
|
|
151
|
+
...selectedSystemPropTypes,
|
|
152
|
+
/**
|
|
153
|
+
* Content to be overlaid while the spinner is active. Can be text, any HTML element,
|
|
154
|
+
* or any component.
|
|
155
|
+
*/
|
|
156
|
+
children: PropTypes.node,
|
|
157
|
+
/**
|
|
158
|
+
* Enables body locking.
|
|
159
|
+
*/
|
|
160
|
+
fullScreen: PropTypes.bool,
|
|
161
|
+
/**
|
|
162
|
+
* Set the inline prop to true if the Spinner should only cover its children; if
|
|
163
|
+
* the Spinner should cover the full width of its parent regardless of the size of
|
|
164
|
+
* its children, inline should be set to false
|
|
165
|
+
*/
|
|
166
|
+
inline: PropTypes.bool,
|
|
167
|
+
/**
|
|
168
|
+
* Communicates a message to assistive technology while visible. This same message
|
|
169
|
+
* will appear underneath the spinner when its `size` is `large`.
|
|
170
|
+
*/
|
|
171
|
+
label: PropTypes.string.isRequired,
|
|
172
|
+
/**
|
|
173
|
+
* The size of the spinner
|
|
174
|
+
*/
|
|
175
|
+
// size: PropTypes.oneOf(['large', 'small']),
|
|
176
|
+
/**
|
|
177
|
+
* Whether or not to render the spinner.
|
|
178
|
+
*/
|
|
179
|
+
show: PropTypes.bool,
|
|
180
|
+
/**
|
|
181
|
+
* If true, it should render a static spinner
|
|
182
|
+
*/
|
|
183
|
+
isStatic: PropTypes.bool
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export default Spinner
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import PropTypes from 'prop-types'
|
|
3
|
+
import styled from 'styled-components'
|
|
4
|
+
import {
|
|
5
|
+
ActivityIndicator,
|
|
6
|
+
StackView,
|
|
7
|
+
Typography,
|
|
8
|
+
selectSystemProps
|
|
9
|
+
} from '@telus-uds/components-base'
|
|
10
|
+
import { htmlAttrs } from '../utils'
|
|
11
|
+
import { BACKDROP_Z_INDEX, LARGE } from './constants'
|
|
12
|
+
|
|
13
|
+
const [selectProps, selectedSystemPropTypes] = selectSystemProps([htmlAttrs])
|
|
14
|
+
|
|
15
|
+
const Container = styled.div(({ overlay }) => ({
|
|
16
|
+
display: 'inline-flex',
|
|
17
|
+
flexDirection: 'column',
|
|
18
|
+
alignItems: 'center',
|
|
19
|
+
...(overlay && {
|
|
20
|
+
position: 'absolute',
|
|
21
|
+
top: '50%',
|
|
22
|
+
left: '50%',
|
|
23
|
+
transform: 'translate(-50%, -50%)',
|
|
24
|
+
zIndex: BACKDROP_Z_INDEX
|
|
25
|
+
})
|
|
26
|
+
}))
|
|
27
|
+
|
|
28
|
+
const SpinnerContent = ({
|
|
29
|
+
label,
|
|
30
|
+
overlay = false,
|
|
31
|
+
sizeVariant,
|
|
32
|
+
size,
|
|
33
|
+
thickness,
|
|
34
|
+
isStatic,
|
|
35
|
+
...rest
|
|
36
|
+
}) => {
|
|
37
|
+
return (
|
|
38
|
+
<Container overlay={overlay}>
|
|
39
|
+
<StackView space={3} tokens={{ alignItems: 'center' }}>
|
|
40
|
+
<ActivityIndicator
|
|
41
|
+
label={label}
|
|
42
|
+
tokens={{ size, thickness }}
|
|
43
|
+
isStatic={isStatic}
|
|
44
|
+
{...selectProps(rest)}
|
|
45
|
+
/>
|
|
46
|
+
{sizeVariant === LARGE && <Typography>{label}</Typography>}
|
|
47
|
+
</StackView>
|
|
48
|
+
</Container>
|
|
49
|
+
)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
SpinnerContent.propTypes = {
|
|
53
|
+
...selectedSystemPropTypes,
|
|
54
|
+
/**
|
|
55
|
+
* Communicates a message to assistive technology while visible. This same message will appear underneath the spinner when its `size` is `large`.
|
|
56
|
+
*/
|
|
57
|
+
label: PropTypes.string.isRequired,
|
|
58
|
+
/**
|
|
59
|
+
* Whether the container has to have an overlay styling.
|
|
60
|
+
*/
|
|
61
|
+
overlay: PropTypes.bool,
|
|
62
|
+
/**
|
|
63
|
+
* Size (width and height) of the spinner.
|
|
64
|
+
*/
|
|
65
|
+
size: PropTypes.number,
|
|
66
|
+
/**
|
|
67
|
+
* The size of the spinner
|
|
68
|
+
*/
|
|
69
|
+
sizeVariant: PropTypes.oneOf(['large', 'small']),
|
|
70
|
+
/**
|
|
71
|
+
* If true, it should render a static spinner
|
|
72
|
+
*/
|
|
73
|
+
isStatic: PropTypes.bool
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export default SpinnerContent
|
package/src/index.js
CHANGED
|
@@ -17,5 +17,6 @@ export { default as Toast } from './Toast'
|
|
|
17
17
|
export { default as Table } from './Table'
|
|
18
18
|
export { default as Image } from './Image'
|
|
19
19
|
export { default as WaffleGrid } from './WaffleGrid'
|
|
20
|
+
export { default as Spinner } from './Spinner'
|
|
20
21
|
|
|
21
22
|
export * from './baseExports'
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ComponentType, ReactNode } from 'react'
|
|
2
|
+
import type { HTMLAttrs, Variant } from './common'
|
|
3
|
+
|
|
4
|
+
export interface SpinnerProps extends HTMLAttrs {
|
|
5
|
+
children?: ReactNode
|
|
6
|
+
variant?: Variant
|
|
7
|
+
fullScreen?: boolean
|
|
8
|
+
inline?: boolean
|
|
9
|
+
label: string
|
|
10
|
+
show?: boolean
|
|
11
|
+
isStatic?: boolean
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
declare const Spinner: ComponentType<SpinnerProps>
|
|
15
|
+
|
|
16
|
+
export default Spinner
|